class TurboRex::MSRPC::RPCFinder::ImageFinder::InterfaceModel

Attributes

dasm[RW]
decompiler[RW]
endpoints[RW]
finder[R]
interface_id[R]
interface_ver[R]
midl_switches[R]
offset_table[RW]
pproc_fs[RW]
protocol[RW]
ptype_fs[RW]
routines[RW]
struct[R]
uuid[R]
xrefs_from[RW]
xrefs_to[RW]

Public Class Methods

new(struct, finder, dasm = nil) click to toggle source
# File lib/turborex/msrpc/rpcfinder.rb, line 188
def initialize(struct, finder, dasm = nil)
  @struct = struct # RPC_SERVER_INTERFACE_Klass
  @protocol = get_protocol
  @interface_id = @uuid = TurboRex::MSRPC::Utils.raw_to_guid_str(struct.InterfaceId_Value)
  @interface_ver = get_interface_ver
  @transfer_syntax = TurboRex::MSRPC::Utils.raw_to_guid_str(struct.TransferSyntax_Value)
  @transfer_syntax_ver = get_trans_syntax_ver
  @midl_switches = RPCBase::MIDL_SWITCHES.new
  @dasm = dasm || finder.dasm
  @endpoints = []
  @finder = finder
  @routines = []
  @xrefs_to = []
  @xrefs_from = []
end

Public Instance Methods

analysis_midl_switches() click to toggle source
# File lib/turborex/msrpc/rpcfinder.rb, line 256
def analysis_midl_switches
  # Don't analyze the client interfaces. It is performed when parsing the client dispatch functions.
  if server?
    dispatch_funcs = @struct.DispatchTable.DispatchTable

    # TODO: Refine the parse methods with format string
    # Oi/Oicf/ndr64
    unless dispatch_funcs.empty?
      begin
        @dasm.disassemble dispatch_funcs[0]
      rescue StandardError
        return false
      end

      label = @dasm.get_label_at dispatch_funcs[0]
      case label
      when /NdrServerCall2/i
        @midl_switches << %w[Oif Oicf]
      when /NdrServerCall/i
        @midl_switches << %w[Oi Oic]
      when /NdrServerCallNdr64/i
        if @struct.ndr64?
          @midl_switches << 'ndr64'
          @midl_switches << %w[win64 amd64 ia64]
        end
      end
    end

    if (@struct.Flags & 0x6000000) == 0x6000000 # test /Oicf /protocol all /win64(amd64/ia64)
      interpreter_info = @struct.InterpreterInfo
      unless interpreter_info == 0
        if interpreter_info.nCount >= 2 && interpreter_info.ProcString != 0
          begin
            interpreter_info.pSyntaxInfo.each do |syntax_info|
              disp_funcs = syntax_info.DispatchTable.DispatchFunctions
              @dasm.disassemble disp_funcs.first
              label = @dasm.get_label_at disp_funcs.first

              next unless label =~ /NdrServerCallAll/

              @midl_switches << 'all'
              @midl_switches << %w[win64 amd64 ia64]
              @protocol = :all
            end
          rescue StandardError
            # TODO: exception handle
          end
        end
      end
    end

    # Os is contradictory with '/protocol ndr64/all'
    unless @midl_switches.has_one_of_switches?(%w[Oi Oic Oif Oicf ndr64 all])
      if @struct.interpreter_info_nullptr? && @struct.Flags == 0
        @midl_switches << 'Os'
      end
    end
  end
end
client?() click to toggle source
# File lib/turborex/msrpc/rpcfinder.rb, line 208
def client?
  !server?
end
decompile() click to toggle source
# File lib/turborex/msrpc/rpcfinder.rb, line 232
def decompile
  return false unless set_fs

  @finder.ndr_decompiler.decompile(self)
end
func_in_server_routines(addr) click to toggle source
# File lib/turborex/msrpc/rpcfinder.rb, line 242
def func_in_server_routines(addr)
  return false unless server?

  @finder.disassemble_executable_sections
  res = []

  routines = @routines
  routines.each do |r|
    res << r if @finder.has_path?(dasm, r.addr, addr)
  end

  res
end
func_in_server_routines?(addr) click to toggle source
# File lib/turborex/msrpc/rpcfinder.rb, line 238
def func_in_server_routines?(addr)
  func_in_server_routines(addr).empty? ? false : true
end
method_missing(m, *args) click to toggle source
Calls superclass method
# File lib/turborex/msrpc/rpcfinder.rb, line 316
def method_missing(m, *args)
  if m.to_s.start_with?('raw_')
    camelcase_name = camelcase(m.to_s.sub('raw_', ''))
    if @struct.respond_to? camelcase_name
      @struct.public_send camelcase_name, *args
    end
  elsif @struct.respond_to? m
    @struct.public_send m, *args
  else
    begin
      @struct.public_send m, *args
    rescue StandardError
      super(m, *args)
    end
  end
end
server?() click to toggle source
# File lib/turborex/msrpc/rpcfinder.rb, line 204
def server?
  !@struct.dispatch_table_nullptr?
end
set_fs() click to toggle source
# File lib/turborex/msrpc/rpcfinder.rb, line 212
def set_fs
  return false if client?
  analysis_midl_switches

  pe = finder.pe
  @poffset_table = pe.vma_to_file_offset(self.InterpreterInfo.FormatStringOffset_Value)
  @pproc_fs = pe.vma_to_file_offset(self.InterpreterInfo.ProcFormatString_Value)

  if @midl_switches.has_switch?('Oi')
    @ptype_fs = pe.vma_to_file_offset(self.InterpreterInfo.pStubDesc.pFormatTypes_Value)
    mode = :Oi
  elsif @midl_switches.has_switch?('all') && @midl_switches.arch_64?
    return false # TODO: Implement
  elsif @midl_switches.has_switch?('Oicf')
    @ptype_fs = pe.vma_to_file_offset(self.InterpreterInfo.pStubDesc.pFormatTypes_Value)
  end

  true
end

Private Instance Methods

camelcase(str) click to toggle source
# File lib/turborex/msrpc/rpcfinder.rb, line 363
def camelcase(str)
  str.split('_').collect(&:capitalize).join
end
get_interface_ver() click to toggle source
# File lib/turborex/msrpc/rpcfinder.rb, line 345
def get_interface_ver
  major = @struct.InterfaceId.SyntaxVersion.MajorVersion
  minor = @struct.InterfaceId.SyntaxVersion.MinorVersion
  get_syntax_version(major, minor)
end
get_protocol() click to toggle source
# File lib/turborex/msrpc/rpcfinder.rb, line 335
def get_protocol
  @protocol = if @struct.ndr64?
                :ndr64
              elsif @struct.dce?
                :dce
              else
                :unknown
              end
end
get_syntax_version(_major, _minor) click to toggle source
# File lib/turborex/msrpc/rpcfinder.rb, line 357
def get_syntax_version(_major, _minor)
  major = _major.to_s.unpack('S')[0]
  minor = _minor.to_s.unpack('S')[0]
  "#{major}.#{minor}"
end
get_trans_syntax_ver() click to toggle source
# File lib/turborex/msrpc/rpcfinder.rb, line 351
def get_trans_syntax_ver
  major = @struct.TransferSyntax.SyntaxVersion.MajorVersion
  minor = @struct.TransferSyntax.SyntaxVersion.MinorVersion
  get_syntax_version(major, minor)
end