class TurboRex::Windows::COM::ClientFinder
Constants
- BACKTRACE_PROC
Public Class Methods
new(fname_or_dasm)
click to toggle source
# File lib/turborex/windows/com/com_finder.rb, line 265 def initialize(fname_or_dasm) if fname_or_dasm.is_a?(String) pe = Metasm::PE.decode_file(fname_or_dasm) @dasm = _disassemble_executable_sections(pe) elsif fname_or_dasm.is_a?(::Metasm::Disassembler) @dasm = dasm end end
Public Instance Methods
find_client_call(dis=nil)
click to toggle source
# File lib/turborex/windows/com/com_finder.rb, line 274 def find_client_call(dis=nil) res = [] BACKTRACE_PROC.each do |k, v| @dasm.call_sites(::Metasm::Expression[k]).each do |c| bt_result = v.to_proc.call(self, @dasm, c) pv = bt_result[:pv] clsid = bt_result[:rclsid] iid = bt_result[:riid] context = bt_result[:context] unless pv == :unknown func_start = @dasm.find_function_start(c) func_end = @dasm.function_including(c).return_address return unless func_end func_end = func_end.first dis ||= @dasm.decoded.values.select {|di| di.address >= func_start && di.address <= func_end} dis.select {|di| di.opcode.props[:saveip]}.each do |di_call| if (obj, vtbl, index = solve_cppobj_call(@dasm, di_call)) if obj.reduce_rec.to_s == pv.to_s res << { clsid: clsid, iid: iid, context: context, method_index: index, call_site: di_call.address } end elsif fptr = solve_guard_icall(@dasm, di_call) # TODO: check Guard Flags to detect whether cfg is enabled if fptr.is_a?(::Metasm::Indirection) if fptr.pointer.op == :+ && fptr.pointer.rexpr.is_a?(Integer) && fptr.pointer.lexpr.is_a?(::Metasm::Indirection) if fptr.pointer.lexpr.pointer.reduce_rec.to_s == pv.to_s res << { clsid: clsid, iid: iid, context: context, method_index: fptr.pointer.rexpr / (@dasm.cpu.size / 8), call_site: di_call.address } end end end end end end end end res end