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