Skip to content

Instantly share code, notes, and snippets.

@snipsnipsnip
Last active March 19, 2016 03:07
Show Gist options
  • Save snipsnipsnip/70ee880f40fd15e659a9 to your computer and use it in GitHub Desktop.
Save snipsnipsnip/70ee880f40fd15e659a9 to your computer and use it in GitHub Desktop.
dll.rb: dumpbin/undname wrapper
require 'tempfile'
class DLL
include Enumerable
attr_reader :path
def initialize(path)
@path = path
end
def name
File.basename path
end
def each
syms = list_symbols
signatures = demangle_symbols(syms)
syms.zip(signatures) {|sym, sig| yield Function.new(sym, sig) }
end
private
def list_symbols
`dumpbin /exports "#{File.realpath path}"`.scan(/^\s+\d+\s+\h+\s+\h+\s+(\S+)/).flatten!
end
def demangle_symbols(symbols)
Tempfile.open($0) do |f|
f.puts symbols
f.close
`undname "#{f.path}"`.scan(/^.+/)
end
end
class Function
attr_reader :symbol
attr_reader :signature
attr_reader :return_type
attr_reader :klass
attr_reader :name
attr_reader :args
attr_reader :modifiers
def initialize(symbol, signature)
@symbol = symbol
@signature = signature
parse_member_info
end
private
def parse_member_info
signature =~ /[<>]/ and raise "Can't handle templates"
signature =~ /[,\(\)]/ and raise "Can't handle function pointers"
signature =~ /\b(\S+)::([^\(\s]+)\(/ or return
@return_type = $`
@klass = $1
@name = $2
@args = $'
@modifiers = []
@return_type.gsub!(/\s*(virtual|private:|public:|__(?:thiscall|cdecl)|static)\s+/) { @modifiers << $1.to_sym; nil }
@args.gsub!(/\)const\s*\z/, '') and @modifiers << :const
@args.gsub!(/\)?\z/, '') or raise @args
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment