module TurboRex::MSRPC::RPCFinder::StaticRPCBacktracer

This module provides a set of helper functions that backtracking RPC runtime routines parameters to determine information such as address of security callback function and rpc flags.

Public Instance Methods

bt_security_callback(dasm, trace_flags=false, uuid=nil) click to toggle source

RpcServerRegisterIf2/RpcServerRegisterIf3/RpcServerRegisterIfEx

# File lib/turborex/msrpc/rpcfinder.rb, line 14
def bt_security_callback(dasm, trace_flags=false, uuid=nil)
  res = []

  case dasm.cpu.size
  when 64
    expr_if_handle = 'rcx'
    expr_sec_cb = '[rsp+30h]'
    expr_flag = 'r9' if trace_flags
    mk_struct_proc = Proc.new {
      TurboRex::MSRPC::RPCBase::RPC_SERVER_INTERFACE64.make(pack: 8, align: true)
    }
  when 32
    expr_if_handle = '[esp]'
    expr_sec_cb = '[esp+14h]'
    expr_flag = '[esp+Ch]' if trace_flags
    mk_struct_proc = Proc.new {
      TurboRex::MSRPC::RPCBase::RPC_SERVER_INTERFACE32.make(pack: 4, align: true)
    }
  end

  fn = ['RpcServerRegisterIf2', 'RpcServerRegisterIf3', 'RpcServerRegisterIfEx']
  fn.each do |f|
    callers = dasm.call_sites(Metasm::Expression[f])
    callers.each do |addr|
      server_if = mk_struct_proc.call
      if_handle = backtrace(addr, dasm, expr_if_handle).first.first

      next unless raw = dasm.read_raw_data(if_handle, server_if.slength)
      server_if.from_s(raw) 
      interface_id = TurboRex::MSRPC::Utils.raw_to_guid_str(server_if['interfaceId'].to_s)

      found, _ = backtrace(addr, dasm, expr_sec_cb)
      found_flags, _ = backtrace(addr, dasm, expr_flag) if trace_flags
      if dasm.get_section_at(found.first)
        r = {interface_id: interface_id, callback: found.first}
        r[:flags] = found_flags.first.to_i if trace_flags
        res << r
      end
    end
  end

  res.uniq!

  case uuid
  when String
    return res.select {|r| r[:interface_id] == uuid}
  when Array
    return res.select { |r| uuid.include?(r[:interface_id])}
  else
    return res
  end
end