class TurboRex::Windows::COM::InProcFinder

Attributes

clsid[R]
server_path[R]

Public Class Methods

new(clsid) click to toggle source
# File lib/turborex/windows/com/com_finder.rb, line 22
def initialize(clsid)
  @clsid = clsid
  @process = TurboRex::Windows::Process.new(nil, -1)
  @memory = @process.memory
  @ptr_len = @process.cpusz / 8
end

Public Instance Methods

locate_interface_methods(iid) click to toggle source
# File lib/turborex/windows/com/com_finder.rb, line 29
def locate_interface_methods(iid)
  Win32::Registry::HKEY_CLASSES_ROOT.open("CLSID\\{#{@clsid}}") do |reg_clsid|
    reg_clsid.open('InprocServer32') do |reg_inproc32|
      @server_path = reg_inproc32.read_s_expand('')
    end
  end

  class_factory = Utils.dll_get_class_object(@clsid, @server_path)
  ppv = INTERNAL_APIPROXY.alloc_c_ptr('PVOID')
  unless class_factory.CreateInstance(0, Utils.clsid_to_raw(iid), ppv)
    # class_factory.Release
    pvtbl = to_ptr(@memory.get_page(ppv[0], @ptr_len))
    proxy_file_info = get_proxy_file_info(iid)
    return false unless proxy_file_info

    count = get_disptbl_count(proxy_file_info)

    if count
      methods = []
      @memory.get_page(pvtbl, count * @ptr_len).split('').each_slice(@ptr_len) { |m| methods << to_ptr(m.join) }

      first_method = methods.first
      _module = @process.modules.find { |m| first_method > m.addr && first_method < m.addr + m.size }
      if relative
        return {
          module: _module.path,
          methods: methods.map.with_index { |method, i| { index: i, rva: method - _module.addr } }
        }
      else
        return {
          module: _module.path,
          methods: methods.map.with_index { |method, i| { index: i, va: method } }
        }
      end
     
    end
  end
end