Class: TurboRex::MSRPC::Decompiler

Inherits:
Object
  • Object
show all
Includes:
MIDL, RPCBase
Defined in:
lib/turborex/msrpc/decompiler.rb

Direct Known Subclasses

OifDecompiler

Constant Summary

Constants included from NDRType

NDRType::DECODE_IS_USED, NDRType::ENCODE_IS_USED, NDRType::FC_ADD_1, NDRType::FC_ALIGNM2, NDRType::FC_ALIGNM4, NDRType::FC_ALIGNM8, NDRType::FC_AUTO_HANDLE, NDRType::FC_BIND_CONTEXT, NDRType::FC_BIND_GENERIC, NDRType::FC_BIND_PRIMITIVE, NDRType::FC_BLKHOLE, NDRType::FC_BOGUS_ARRAY, NDRType::FC_BOGUS_STRUCT, NDRType::FC_BSTRING, NDRType::FC_BYTE, NDRType::FC_BYTE_COUNT_POINTER, NDRType::FC_CALLBACK, NDRType::FC_CALLBACK_HANDLE, NDRType::FC_CARRAY, NDRType::FC_CHAR, NDRType::FC_CONSTANT_IID, NDRType::FC_CPSTRUCT, NDRType::FC_CSTRING, NDRType::FC_CSTRUCT, NDRType::FC_CVARRAY, NDRType::FC_CVSTRUCT, NDRType::FC_C_BSTRING, NDRType::FC_C_CSTRING, NDRType::FC_C_SSTRING, NDRType::FC_C_WSTRING, NDRType::FC_DEREFERENCE, NDRType::FC_DIV_2, NDRType::FC_DOUBLE, NDRType::FC_EMBEDDED_COMPLEX, NDRType::FC_ENCAPSULATED_UNION, NDRType::FC_END, NDRType::FC_END_OF_UNIVERSE, NDRType::FC_ENUM16, NDRType::FC_ENUM32, NDRType::FC_ERROR_STATUS_T, NDRType::FC_EXPLICIT_HANDLE, NDRType::FC_EXPR, NDRType::FC_FIXED_OFFSET, NDRType::FC_FIXED_REPEAT, NDRType::FC_FLOAT, NDRType::FC_FP, NDRType::FC_HARD_STRUCT, NDRType::FC_HYPER, NDRType::FC_IGNORE, NDRType::FC_INT3264, NDRType::FC_IN_OUT_PARAM, NDRType::FC_IN_PARAM, NDRType::FC_IN_PARAM_BASETYPE, NDRType::FC_IN_PARAM_NO_FREE_INST, NDRType::FC_IP, NDRType::FC_LGFARRAY, NDRType::FC_LGVARRAY, NDRType::FC_LONG, NDRType::FC_MULT_2, NDRType::FC_NON_ENCAPSULATED_UNION, NDRType::FC_NO_REPEAT, NDRType::FC_OP, NDRType::FC_OUT_PARAM, NDRType::FC_PAD, NDRType::FC_PIPE, NDRType::FC_POINTER, NDRType::FC_PP, NDRType::FC_PSTRUCT, NDRType::FC_RANGE, NDRType::FC_REPRESENT_AS, NDRType::FC_REPRESENT_AS_PTR, NDRType::FC_RETURN_PARAM, NDRType::FC_RETURN_PARAM_BASETYPE, NDRType::FC_RP, NDRType::FC_SHORT, NDRType::FC_SMALL, NDRType::FC_SMFARRAY, NDRType::FC_SMVARRAY, NDRType::FC_SPLIT_ADD_1, NDRType::FC_SPLIT_CALLBACK, NDRType::FC_SPLIT_DEREFERENCE, NDRType::FC_SPLIT_DIV_2, NDRType::FC_SPLIT_MULT_2, NDRType::FC_SPLIT_SUB_1, NDRType::FC_SSTRING, NDRType::FC_STRING_SIZED, NDRType::FC_STRUCT, NDRType::FC_STRUCTPAD1, NDRType::FC_STRUCTPAD2, NDRType::FC_STRUCTPAD3, NDRType::FC_STRUCTPAD4, NDRType::FC_STRUCTPAD5, NDRType::FC_STRUCTPAD6, NDRType::FC_STRUCTPAD7, NDRType::FC_SUB_1, NDRType::FC_TRANSMIT_AS, NDRType::FC_TRANSMIT_AS_PTR, NDRType::FC_UINT3264, NDRType::FC_ULONG, NDRType::FC_UNUSED1, NDRType::FC_UNUSED2, NDRType::FC_UNUSED3, NDRType::FC_UNUSED4, NDRType::FC_UNUSED5, NDRType::FC_UP, NDRType::FC_USER_MARSHAL, NDRType::FC_USHORT, NDRType::FC_USMALL, NDRType::FC_VARIABLE_OFFSET, NDRType::FC_VARIABLE_REPEAT, NDRType::FC_WCHAR, NDRType::FC_WSTRING, NDRType::FC_ZERO, NDRType::Oi_FULL_PTR_USED, NDRType::Oi_HAS_COMM_OR_FAULT, NDRType::Oi_HAS_RPCFLAGS, NDRType::Oi_IGNORE_OBJECT_EXCEPTION_HANDLING, NDRType::Oi_OBJECT_PROC, NDRType::Oi_OBJ_USE_V2_INTERPRETER, NDRType::Oi_RPCSS_ALLOC_USED, NDRType::Oi_USE_NEW_INIT_ROUTINES, NDRType::Oi_Unused, NDRType::Oi_overloaded1, NDRType::Oi_overloaded2, NDRType::WIN2K_EXT64_SIZE, NDRType::WIN2K_EXT_SIZE

Constants included from RPCBase

RPCBase::DCE_TransferSyntax, RPCBase::GUID, RPCBase::MIDL_SERVER_INFO, RPCBase::MIDL_SERVER_INFO32, RPCBase::MIDL_SERVER_INFO64, RPCBase::MIDL_STUBLESS_PROXY_INFO, RPCBase::MIDL_STUBLESS_PROXY_INFO32, RPCBase::MIDL_STUBLESS_PROXY_INFO64, RPCBase::MIDL_STUB_DESC, RPCBase::MIDL_STUB_DESC32, RPCBase::MIDL_STUB_DESC64, RPCBase::MIDL_SYNTAX_INFO, RPCBase::MIDL_SYNTAX_INFO32, RPCBase::MIDL_SYNTAX_INFO64, RPCBase::NDR64_TransferSyntax, RPCBase::RPC_DISPATCH_TABLE_T, RPCBase::RPC_DISPATCH_TABLE_T32, RPCBase::RPC_DISPATCH_TABLE_T64, RPCBase::RPC_IF_ID, RPCBase::RPC_PROTSEQ_ENDPOINT, RPCBase::RPC_PROTSEQ_ENDPOINT32, RPCBase::RPC_PROTSEQ_ENDPOINT64, RPCBase::RPC_SERVER_INTERFACE, RPCBase::RPC_SERVER_INTERFACE32, RPCBase::RPC_SERVER_INTERFACE64, RPCBase::RPC_SYNTAX_IDENTIFIER, RPCBase::RPC_SYNTAX_IDENTIFIER64, RPCBase::RPC_Struct_Mgr32, RPCBase::RPC_Struct_Mgr64, RPCBase::RPC_VERSION

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from RPCBase

from_guid_str, make_transferSyntax

Methods included from CStruct

#define_structs

Constructor Details

#initialize(opts = {}) ⇒ Decompiler

Returns a new instance of Decompiler.



37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/turborex/msrpc/decompiler.rb', line 37

def initialize(opts = {})
  arch = opts[:arch] || 'x86'
  header_file = TurboRex.root + '/resources/headers/rpc/internal_ndrtypes.h'
  case arch
  when 'x86'
    cpu = Metasm::Ia32
  when 'x64'
    cpu = Metasm::X86_64
  else
    raise 'Unknown architecture'
  end

  @parser = TurboRex::CStruct::NativeParser.new(nil, file: header_file, cpu: cpu, predefined: true)
end

Instance Attribute Details

#parserObject (readonly)

Returns the value of attribute parser.



35
36
37
# File 'lib/turborex/msrpc/decompiler.rb', line 35

def parser
  @parser
end

Instance Method Details

#decompile(iface) ⇒ Object



52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/turborex/msrpc/decompiler.rb', line 52

def decompile(iface)
  return false if iface.client?
  switches = iface.midl_switches
  return false if switches.has_one_of_switches?(%w[Os])

  mode = :oif
  if switches.has_switch?('Oi')
    mode = :oi
  elsif switches.has_switch?('all') && switches.arch_64?
    return false # TODO: Implement

  end

  public_send "decompile_#{mode}", iface
end

#decompile_oif(iface) ⇒ Object



67
68
69
# File 'lib/turborex/msrpc/decompiler.rb', line 67

def decompile_oif(iface)
  OifDecompiler.new(iface, @parser).decompile
end

#parse_proc_fs_header(raw_header, mode = :Oif) ⇒ Object



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/turborex/msrpc/decompiler.rb', line 71

def parse_proc_fs_header(raw_header, mode = :Oif)
  offset = 0
  header_s = Struct.new(:oi_header, :oif_header, :win2k_ext).new
  oi_header_s = Struct.new(:common, :explicit_handle_desc).new

  oi_header_p1 = @parser.decode_c_struct('Oi_Header_HType_Flags_t', raw_header)
  oi_header = if (oi_header_p1.OiFlags & Oi_HAS_RPCFLAGS) == Oi_HAS_RPCFLAGS
                @parser.decode_c_struct('Oi_Header_t', raw_header)
              else
                @parser.decode_c_struct('Oi_Header_Without_RPCFlags_t', raw_header)
              end

  oi_header_s.common = oi_header
  offset += oi_header.sizeof
  if oi_header_p1.HandleType == FC_EXPLICIT_HANDLE
    explicit_hdesc = @parser.decode_c_struct('Handle_Desc_Common_t', raw_header, offset)
    case explicit_hdesc.HandleType
    when FC_BIND_PRIMITIVE
      explicit_handle_desc = @parser.decode_c_struct('ExplicitHandlePrimitive_t', raw_header, offset)
    when FC_BIND_GENERIC
      explicit_handle_desc = @parser.decode_c_struct('ExplicitHandleGeneric_t', raw_header, offset)
    when FC_BIND_CONTEXT
      explicit_handle_desc = @parser.decode_c_struct('ExplicitHandleContext_t', raw_header, offset)
    end

    offset += explicit_handle_desc.sizeof
    oi_header_s.explicit_handle_desc = explicit_handle_desc
  end

  header_s.oi_header = oi_header_s

  case mode
  when :Oi
    return oi_header_s, offset
  when :Oif
    oif_header = @parser.decode_c_struct('Oif_Header_t', raw_header, offset)
    offset += oif_header.sizeof
    header_s.oif_header = oif_header

    if (oif_header.InterpreterOptFlags.HasExtensions) == 1 # Has win2k extension part

      size = @parser.decode_c_struct('WIN2K_EXT', raw_header, offset).ExtensionVersion
      case size
      when WIN2K_EXT_SIZE
        win2k_ext = @parser.decode_c_struct('WIN2K_EXT', raw_header, offset)
      when WIN2K_EXT64_SIZE
        win2k_ext = @parser.decode_c_struct('WIN2K_EXT64', raw_header, offset)
      end
      offset += win2k_ext.sizeof
      header_s.win2k_ext = win2k_ext
    end
  when :Os
    raise NotImplementedError
  end

  [header_s, offset]
end

#parse_proc_fs_header_dasm(dasm, addr, mode = :Oif) ⇒ Object



128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/turborex/msrpc/decompiler.rb', line 128

def parse_proc_fs_header_dasm(dasm, addr, mode = :Oif)
  offset = 0
  header_s = Struct.new(:oi_header, :oif_header, :win2k_ext).new
  oi_header_s = Struct.new(:common, :explicit_handle_desc).new

  oi_header_p1 = dasm.decode_c_struct('Oi_Header_HType_Flags_t', addr + offset)
  oi_header = if (oi_header_p1.OiFlags & Oi_HAS_RPCFLAGS) == Oi_HAS_RPCFLAGS
                dasm.decode_c_struct('Oi_Header_t', addr + offset)
              else
                dasm.decode_c_struct('Oi_Header_Without_RPCFlags_t', addr + offset)
              end

  oi_header_s.common = oi_header
  offset += oi_header.sizeof
  if oi_header_p1.HandleType == FC_EXPLICIT_HANDLE
    explicit_hdesc = dasm.decode_c_struct('Handle_Desc_Common_t', addr + offset)
    case explicit_hdesc.HandleType
    when FC_BIND_PRIMITIVE
      explicit_handle_desc = dasm.decode_c_struct('ExplicitHandlePrimitive_t', addr + offset)
    when FC_BIND_GENERIC
      explicit_handle_desc = dasm.decode_c_struct('ExplicitHandleGeneric_t', addr + offset)
    when FC_BIND_CONTEXT
      explicit_handle_desc = dasm.decode_c_struct('ExplicitHandleContext_t', addr + offset)
    end

    offset += explicit_handle_desc.sizeof
    oi_header_s.explicit_handle_desc = explicit_handle_desc
  end

  header_s.oi_header = oi_header_s

  case mode
  when :Oi
    raise NotImplementedError
  when :Oif
    oif_header = dasm.decode_c_struct('Oif_Header_t', addr + offset)
    offset += oif_header.sizeof
    header_s.oif_header = oif_header

    if oif_header.InterpreterOptFlags.HasExtensions == 1 # Has win2k extension part

      size = dasm.decode_c_struct('WIN2K_EXT', addr + offset).ExtensionVersion
      case size
      when WIN2K_EXT_SIZE
        win2k_ext = dasm.decode_c_struct('WIN2K_EXT', addr + offset)
      when WIN2K_EXT64_SIZE
        win2k_ext = dasm.decode_c_struct('WIN2K_EXT64', addr + offset)
      end
      offset += win2k_ext.sizeof
      header_s.win2k_ext = win2k_ext
    end
  when :Os
    raise NotImplementedError
  end

  [header_s, offset]
end