turborex 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (74) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +674 -0
  3. data/README.md +38 -0
  4. data/README.rdoc +19 -0
  5. data/examples/alpc_client.rb +15 -0
  6. data/examples/alpc_server.rb +14 -0
  7. data/examples/com_client.rb +19 -0
  8. data/examples/com_finder.rb +39 -0
  9. data/examples/create_instance.rb +15 -0
  10. data/examples/cstruct.rb +19 -0
  11. data/examples/find_com_client_calls.rb +16 -0
  12. data/examples/find_rpc_security_callback.rb +12 -0
  13. data/examples/rpc_finder.rb +117 -0
  14. data/examples/scan_exports.rb +5 -0
  15. data/examples/scan_imports.rb +5 -0
  16. data/examples/tinysdk.rb +17 -0
  17. data/lib/turborex.rb +21 -0
  18. data/lib/turborex/cstruct.rb +565 -0
  19. data/lib/turborex/cstruct/struct_helper.rb +7 -0
  20. data/lib/turborex/exception.rb +65 -0
  21. data/lib/turborex/fuzzer.rb +204 -0
  22. data/lib/turborex/fuzzer/containers.rb +115 -0
  23. data/lib/turborex/fuzzer/coverage.rb +67 -0
  24. data/lib/turborex/fuzzer/mutators.rb +25 -0
  25. data/lib/turborex/fuzzer/seed.rb +30 -0
  26. data/lib/turborex/monkey.rb +11 -0
  27. data/lib/turborex/msrpc.rb +14 -0
  28. data/lib/turborex/msrpc/decompiler.rb +244 -0
  29. data/lib/turborex/msrpc/midl.rb +747 -0
  30. data/lib/turborex/msrpc/ndrtype.rb +167 -0
  31. data/lib/turborex/msrpc/rpcbase.rb +777 -0
  32. data/lib/turborex/msrpc/rpcfinder.rb +1426 -0
  33. data/lib/turborex/msrpc/utils.rb +70 -0
  34. data/lib/turborex/pefile.rb +8 -0
  35. data/lib/turborex/pefile/pe.rb +61 -0
  36. data/lib/turborex/pefile/scanner.rb +82 -0
  37. data/lib/turborex/utils.rb +321 -0
  38. data/lib/turborex/windows.rb +402 -0
  39. data/lib/turborex/windows/alpc.rb +844 -0
  40. data/lib/turborex/windows/com.rb +266 -0
  41. data/lib/turborex/windows/com/client.rb +84 -0
  42. data/lib/turborex/windows/com/com_finder.rb +330 -0
  43. data/lib/turborex/windows/com/com_registry.rb +100 -0
  44. data/lib/turborex/windows/com/interface.rb +522 -0
  45. data/lib/turborex/windows/com/utils.rb +210 -0
  46. data/lib/turborex/windows/constants.rb +82 -0
  47. data/lib/turborex/windows/process.rb +56 -0
  48. data/lib/turborex/windows/security.rb +12 -0
  49. data/lib/turborex/windows/security/ace.rb +76 -0
  50. data/lib/turborex/windows/security/acl.rb +25 -0
  51. data/lib/turborex/windows/security/security_descriptor.rb +118 -0
  52. data/lib/turborex/windows/tinysdk.rb +89 -0
  53. data/lib/turborex/windows/utils.rb +138 -0
  54. data/resources/headers/alpc/ntdef.h +72 -0
  55. data/resources/headers/alpc/ntlpcapi.h +1014 -0
  56. data/resources/headers/rpc/common.h +162 -0
  57. data/resources/headers/rpc/guiddef.h +191 -0
  58. data/resources/headers/rpc/internal_ndrtypes.h +262 -0
  59. data/resources/headers/rpc/rpc.h +10 -0
  60. data/resources/headers/rpc/rpcdce.h +266 -0
  61. data/resources/headers/rpc/rpcdcep.h +187 -0
  62. data/resources/headers/rpc/rpcndr.h +39 -0
  63. data/resources/headers/rpc/v4_x64/rpcinternals.h +154 -0
  64. data/resources/headers/rpc/wintype.h +517 -0
  65. data/resources/headers/tinysdk/tinysdk.h +5 -0
  66. data/resources/headers/tinysdk/tinysdk/comdef.h +645 -0
  67. data/resources/headers/tinysdk/tinysdk/dbghelp.h +118 -0
  68. data/resources/headers/tinysdk/tinysdk/guiddef.h +194 -0
  69. data/resources/headers/tinysdk/tinysdk/memoryapi.h +12 -0
  70. data/resources/headers/tinysdk/tinysdk/poppack.h +12 -0
  71. data/resources/headers/tinysdk/tinysdk/pshpack4.h +13 -0
  72. data/resources/headers/tinysdk/tinysdk/winnt.h +1059 -0
  73. data/resources/headers/tinysdk/tinysdk/wintype.h +326 -0
  74. metadata +290 -0
@@ -0,0 +1,167 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TurboRex
4
+ module MSRPC
5
+ module NDRType
6
+ # https://github.com/wine-mirror/wine/tree/master/tools/widl
7
+ # https://docs.microsoft.com/en-us/windows/win32/midl/midl-data-types
8
+ # https://github.com/wine-mirror/wine/blob/master/include/ndrtypes.h
9
+
10
+ # FC Base Type
11
+ FC_ZERO = 0x0
12
+ FC_BYTE = 0x1
13
+ FC_CHAR = 0x2
14
+ FC_SMALL = 0x3
15
+ FC_USMALL = 0x4
16
+ FC_WCHAR = 0x5
17
+ FC_SHORT = 0x6
18
+ FC_USHORT = 0x7
19
+ FC_LONG = 0x8
20
+ FC_ULONG = 0x9
21
+ FC_FLOAT = 0xA
22
+ FC_HYPER = 0xB
23
+ FC_DOUBLE = 0xC
24
+ FC_ENUM16 = 0xD
25
+ FC_ENUM32 = 0xE
26
+ FC_IGNORE = 0xF
27
+ FC_ERROR_STATUS_T = 0x10
28
+
29
+ FC_RP = 0x11
30
+ FC_UP = 0x12
31
+ FC_OP = 0x13
32
+ FC_FP = 0x14
33
+ FC_STRUCT = 0x15
34
+ FC_PSTRUCT = 0x16
35
+ FC_CSTRUCT = 0x17
36
+ FC_CPSTRUCT = 0x18
37
+ FC_CVSTRUCT = 0x19
38
+ FC_BOGUS_STRUCT = 0x1A
39
+ FC_CARRAY = 0x1B
40
+ FC_CVARRAY = 0x1C
41
+ FC_SMFARRAY = 0x1D
42
+ FC_LGFARRAY = 0x1E
43
+ FC_SMVARRAY = 0x1F
44
+ FC_LGVARRAY = 0x20
45
+ FC_BOGUS_ARRAY = 0x21
46
+ FC_C_CSTRING = 0x22
47
+ FC_C_BSTRING = 0x23
48
+ FC_C_SSTRING = 0x24
49
+ FC_C_WSTRING = 0x25
50
+ FC_CSTRING = 0x26
51
+ FC_BSTRING = 0x27
52
+ FC_SSTRING = 0x28
53
+ FC_WSTRING = 0x29
54
+ FC_ENCAPSULATED_UNION = 0x2A
55
+ FC_NON_ENCAPSULATED_UNION = 0x2B
56
+ FC_BYTE_COUNT_POINTER = 0x2C
57
+ FC_TRANSMIT_AS = 0x2D
58
+ FC_REPRESENT_AS = 0x2E
59
+ FC_IP = 0x2F
60
+ FC_EXPLICIT_HANDLE = 0x00
61
+ FC_BIND_CONTEXT = 0x30
62
+ FC_BIND_GENERIC = 0x31
63
+ FC_BIND_PRIMITIVE = 0x32
64
+ FC_AUTO_HANDLE = 0x33
65
+ FC_CALLBACK_HANDLE = 0x34
66
+ FC_UNUSED1 = 0x35
67
+ FC_POINTER = 0x36
68
+ FC_ALIGNM2 = 0x37
69
+ FC_ALIGNM4 = 0x38
70
+ FC_ALIGNM8 = 0x39
71
+ FC_UNUSED2 = 0x3A
72
+ FC_UNUSED3 = 0x3B
73
+ FC_UNUSED4 = 0x3C
74
+ FC_STRUCTPAD1 = 0x3D
75
+ FC_STRUCTPAD2 = 0x3E
76
+ FC_STRUCTPAD3 = 0x3F
77
+ FC_STRUCTPAD4 = 0x40
78
+ FC_STRUCTPAD5 = 0x41
79
+ FC_STRUCTPAD6 = 0x42
80
+ FC_STRUCTPAD7 = 0x43
81
+ FC_STRING_SIZED = 0x44
82
+ FC_UNUSED5 = 0x45
83
+ FC_NO_REPEAT = 0x46
84
+ FC_FIXED_REPEAT = 0x47
85
+ FC_VARIABLE_REPEAT = 0x48
86
+ FC_FIXED_OFFSET = 0x49
87
+ FC_VARIABLE_OFFSET = 0x4A
88
+ FC_PP = 0x4B
89
+ FC_EMBEDDED_COMPLEX = 0x4C
90
+ FC_IN_PARAM = 0x4D
91
+ FC_IN_PARAM_BASETYPE = 0x4E
92
+ FC_IN_PARAM_NO_FREE_INST = 0x4F
93
+ FC_IN_OUT_PARAM = 0x50
94
+ FC_OUT_PARAM = 0x51
95
+ FC_RETURN_PARAM = 0x52
96
+ FC_RETURN_PARAM_BASETYPE = 0x53
97
+ FC_DEREFERENCE = 0x54
98
+ FC_DIV_2 = 0x55
99
+ FC_MULT_2 = 0x56
100
+ FC_ADD_1 = 0x57
101
+ FC_SUB_1 = 0x58
102
+ FC_CALLBACK = 0x59
103
+ FC_CONSTANT_IID = 0x5A
104
+ FC_END = 0x5B
105
+ FC_PAD = 0x5C
106
+ FC_EXPR = 0x5D
107
+ FC_SPLIT_DEREFERENCE = 0x74
108
+ FC_SPLIT_DIV_2 = 0x75
109
+ FC_SPLIT_MULT_2 = 0x76
110
+ FC_SPLIT_ADD_1 = 0x77
111
+ FC_SPLIT_SUB_1 = 0x78
112
+ FC_SPLIT_CALLBACK = 0x79
113
+ FC_HARD_STRUCT = 0xB1
114
+ FC_TRANSMIT_AS_PTR = 0xB2
115
+ FC_REPRESENT_AS_PTR = 0xB3
116
+ FC_USER_MARSHAL = 0xB4
117
+ FC_PIPE = 0xB5
118
+ FC_BLKHOLE = 0xB6
119
+ FC_RANGE = 0xB7
120
+ FC_INT3264 = 0xB8 # base type
121
+ FC_UINT3264 = 0xB9 # base type
122
+ FC_END_OF_UNIVERSE = 0xBA
123
+
124
+ # The Oi flags
125
+ Oi_FULL_PTR_USED = 0x01
126
+ Oi_RPCSS_ALLOC_USED = 0x02
127
+ Oi_OBJECT_PROC = 0x04
128
+ Oi_HAS_RPCFLAGS = 0x08
129
+ Oi_overloaded1 = 0x10
130
+ Oi_overloaded2 = 0x20
131
+ Oi_USE_NEW_INIT_ROUTINES = 0x40
132
+ Oi_Unused = 0x80
133
+
134
+ # Overloaded Oi flags
135
+ ENCODE_IS_USED = 0x10
136
+ DECODE_IS_USED = 0x20
137
+ Oi_IGNORE_OBJECT_EXCEPTION_HANDLING = 0x10
138
+ Oi_HAS_COMM_OR_FAULT = 0x20
139
+ Oi_OBJ_USE_V2_INTERPRETER = 0x20
140
+
141
+ # Interpreter opt flags
142
+ module InterpreterOptFlags
143
+ ServerMustSize = 0x01
144
+ ClientMustSize = 0x02
145
+ HasReturn = 0x04
146
+ HasPipes = 0x08
147
+ Unused = 0x10
148
+ HasAsyncUuid = 0x20
149
+ HasExtensions = 0x40
150
+ HasAsyncHandle = 0x80
151
+ end
152
+
153
+ module InterpreterOptFlags2
154
+ HasNewCorrDesc = 0x01
155
+ ClientCorrCheck = 0x02
156
+ ServerCorrCheck = 0x04
157
+ HasNotify = 0x08
158
+ HasNotify2 = 0x10
159
+ HasComplexReturn = 0x20
160
+ HasRangeOnConformance = 0x40
161
+ end
162
+
163
+ WIN2K_EXT_SIZE = 8
164
+ WIN2K_EXT64_SIZE = 10 # 12?
165
+ end
166
+ end
167
+ end
@@ -0,0 +1,777 @@
1
+ # frozen_string_literal: true
2
+
3
+ module TurboRex
4
+ module MSRPC
5
+ module RPCBase
6
+ extend TurboRex::CStruct
7
+
8
+ RPC_Struct_Mgr32 = define_structs do
9
+ struct GENERIC_BINDING_ROUTINE_PAIR {
10
+ PVOID pfnBind
11
+ PVOID pfnUnbind
12
+ }
13
+
14
+ struct GUID {
15
+ UINT data1
16
+ USHORT data2
17
+ USHORT data3
18
+ BYTE data4[8]
19
+ }
20
+
21
+ struct RPC_VERSION {
22
+ USHORT majorVersion
23
+ USHORT minorVersion
24
+ }
25
+
26
+ struct RPC_SYNTAX_IDENTIFIER {
27
+ GUID syntaxGUID
28
+ RPC_VERSION syntaxVersion
29
+ }
30
+
31
+ struct RPC_SERVER_INTERFACE {
32
+ UINT length
33
+ RPC_SYNTAX_IDENTIFIER interfaceId
34
+ RPC_SYNTAX_IDENTIFIER transferSyntax
35
+ PVOID dispatchTable
36
+ UINT rpcProtseqEndpointCount
37
+ PVOID rpcProtseqEndpoint
38
+ PVOID defaultManagerEpv
39
+ PVOID interpreterInfo
40
+ UINT flags
41
+ }
42
+
43
+ struct RPC_PROTSEQ_ENDPOINT {
44
+ PVOID rpcProtocolSequence
45
+ PVOID endpoint
46
+ }
47
+
48
+ struct RPC_DISPATCH_TABLE_T {
49
+ UINT dispatchTableCount
50
+ PVOID dispatchTable
51
+ ULONG_PTR_T reserved
52
+ }
53
+
54
+ struct MIDL_SERVER_INFO {
55
+ PVOID pStubDesc
56
+ PVOID dispatchTable
57
+ PVOID procString
58
+ PVOID fmtStringOffset
59
+ PVOID thunkTable
60
+ PVOID pTransferSyntax
61
+ PVOID nCount
62
+ PVOID pSyntaxInfo
63
+ }
64
+
65
+ struct MIDL_STUB_DESC {
66
+ PVOID rpcInterfaceInformation
67
+ PVOID pfnAllocate
68
+ PVOID pfnFree
69
+ PVOID implicit_handle_info
70
+ PVOID apfnNdrRundownRoutines
71
+ PVOID aGenericBindingRoutinePairs
72
+ PVOID apfnExprEval
73
+ PVOID aXmitQuintuple
74
+ PVOID pFormatTypes
75
+ INT fCheckBounds
76
+ ULONG version
77
+ PVOID pMallocFreeStruct
78
+ LONG midlVersion
79
+ PVOID commFaultOffsets
80
+ PVOID aUserMarshalQuadruple
81
+ PVOID notifyRoutineTable
82
+ ULONG_PTR mFlags
83
+ PVOID csRoutineTables
84
+ PVOID proxyServerInfo
85
+ PVOID pExprInfo
86
+ }
87
+
88
+ struct MIDL_STUBLESS_PROXY_INFO {
89
+ PVOID pStubDesc
90
+ PVOID procFormatString
91
+ PVOID formatStringOffset
92
+ PVOID pTransferSyntax
93
+ ULONG_PTR nCount
94
+ PVOID pSyntaxInfo
95
+ }
96
+
97
+ struct MIDL_SYNTAX_INFO {
98
+ RPC_SYNTAX_IDENTIFIER transferSyntax
99
+ PVOID dispatchTable
100
+ PVOID procString
101
+ PVOID fmtStringOffset
102
+ PVOID typeString
103
+ PVOID aUserMarshalQuadruple
104
+ PVOID pMethodProperties
105
+ ULONG_PTR pReserved2
106
+ }
107
+ end
108
+
109
+ RPC_Struct_Mgr64 = define_structs(arch: 'x64') do
110
+ struct GUID {
111
+ uint data1
112
+ ushort data2
113
+ ushort data3
114
+ BYTE data4[8]
115
+ }
116
+
117
+ struct RPC_VERSION {
118
+ ushort majorVersion
119
+ ushort minorVersion
120
+ }
121
+
122
+ struct RPC_SYNTAX_IDENTIFIER {
123
+ GUID syntaxGUID
124
+ RPC_VERSION syntaxVersion
125
+ }
126
+
127
+ struct RPC_SERVER_INTERFACE {
128
+ UINT length
129
+ RPC_SYNTAX_IDENTIFIER interfaceId
130
+ RPC_SYNTAX_IDENTIFIER transferSyntax
131
+ PVOID dispatchTable
132
+ UINT rpcProtseqEndpointCount
133
+ PVOID rpcProtseqEndpoint
134
+ PVOID defaultManagerEpv
135
+ PVOID interpreterInfo
136
+ UINT flags
137
+ }
138
+
139
+ struct RPC_PROTSEQ_ENDPOINT {
140
+ PVOID rpcProtocolSequence
141
+ PVOID endpoint
142
+ }
143
+
144
+ struct RPC_DISPATCH_TABLE_T {
145
+ UINT dispatchTableCount
146
+ PVOID dispatchTable
147
+ ULONG_PTR_T reserved
148
+ }
149
+
150
+ struct MIDL_STUB_DESC {
151
+ PVOID rpcInterfaceInformation
152
+ PVOID pfnAllocate
153
+ PVOID pfnFree
154
+ PVOID implicit_handle_info
155
+ PVOID apfnNdrRundownRoutines
156
+ PVOID aGenericBindingRoutinePairs
157
+ PVOID apfnExprEval
158
+ PVOID aXmitQuintuple
159
+ PVOID pFormatTypes
160
+ INT fCheckBounds
161
+ ULONG version
162
+ PVOID pMallocFreeStruct
163
+ LONG midlVersion
164
+ PVOID commFaultOffsets
165
+ PVOID aUserMarshalQuadruple
166
+ PVOID notifyRoutineTable
167
+ ULONG_PTR mFlags
168
+ PVOID csRoutineTables
169
+ PVOID proxyServerInfo
170
+ PVOID pExprInfo
171
+ }
172
+
173
+ struct MIDL_SERVER_INFO {
174
+ PVOID pStubDesc
175
+ PVOID dispatchTable
176
+ PVOID procString
177
+ PVOID fmtStringOffset
178
+ PVOID thunkTable
179
+ PVOID pTransferSyntax
180
+ PVOID nCount
181
+ PVOID pSyntaxInfo
182
+ }
183
+
184
+ struct MIDL_SYNTAX_INFO {
185
+ RPC_SYNTAX_IDENTIFIER transferSyntax
186
+ PVOID dispatchTable
187
+ PVOID procString
188
+ PVOID fmtStringOffset
189
+ PVOID typeString
190
+ PVOID aUserMarshalQuadruple
191
+ PVOID pMethodProperties
192
+ ULONG_PTR pReserved2
193
+ }
194
+
195
+ struct MIDL_STUBLESS_PROXY_INFO {
196
+ PVOID pStubDesc
197
+ PVOID procFormatString
198
+ PVOID formatStringOffset
199
+ PVOID pTransferSyntax
200
+ ULONG_PTR nCount
201
+ PVOID pSyntaxInfo
202
+ }
203
+ end
204
+
205
+ RPC_SERVER_INTERFACE = RPC_Struct_Mgr32['RPC_SERVER_INTERFACE']
206
+ RPC_SERVER_INTERFACE32 = RPC_Struct_Mgr32['RPC_SERVER_INTERFACE']
207
+ RPC_SERVER_INTERFACE64 = RPC_Struct_Mgr64['RPC_SERVER_INTERFACE']
208
+ RPC_PROTSEQ_ENDPOINT = RPC_Struct_Mgr32['RPC_PROTSEQ_ENDPOINT']
209
+ RPC_PROTSEQ_ENDPOINT32 = RPC_Struct_Mgr32['RPC_PROTSEQ_ENDPOINT']
210
+ RPC_PROTSEQ_ENDPOINT64 = RPC_Struct_Mgr64['RPC_PROTSEQ_ENDPOINT']
211
+ MIDL_SERVER_INFO = RPC_Struct_Mgr32['MIDL_SERVER_INFO']
212
+ MIDL_SERVER_INFO32 = RPC_Struct_Mgr32['MIDL_SERVER_INFO']
213
+ MIDL_SERVER_INFO64 = RPC_Struct_Mgr64['MIDL_SERVER_INFO']
214
+ MIDL_STUB_DESC = RPC_Struct_Mgr32['MIDL_STUB_DESC']
215
+ MIDL_STUB_DESC32 = RPC_Struct_Mgr32['MIDL_STUB_DESC']
216
+ MIDL_STUB_DESC64 = RPC_Struct_Mgr64['MIDL_STUB_DESC']
217
+ MIDL_SYNTAX_INFO = RPC_Struct_Mgr32['MIDL_SYNTAX_INFO']
218
+ MIDL_SYNTAX_INFO32 = RPC_Struct_Mgr32['MIDL_SYNTAX_INFO']
219
+ MIDL_SYNTAX_INFO64 = RPC_Struct_Mgr64['MIDL_SYNTAX_INFO']
220
+ MIDL_STUBLESS_PROXY_INFO = RPC_Struct_Mgr32['MIDL_STUBLESS_PROXY_INFO']
221
+ MIDL_STUBLESS_PROXY_INFO32 = RPC_Struct_Mgr32['MIDL_STUBLESS_PROXY_INFO']
222
+ MIDL_STUBLESS_PROXY_INFO64 = RPC_Struct_Mgr64['MIDL_STUBLESS_PROXY_INFO']
223
+ RPC_DISPATCH_TABLE_T = RPC_Struct_Mgr32['RPC_DISPATCH_TABLE_T']
224
+ RPC_DISPATCH_TABLE_T32 = RPC_Struct_Mgr32['RPC_DISPATCH_TABLE_T']
225
+ RPC_DISPATCH_TABLE_T64 = RPC_Struct_Mgr64['RPC_DISPATCH_TABLE_T']
226
+
227
+ GUID = RPC_Struct_Mgr32['GUID']
228
+ RPC_VERSION = RPC_Struct_Mgr32['RPC_VERSION']
229
+ RPC_SYNTAX_IDENTIFIER = RPC_Struct_Mgr32['RPC_SYNTAX_IDENTIFIER']
230
+ RPC_SYNTAX_IDENTIFIER64 = RPC_Struct_Mgr64['RPC_SYNTAX_IDENTIFIER']
231
+ RPC_IF_ID = RPC_SYNTAX_IDENTIFIER
232
+
233
+ def self.from_guid_str(guid_str)
234
+ if guid_str.count('-') == 3
235
+ hexData1, hexData2, hexData3, hexData4 = guid_str.split('-')
236
+
237
+ data1 = hexData1.to_i(16)
238
+ data2 = hexData2.to_i(16)
239
+ data3 = hexData3.to_i(16)
240
+ data4 = [hexData4.to_i(16)].pack('Q<').unpack('CCCCCCCC')
241
+
242
+ guid_struct = GUID.make
243
+ guid_struct['data1'].value = data1
244
+ guid_struct['data2'].value = data2
245
+ guid_struct['data3'].value = data3
246
+
247
+ data4.each_with_index do |c, i|
248
+ guid_struct['data4'][i].value = c
249
+ end
250
+
251
+ guid_struct
252
+ elsif guid_str.count('-') == 4
253
+ hexData1, hexData2, hexData3, hexData4Hi, hexData4 = guid_str.split('-')
254
+
255
+ data1 = hexData1.to_i(16)
256
+ data2 = hexData2.to_i(16)
257
+ data3 = hexData3.to_i(16)
258
+ data4Hi = hexData4Hi.to_i(16)
259
+ data4 = []
260
+
261
+ (0...hexData4.length).step(2) do |i|
262
+ data4 << hexData4[i...i + 2].to_i(16)
263
+ end
264
+
265
+ guid_struct = GUID.make
266
+ guid_struct['data1'].value = data1
267
+ guid_struct['data2'].value = data2
268
+ guid_struct['data3'].value = data3
269
+ guid_struct['data4'][0].value = data4Hi >> 8
270
+ guid_struct['data4'][1].value = data4Hi & 0xff
271
+
272
+ data4.each_with_index do |c, i|
273
+ guid_struct['data4'][i + 2].value = c
274
+ end
275
+
276
+ guid_struct
277
+ end
278
+ end
279
+
280
+ def self.make_transferSyntax(guid, majorVersion, minorVersion)
281
+ ident = RPC_SYNTAX_IDENTIFIER.make
282
+ ident['syntaxGUID'].from_s from_guid_str(guid).to_s
283
+ ident['syntaxVersion'][0].value = majorVersion
284
+ ident['syntaxVersion'][1].value = minorVersion
285
+
286
+ ident
287
+ end
288
+
289
+ DCE_TransferSyntax = make_transferSyntax('8A885D04-1CEB-11C9-9FE8-08002B104860', 2, 0)
290
+ NDR64_TransferSyntax = make_transferSyntax('71710533-BEBA-4937-8319-B5DBEF9CCC36', 1, 0)
291
+
292
+ module InterfaceType
293
+ UNKNOWN = 0
294
+ RPC = 1
295
+ DCOM = 2
296
+ OLE = 3
297
+ end
298
+
299
+ module InterfaceFlag
300
+ RPC_IF_AUTOLISTEN = 0x0001
301
+ RPC_IF_OLE = 0x0002
302
+ RPC_IF_ALLOW_UNKNOWN_AUTHORITY = 0x0004
303
+ RPC_IF_ALLOW_SECURE_ONLY = 0x0008
304
+ RPC_IF_ALLOW_CALLBACKS_WITH_NO_AUTH = 0x0010
305
+ RPC_IF_ALLOW_LOCAL_ONLY = 0x0020
306
+ RPC_IF_SEC_NO_CACHE = 0x0040
307
+ RPC_IF_SEC_CACHE_PER_PROC = 0x0080
308
+ RPC_IF_ASYNC_CALLBACK = 0x0100
309
+
310
+ MAPPING = {
311
+ rpc_if_autolisten: 0x1,
312
+ rpc_if_ole: 0x2,
313
+ rpc_if_allow_unknown_authority: 0x4,
314
+ rpc_if_allow_secure_only: 0x8,
315
+ rpc_if_allow_callbacks_with_no_auth: 0x10,
316
+ rpc_if_allow_local_only: 0x20,
317
+ rpc_if_sec_no_cache: 0x40,
318
+ rpc_if_sec_cache_per_proc: 0x80,
319
+ rpc_if_async_callback: 0x100
320
+ }
321
+ end
322
+
323
+ class MIDL_SWITCHES
324
+ SWITCHES = %w[Oi Oic Oif Oicf Os ndr64 all win64 amd64 ia64]
325
+ attr_reader :value
326
+
327
+ def initialize
328
+ @value = 0
329
+ end
330
+
331
+ def add(switch)
332
+ return @value if has_switch?(switch)
333
+ @value |= mapping_midl_switch(switch)
334
+ end
335
+
336
+ def remove(switch)
337
+ @value &= ~mapping_midl_switch(switch)
338
+ end
339
+
340
+ def has_switch?(switch)
341
+ integer = mapping_midl_switch(switch)
342
+ !integer.zero? && (@value & integer) == integer
343
+ end
344
+
345
+ def has_one_of_switches?(switch)
346
+ switch.each { |s| return true if has_switch?(s) }
347
+ false
348
+ end
349
+
350
+ def has_all_of_switches?(switch)
351
+ res = true
352
+ switch.map {|s|res = false unless has_switch?(s)}
353
+ res
354
+ end
355
+
356
+ def arch_64?
357
+ has_one_of_switches?(%w[win64 amd64 ia64])
358
+ end
359
+
360
+ def mapping_midl_switch(switch)
361
+ switch = [switch] if switch.is_a?(String)
362
+ case switch
363
+ when Array
364
+ (switch & SWITCHES).map do |s|
365
+ 2**SWITCHES.index(s)
366
+ end.inject(0, :+)
367
+ when Integer
368
+ SWITCHES.reject do |s|
369
+ ((switch || 0) & 2**SWITCHES.index(s)).zero?
370
+ end
371
+ end
372
+ end
373
+
374
+ def to_array
375
+ mapping_midl_switch(@value)
376
+ end
377
+
378
+ def to_s
379
+ mapping_midl_switch(@value).join(', ')
380
+ end
381
+
382
+ alias_method :<<, :add
383
+ end
384
+
385
+
386
+ class Structures_Klass
387
+ attr_accessor :xrefs
388
+
389
+ def initialize(cstruct)
390
+ @xrefs = []
391
+ @value_table = {}
392
+ @cstruct = cstruct
393
+ parse_struct(cstruct)
394
+ end
395
+
396
+ def to_s
397
+ @cstruct.to_s
398
+ end
399
+
400
+ def [](key)
401
+ self.send key
402
+ end
403
+
404
+ def method_missing(m, *args)
405
+ if m.to_s.end_with?('_Value')
406
+ key = m.to_s.split('_Value')[0].to_sym
407
+ @value_table[key]
408
+ elsif @value_table.keys.map(&:downcase).include?(m.downcase)
409
+ self.define_singleton_method(m) do
410
+ @value_table[m]
411
+ end
412
+ @value_table[m]
413
+ else
414
+ super(m, *args)
415
+ end
416
+ end
417
+
418
+ def link_and_xref(var_name, struct)
419
+ self.instance_variable_set ('@'+var_name.to_s).to_sym, struct
420
+ var = struct
421
+ xref_from(struct) unless struct.is_a?(Array)
422
+ end
423
+
424
+ def xref_from(cstruct)
425
+ cstruct.xrefs << self
426
+ end
427
+ end
428
+
429
+ class GUID_Klass < Structures_Klass
430
+ def initialize(cstruct)
431
+ parse_struct(cstruct)
432
+ end
433
+
434
+ def parse_struct(cstruct)
435
+ @value_table = {
436
+ Data1: cstruct['data1'],
437
+ Data2: cstruct['data2'],
438
+ Data3: cstruct['data3'],
439
+ Data4: cstruct['data4']
440
+ }
441
+ end
442
+ end
443
+
444
+ class RPC_VERSION_Klass < Structures_Klass
445
+ def parse_struct(cstruct)
446
+ @value_table = {
447
+ MajorVersion: cstruct['majorVersion'],
448
+ MinorVersion: cstruct['minorVersion']
449
+ }
450
+ end
451
+ end
452
+
453
+ class RPC_SYNTAX_IDENTIFIER_Klass < Structures_Klass
454
+ attr_accessor :type
455
+
456
+ def parse_struct(cstruct)
457
+ @value_table = {
458
+ SyntaxGUID: cstruct['syntaxGUID'].to_s,
459
+ SyntaxVersion:cstruct['syntaxVersion'].to_s
460
+ }
461
+
462
+ @type = :interface_id
463
+ guid = @value_table[:SyntaxGUID]
464
+ if guid == DCE_TransferSyntax.to_s || guid == NDR64_TransferSyntax.to_s
465
+ @type = :transfer_syntax
466
+ end
467
+
468
+ @syntax_guid_link_to = GUID_Klass.new(cstruct['syntaxGUID'])
469
+ @syntax_version_link_to = RPC_VERSION_Klass.new(cstruct['syntaxVersion'])
470
+
471
+ true
472
+ end
473
+
474
+ def SyntaxGUID
475
+ @syntax_guid_link_to || @value_table[:SyntaxGUID]
476
+ end
477
+
478
+ def SyntaxVersion
479
+ @syntax_version_link_to || @value_table[:SyntaxVersion]
480
+ end
481
+
482
+ def link_to(struct)
483
+ case struct
484
+ when GUID_Klass
485
+ link_and_xref :syntax_guid_link_to, struct
486
+ when RPC_VERSION_Klass
487
+ link_and_xref :syntax_version_link_to, struct
488
+ end
489
+ end
490
+ end
491
+
492
+ class RPC_DISPATCH_TABLE_Klass < Structures_Klass
493
+ def parse_struct(cstruct)
494
+ @value_table = {
495
+ DispatchTableCount: cstruct['dispatchTableCount'].value,
496
+ DispatchTable: cstruct['dispatchTable'].to_s,
497
+ Reserved: cstruct['seserved'].to_s
498
+ }
499
+
500
+ @dispatch_table_link_to = nil
501
+ end
502
+
503
+
504
+ def DispatchTable
505
+ @dispatch_table_link_to || @value_table[:DispatchTable]
506
+ end
507
+
508
+ def DispatchFunctions # Virtual Field
509
+ self.DispatchTable
510
+ end
511
+
512
+ def link_to(dispatch_funcs)
513
+ if dispatch_funcs.is_a?(Array)
514
+ @dispatch_table_link_to = dispatch_funcs
515
+ end
516
+ end
517
+ end
518
+
519
+ class RPC_SERVER_INTERFACE_Klass < Structures_Klass
520
+ def parse_struct(cstruct)
521
+ @value_table = {
522
+ Length: cstruct['length'].value,
523
+ InterfaceId: cstruct['interfaceId'].to_s,
524
+ TransferSyntax: cstruct['transferSyntax'].to_s,
525
+ DispatchTable: cstruct['dispatchTable'].value,
526
+ RpcProtseqEndpointCount: cstruct['rpcProtseqEndpointCount'].value,
527
+ RpcProtseqEndpoint: cstruct['rpcProtseqEndpoint'].value,
528
+ DefaultManagerEpv: cstruct['defaultManagerEpv'].value,
529
+ InterpreterInfo: cstruct['interpreterInfo'].value,
530
+ Flags: cstruct['flags'].value
531
+ }
532
+
533
+ @interface_id_link_to = nil
534
+ link_and_xref :interface_id_link_to, RPC_SYNTAX_IDENTIFIER_Klass.new(cstruct['interfaceId'])
535
+ link_and_xref :transfer_syntax_link_to, RPC_SYNTAX_IDENTIFIER_Klass.new(cstruct['transferSyntax'])
536
+ @interpreterInfo_link_to = nil
537
+ @dispatch_table_link_to = nil
538
+
539
+ true
540
+ end
541
+
542
+ def ndr64?
543
+ NDR64_TransferSyntax.to_s == @value_table[:TransferSyntax]
544
+ end
545
+
546
+ def dce?
547
+ DCE_TransferSyntax.to_s == @value_table[:TransferSyntax]
548
+ end
549
+
550
+ def dispatch_table_nullptr?
551
+ @value_table[:DispatchTable] == 0
552
+ end
553
+
554
+ def interpreter_info_nullptr?
555
+ @value_table[:InterpreterInfo] == 0
556
+ end
557
+
558
+ def server_routines
559
+ unless interpreter_info_nullptr?
560
+ begin
561
+ routines = self.InterpreterInfo.server_routines
562
+ return routines
563
+ end
564
+ end
565
+
566
+ []
567
+ end
568
+
569
+ def InterfaceId
570
+ @interface_id_link_to || @value_table[:InterfaceId]
571
+ end
572
+
573
+ def TransferSyntax
574
+ @transfer_syntax_link_to || @value_table[:TransferSyntax]
575
+ end
576
+
577
+ def DispatchTable
578
+ @dispatch_table_link_to || @value_table[:DispatchTable]
579
+ end
580
+
581
+ def InterpreterInfo
582
+ @interpreterInfo_link_to || @value_table[:InterpreterInfo]
583
+ end
584
+
585
+ def link_to(struct)
586
+ if struct.to_s == DCE_TransferSyntax.to_s || struct.to_s == NDR64_TransferSyntax.to_s
587
+ return link_and_xref(:transfer_syntax_link_to, struct)
588
+ end
589
+
590
+ case struct
591
+ when RPC_SYNTAX_IDENTIFIER_Klass
592
+ case struct.type
593
+ when :interface_id
594
+ link_and_xref :interface_id_link_to, struct
595
+ when :transfer_syntax
596
+ link_and_xref :transfer_syntax_link_to, struct
597
+ end
598
+ when MIDL_SERVER_INFO_Klass
599
+ link_and_xref :interpreterInfo_link_to, struct
600
+ when RPC_DISPATCH_TABLE_Klass
601
+ link_and_xref :dispatch_table_link_to, struct
602
+ when MIDL_STUBLESS_PROXY_INFO_Klass
603
+ link_and_xref :interpreterInfo_link_to, struct
604
+ end
605
+ end
606
+ end
607
+
608
+ class SERVER_ROUTINE_Klass < Structures_Klass
609
+ attr_reader :addr
610
+ attr_reader :proc_num
611
+
612
+ def initialize(routine)
613
+ @addr = routine
614
+ @proc_num = nil
615
+ end
616
+ end
617
+
618
+ class CLIENT_ROUTINE_Klass < Structures_Klass
619
+ attr_reader :addr
620
+ attr_accessor :proc_num
621
+
622
+ def initialize(routine, opts = {})
623
+ @addr = routine
624
+ @proc_num = opts[:proc_num]
625
+ end
626
+ end
627
+
628
+ class MIDL_SERVER_INFO_Klass < Structures_Klass
629
+ def parse_struct(cstruct)
630
+ @value_table = {
631
+ pStubDesc: cstruct['pStubDesc'].value,
632
+ DispatchTable: cstruct['dispatchTable'].value,
633
+ ProcString: cstruct['procString'].value,
634
+ ProcFormatString: cstruct['procString'].value, # alias of ProcString
635
+ FmtStringOffset: cstruct['fmtStringOffset'].value,
636
+ FormatStringOffset: cstruct['fmtStringOffset'].value, # alias of FmtStringOffset
637
+ ThunkTable: cstruct['thunkTable'].value,
638
+ pTransferSyntax: cstruct['pTransferSyntax'].value,
639
+ nCount: cstruct['nCount'].value,
640
+ pSyntaxInfo: cstruct['pSyntaxInfo'].value
641
+ }
642
+
643
+ @dispatch_table_link_to = nil
644
+ @syntax_info_link_to = nil
645
+ @transfer_syntax_link_to = nil
646
+ @stub_desc_link_to = nil
647
+
648
+ true
649
+ end
650
+
651
+ def server_routines
652
+ self.DispatchTable rescue nil
653
+ end
654
+
655
+ def DispatchTable
656
+ @dispatch_table_link_to || @value_table[:DispatchTable]
657
+ end
658
+
659
+ def pStubDesc
660
+ @stub_desc_link_to || @value_table[:pStubDesc]
661
+ end
662
+
663
+ def pSyntaxInfo
664
+ @syntax_info_link_to || @value_table[:pSyntaxInfo]
665
+ end
666
+
667
+ def link_to(struct)
668
+ case struct
669
+ when Array
670
+ @dispatch_table_link_to = struct
671
+ when MIDL_STUB_DESC_Klass
672
+ link_and_xref :stub_desc_link_to, struct
673
+ when MIDL_SYNTAX_INFO_Klass, Array
674
+ link_and_xref :syntax_info_link_to, struct
675
+ end
676
+ end
677
+ end
678
+
679
+ class MIDL_SYNTAX_INFO_Klass < Structures_Klass
680
+ def parse_struct(cstruct)
681
+ @value_table = {
682
+ TransferSyntax: cstruct['transferSyntax'],
683
+ DispatchTable: cstruct['dispatchTable'].value,
684
+ ProcString: cstruct['procString'].value,
685
+ FmtStringOffset: cstruct['fmtStringOffset'].value,
686
+ TypeString: cstruct['typeString'].value,
687
+ aUserMarshalQuadruple: cstruct['aUserMarshalQuadruple'].value,
688
+ pMethodProperties: cstruct['pMethodProperties'].value,
689
+ pReserved2: cstruct['pReserved2'].value
690
+ }
691
+
692
+ @dispatch_table_link_to = nil
693
+ end
694
+
695
+ def DispatchTable
696
+ @dispatch_table_link_to || @value_table[:DispatchTable]
697
+ end
698
+
699
+ def link_to(struct)
700
+ if struct.is_a? RPC_DISPATCH_TABLE_Klass
701
+ link_and_xref :dispatch_table_link_to, struct
702
+ end
703
+ end
704
+ end
705
+
706
+ class MIDL_STUBLESS_PROXY_INFO_Klass < Structures_Klass
707
+ def parse_struct(cstruct)
708
+ @value_table = {
709
+ pStubDesc: cstruct['pStubDesc'].value,
710
+ ProcFormatString: cstruct['procFormatString'].value,
711
+ FormatStringOffset: cstruct['formatStringOffset'].value,
712
+ pTransferSyntax: cstruct['pTransferSyntax'].value,
713
+ nCount: cstruct['nCount'].value,
714
+ pSyntaxInfo: cstruct['pSyntaxInfo'].value
715
+ }
716
+
717
+ @stub_desc_link_to = nil
718
+ @syntax_info_link_to = nil
719
+ @transfer_syntax_link_to = nil
720
+ end
721
+
722
+ def link_to(struct)
723
+ case struct
724
+ when MIDL_STUB_DESC_Klass
725
+ link_and_xref :stub_desc_link_to, struct
726
+ when MIDL_SYNTAX_INFO_Klass
727
+ link_and_xref :syntax_info_link_to, struct
728
+ end
729
+ end
730
+ end
731
+
732
+ class MIDL_STUB_DESC_Klass < Structures_Klass
733
+ def parse_struct(cstruct)
734
+ @value_table = {
735
+ RpcInterfaceInformation: cstruct['rpcInterfaceInformation'].value,
736
+ pfnAllocate: cstruct['pfnAllocate'].value,
737
+ pfnFree: cstruct['pfnFree'].value,
738
+ pAutoHandle: cstruct['implicit_handle_info'].value,
739
+ pPrimitiveHandle: cstruct['implicit_handle_info'].value,
740
+ pGenericBindingInfo: cstruct['implicit_handle_info'].value,
741
+ apfnNdrRundownRoutines: cstruct['apfnNdrRundownRoutines'].value,
742
+ aGenericBindingRoutinePairs: cstruct['aGenericBindingRoutinePairs'].value,
743
+ apfnExprEval: cstruct['apfnExprEval'].value,
744
+ aXmitQuintuple: cstruct['aXmitQuintuple'].value,
745
+ pFormatTypes: cstruct['pFormatTypes'].value,
746
+ fCheckBounds: cstruct['fCheckBounds'].value,
747
+ Version: cstruct['version'].value,
748
+ pMallocFreeStruct: cstruct['pMallocFreeStruct'].value,
749
+ MIDLVersion: cstruct['midlVersion'].value,
750
+ CommFaultOffsets: cstruct['commFaultOffsets'].value,
751
+ aUserMarshalQuadruple: cstruct['aUserMarshalQuadruple'].value,
752
+ NotifyRoutineTable: cstruct['notifyRoutineTable'].value,
753
+ mFlags: cstruct['mFlags'].value,
754
+ CsRoutineTables: cstruct['csRoutineTables'].value,
755
+ ProxyServerInfo: cstruct['proxyServerInfo'].value,
756
+ pExprInfo: cstruct['pExprInfo'].value
757
+ }
758
+
759
+ @interface_info_link_to = nil
760
+ @format_types_link_to = nil
761
+
762
+ true
763
+ end
764
+
765
+ def pFormatTypes
766
+ @value_table[:pFormatTypes] || @format_types_link_to
767
+ end
768
+
769
+ def link_to(struct)
770
+ if struct.is_a? RPC_SERVER_INTERFACE_Klass
771
+ link_and_xref :interface_info_link_to, struct
772
+ end
773
+ end
774
+ end
775
+ end
776
+ end
777
+ end