turborex 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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