module TurboRex::Utils::DisassemblerHelper
Public Instance Methods
_disassemble_executable_sections(pe, method=:disassemble_fast_deep)
click to toggle source
# File lib/turborex/utils.rb, line 97 def _disassemble_executable_sections(pe, method=:disassemble_fast_deep) dasm = pe.disassembler executable_sections = pe.section_info.select {|s| s.last.to_s.split(',').include?('MEM_EXECUTE')} unless executable_sections.empty? add_dasm_all_method(dasm) executable_sections.each do |name, address, len| dasm.dasm_all(address, len, method) end addrtolabel(dasm) dasm end end
add_dasm_all_method(dasm)
click to toggle source
# File lib/turborex/utils.rb, line 44 def add_dasm_all_method(dasm) dasm.instance_eval %( def dasm_all(addrstart, length, method=:disassemble_fast_deep) s = get_section_at(addrstart) return if not s s = s[0] boff = s.ptr off = 0 while off < length if di = di_at(addrstart + off) off += di.bin_length elsif @decoded[addrstart+off] off += 1 else s.ptr = boff+off maydi = cpu.decode_instruction(s, 0) if not maydi off += 1 elsif maydi.instruction.to_s =~ /nop|lea (.*), \[\1(?:\+0)?\]|mov (.*), \2|int 3/ off += maydi.bin_length else send(method, addrstart+off) end end end count = 0 off = 0 while off < length addr = addrstart+off if di = di_at(addr) if di.block_head? b = di.block if not @function[addr] and b.from_subfuncret.to_a.empty? and b.from_normal.to_a.empty? l = auto_label_at(addr, 'sub_orph') @function[addrstart+off] = Metasm::DecodedFunction.new @function[addrstart+off].finalized = true detect_function_thunk(addr) count += 1 end end off += di.bin_length else off += 1 end end end ) dasm end
addrtolabel(dasm)
click to toggle source
github.com/jjyg/metasm/blob/master/samples/dasm-plugins/imm2off.rb
# File lib/turborex/utils.rb, line 23 def addrtolabel(dasm) bp = dasm.prog_binding.invert dasm.decoded.each_value do |di| next unless di.is_a?(Metasm::DecodedInstruction) di.each_expr do |e| next unless e.is_a?(Metasm::Expression) if l = bp[e.lexpr] dasm.add_xref(e.lexpr, Metasm::Xref.new(:addr, di.address)) e.lexpr = Metasm::Expression[l] end if l = bp[e.rexpr] dasm.add_xref(e.rexpr, Metasm::Xref.new(:addr, di.address)) e.rexpr = (e.lexpr ? Metasm::Expression[l] : l) end end end nil end
backtrace(addr, dasm, e, narg={})
click to toggle source
github.com/jjyg/metasm/blob/2a088ff85e5b873570bc284a97ddd9f8b3b0a03a/metasm/gui/dasm_main.rb#L413
# File lib/turborex/utils.rb, line 112 def backtrace(addr, dasm, e, narg={}) bd = {} expr = Metasm::IndExpression.parse_string(e) registers = (begin dasm.cpu.dbg_register_list.map(&:to_s) rescue StandardError [] end) expr.externals.grep(String).each do |w| bd[w] = w.downcase.to_sym if registers.include? w.downcase end expr = expr.bind(bd).reduce do |e_| e_.len ||= dasm.cpu.size / 8 if e_.is_a? Metasm::Indirection; nil end log = [] found = [] bt_opts = { log: log } bt_opts.merge!(narg) dasm.backtrace(expr, addr, bt_opts) if found_log = log.assoc(:found) found_log[1].each do |expr| found << dasm.resolve(expr) end end [found, log] end
solve_cppobj_call(dasm, di)
click to toggle source
# File lib/turborex/utils.rb, line 142 def solve_cppobj_call(dasm, di) return unless di.opcode.props[:saveip] fptr = dasm.get_xrefs_x(di) return if fptr.to_a.length != 1 fptr = ::Metasm::Expression[fptr.first].reduce_rec return unless fptr.kind_of? ::Metasm::Indirection return unless fptr.pointer.lexpr.kind_of? Symbol return unless fptr.pointer.rexpr.kind_of? Integer log = [] vtbl = dasm.backtrace(fptr.pointer.lexpr, di.address, log: log) vtbl.delete ::Metasm::Expression::Unknown if vtbl.empty? r = log.reverse_each.detect {|l| l[0] != :found && l[2] != ::Metasm::Expression[:unknown]} vtbl = r[2].reduce_rec else vtbl = vtbl.first end vtbl = ::Metasm::Expression[vtbl].reduce_rec return unless vtbl.kind_of? ::Metasm::Indirection obj = vtbl.pointer ptr_size = @dasm.program.cpu.size / 8 [obj, vtbl, fptr.pointer.rexpr / ptr_size] end
solve_guard_icall(dasm, di)
click to toggle source
# File lib/turborex/utils.rb, line 168 def solve_guard_icall(dasm, di) return unless di.opcode.props[:saveip] fptr = dasm.get_xrefs_x(di) return if fptr.to_a.length != 1 fptr = ::Metasm::Expression[fptr.first].reduce_rec return unless fptr.kind_of? ::Metasm::Indirection v = case dasm.cpu.size when 32 dasm.program.decode_loadconfig.guard_check_icall when 64 dasm.program.decode_loadconfig.guard_dispatch_icall end #f = dasm.decode_dword(dasm.normalize(dasm.prog_binding[v.to_s])).to_s if v == fptr.pointer case dasm.cpu.size when 32 expr = :ecx when 64 expr = :rax end log = [] res = dasm.backtrace(expr, di.address, log: log) res.delete ::Metasm::Expression::Unknown if res.empty? r = log.reverse_each.detect {|l| l[0] != :found && l[2] != ::Metasm::Expression[:unknown]} return r[2].reduce_rec end return res.first end end