module TurboRex::Utils::COMApiBacktraceHelper

Public Instance Methods

bt_cocreateinstance(dasm, addr, filter={}) click to toggle source
# File lib/turborex/utils.rb, line 207
def bt_cocreateinstance(dasm, addr, filter={})
  case dasm.cpu.size
  when 32
    expr_rclsid = '[esp]'
    expr_context = '[esp+8]'
    expr_riid = '[esp+12]'
    expr_pv = '[[esp+16]]'
  when 64
    expr_rclsid = 'rcx'
    expr_context = 'r8'
    expr_riid = 'r9'
    expr_pv = '[[rsp+32]]'
  end

  rclsid, context, riid, pv = [:unknown]*4
  # rclsid
  found, _ = backtrace(addr, dasm, expr_rclsid)
  unless found.empty?
    raw_rclsid = dasm.read_raw_data(found.first, 16)
    rclsid = TurboRex::MSRPC::Utils.raw_to_guid_str(raw_rclsid)
    if filter[:rclsid]
      return unless rclsid == filter[:rclsid]
    end
  end

  #context
  found, _ = backtrace(addr, dasm, expr_context)
  unless found.empty?
    context = found.first
    if filter[:context]
      return unless context == filter[:context]
    end
  end

  # riid
  found, _ = backtrace(addr, dasm, expr_riid)
  unless found.empty?
    raw_riid = dasm.read_raw_data(found.first, 16)
    riid = TurboRex::MSRPC::Utils.raw_to_guid_str(raw_riid)
    if filter[:riid]
      return unless riid == filter[:riid]
    end
  end

  # pv
  log = []
  found, _ = backtrace(addr, dasm, expr_pv, log: log)
  found.delete ::Metasm::Expression::Unknown
  if found.empty?
    r = log.reverse_each.detect {|l| l[0] != :found && l[2] != ::Metasm::Expression[:unknown]}
    pv = r[2].reduce_rec
  else
    pv = found.first
  end


  {rclsid: rclsid, context: context, riid: riid, pv: pv}
end
bt_cocreateinstanceex(dasm, addr, filter={}) click to toggle source

TODO: Backtrace ServerInfo

# File lib/turborex/utils.rb, line 267
def bt_cocreateinstanceex(dasm, addr, filter={})
  case dasm.cpu.size
  when 32
    expr_rclsid = '[esp]'
    expr_context = '[esp+8]'
    expr_count = '[esp+16]'
    expr_results = '[esp+20]'
  when 64
    expr_rclsid = 'rcx'
    expr_context = 'r8'
    expr_count = 'dword ptr [rsp+32]'
    expr_results = '[rsp+40]'
  end

  rclsid, context, iids = [:unknown]*3

  # rclsid
  found, _ = backtrace(addr, dasm, expr_rclsid)
  unless found.empty?
    raw_rclsid = dasm.read_raw_data(found.first, 16)
    rclsid = TurboRex::MSRPC::Utils.raw_to_guid_str(raw_rclsid)
    if filter[:rclsid]
      return unless rclsid == filter[:rclsid]
    end
  end

  #context
  found, _ = backtrace(addr, dasm, expr_context)
  unless found.empty?
    context = found.first
    if filter[:context]
      return unless context == filter[:context]
    end
  end

  # results and count
  found, _ = backtrace(addr, dasm, expr_count)
  unless found.empty?
    count = found.first
    iids = []
    size = dasm.alloc_c_struct('MULTI_QI').sizeof
    count.times do |i|
      expr_iid = "[#{expr_results}+#{i*size}]"
      found, _ = backtrace(addr, dasm, expr_iid)
      unless found.empty?
        iids << found.first
      end
    end
  end

  {rclsid: rclsid, context: context, iids: iids}
end