Coverage Report

Created: 2026-05-14 06:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-wmio.c
Line
Count
Source
1
/* packet-wmio.c
2
 * Wireshark's WMIO dissector.
3
 *
4
 * Copyright 2024, Hiddencodes Sec <hidd3ncod3s[]gmail.com>
5
 *
6
 * Wireshark - Network traffic analyzer
7
 * By Gerald Combs <gerald@wireshark.org>
8
 * Copyright 1998 Gerald Combs
9
 *
10
 * SPDX-License-Identifier: GPL-2.0-or-later
11
 */
12
13
#include "config.h"
14
15
#include <epan/packet.h>
16
#include "packet-dcerpc.h"
17
#include <packet-dcom.h>
18
19
void proto_register_WMIO (void);
20
void proto_reg_handoff_WMIO (void);
21
22
static int proto_WMIO;
23
24
/*  IWbemClassObject Interface
25
 *    https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-wmi/46710c5c-d7ab-4e4c-b4a5-ebff311fdcd1
26
 *    dc12a681-737f-11cf-884d-00aa004b2e24
27
 */
28
static e_guid_t iid_WMIO = { 0xdc12a681, 0x737f, 0x11cf, { 0x88, 0x4d, 0x00, 0xaa, 0x00, 0x4b, 0x2e, 0x24} };
29
30
static uint32_t wmio_signature = 0x12345678;
31
32
0
#define CLASS_HEADER_LENGTH 13
33
34
0
#define WMIO_OBJECT_FLAG_CIM_CLASS               0X01
35
#define WMIO_OBJECT_FLAG_CIM_INSTANCE            0X02
36
0
#define WMIO_OBJECT_FLAG_HAS_DECORATION          0X04
37
#define WMIO_OBJECT_FLAG_PROTOTYPE_RESULT_OBJECT 0X10
38
#define WMIO_OBJECT_FLAG_KEY_PROPERTY_MISSING    0X40
39
40
#define WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE      0x01
41
#define WBEM_FLAVOR_FLAG_PROPAGATE_TO_DERIVED_CLASS 0x02
42
#define WBEM_FLAVOR_NOT_OVERRIDABLE                 0x10
43
#define WBEM_FLAVOR_ORIGIN_PROPAGATED               0x20
44
#define WBEM_FLAVOR_ORIGIN_SYSTEM                   0x40
45
#define WBEM_FLAVOR_AMENDED                         0x80
46
47
0
#define CIM_ARRAY_FLAG 0x2000
48
#define INHERITED_PROPERTY_TYPE 0x00004000
49
50
/* CimType
51
 *   https://learn.microsoft.com/de-de/openspecs/windows_protocols/ms-wmio/e137e6c6-c1cc-449e-a0b4-76fabf534480
52
 *   CimType is a 32-bit value of which only the lower 16 bits are used.
53
 */
54
0
#define CIM_TYPE_SINT16    2
55
0
#define CIM_TYPE_SINT32    3
56
0
#define CIM_TYPE_REAL32    4
57
0
#define CIM_TYPE_REAL64    5
58
0
#define CIM_TYPE_STRING    8
59
0
#define CIM_TYPE_BOOLEAN   11
60
0
#define CIM_TYPE_OBJECT    13
61
0
#define CIM_TYPE_SINT8     16
62
0
#define CIM_TYPE_UINT8     17
63
0
#define CIM_TYPE_UINT16    18
64
0
#define CIM_TYPE_UINT32    19
65
0
#define CIM_TYPE_SINT64    20
66
0
#define CIM_TYPE_UINT64    21
67
0
#define CIM_TYPE_DATETIME  101
68
0
#define CIM_TYPE_REFERENCE 102
69
0
#define CIM_TYPE_CHAR16    103
70
71
0
#define CIM_ARRAY_TYPE(X) (CIM_ARRAY_FLAG | X)
72
73
0
#define CIM_ARRAY_SINT8     CIM_ARRAY_TYPE(CIM_TYPE_SINT8)
74
0
#define CIM_ARRAY_UINT8     CIM_ARRAY_TYPE(CIM_TYPE_UINT8)
75
0
#define CIM_ARRAY_SINT16    CIM_ARRAY_TYPE(CIM_TYPE_SINT16)
76
0
#define CIM_ARRAY_UINT16    CIM_ARRAY_TYPE(CIM_TYPE_UINT16)
77
0
#define CIM_ARRAY_SINT32    CIM_ARRAY_TYPE(CIM_TYPE_SINT32)
78
0
#define CIM_ARRAY_UINT32    CIM_ARRAY_TYPE(CIM_TYPE_UINT32)
79
0
#define CIM_ARRAY_SINT64    CIM_ARRAY_TYPE(CIM_TYPE_SINT64)
80
0
#define CIM_ARRAY_UINT64    CIM_ARRAY_TYPE(CIM_TYPE_UINT64)
81
0
#define CIM_ARRAY_REAL32    CIM_ARRAY_TYPE(CIM_TYPE_REAL32)
82
0
#define CIM_ARRAY_REAL64    CIM_ARRAY_TYPE(CIM_TYPE_REAL64)
83
0
#define CIM_ARRAY_BOOLEAN   CIM_ARRAY_TYPE(CIM_TYPE_BOOLEAN)
84
0
#define CIM_ARRAY_STRING    CIM_ARRAY_TYPE(CIM_TYPE_STRING)
85
0
#define CIM_ARRAY_DATETIME  CIM_ARRAY_TYPE(CIM_TYPE_DATETIME)
86
0
#define CIM_ARRAY_REFERENCE CIM_ARRAY_TYPE(CIM_TYPE_REFERENCE)
87
0
#define CIM_ARRAY_CHAR16    CIM_ARRAY_TYPE(CIM_TYPE_CHAR16)
88
0
#define CIM_ARRAY_OBJECT    CIM_ARRAY_TYPE(CIM_TYPE_OBJECT)
89
90
#define STRINGFY(X) { X, #X}
91
92
static const value_string cim_types[] = {
93
  STRINGFY(CIM_TYPE_SINT8),
94
  STRINGFY(CIM_TYPE_UINT8),
95
  STRINGFY(CIM_TYPE_SINT16),
96
  STRINGFY(CIM_TYPE_UINT16),
97
  STRINGFY(CIM_TYPE_SINT32),
98
  STRINGFY(CIM_TYPE_UINT32),
99
  STRINGFY(CIM_TYPE_SINT64),
100
  STRINGFY(CIM_TYPE_UINT64),
101
  STRINGFY(CIM_TYPE_REAL32),
102
  STRINGFY(CIM_TYPE_REAL64),
103
  STRINGFY(CIM_TYPE_BOOLEAN),
104
  STRINGFY(CIM_TYPE_STRING),
105
  STRINGFY(CIM_TYPE_DATETIME),
106
  STRINGFY(CIM_TYPE_REFERENCE),
107
  STRINGFY(CIM_TYPE_CHAR16),
108
  STRINGFY(CIM_TYPE_OBJECT),
109
  STRINGFY(CIM_ARRAY_SINT8),
110
  STRINGFY(CIM_ARRAY_UINT8),
111
  STRINGFY(CIM_ARRAY_SINT16),
112
  STRINGFY(CIM_ARRAY_UINT16),
113
  STRINGFY(CIM_ARRAY_SINT32),
114
  STRINGFY(CIM_ARRAY_UINT32),
115
  STRINGFY(CIM_ARRAY_SINT64),
116
  STRINGFY(CIM_ARRAY_UINT64),
117
  STRINGFY(CIM_ARRAY_REAL32),
118
  STRINGFY(CIM_ARRAY_REAL64),
119
  STRINGFY(CIM_ARRAY_BOOLEAN),
120
  STRINGFY(CIM_ARRAY_STRING),
121
  STRINGFY(CIM_ARRAY_DATETIME),
122
  STRINGFY(CIM_ARRAY_REFERENCE),
123
  STRINGFY(CIM_ARRAY_CHAR16),
124
  STRINGFY(CIM_ARRAY_OBJECT),
125
  { 0,  NULL } };
126
127
static int hf_wmio;
128
static int hf_wmio_signature;
129
static int hf_wmio_objectencodinglength;
130
static int hf_wmio_object_flags;
131
static int hf_wmio_object_flags_cim_class;
132
static int hf_wmio_object_flags_cim_instance;
133
static int hf_wmio_object_flags_has_decoration;
134
static int hf_wmio_object_flags_prototype_result_object;
135
static int hf_wmio_object_flags_key_property_missing;
136
static int hf_wmio_decoration;
137
static int hf_wmio_decoration_server_name;
138
static int hf_wmio_decoration_namespace;
139
static int hf_wmio_encoded_string;
140
static int hf_wmio_encoded_string_flags;
141
static int hf_wmio_encoded_string_flags_unicode;
142
static int hf_wmio_class_part;
143
static int hf_wmio_class_header;
144
static int hf_wmio_class_header_partlength;
145
static int hf_wmio_class_header_nameref;
146
static int hf_wmio_class_header_ndtablevaluetablelength;
147
static int hf_wmio_class_derivation;
148
static int hf_wmio_class_derivation_length;
149
static int hf_wmio_derivation_classname;
150
static int hf_wmio_class_name_length;
151
static int hf_wmio_qualifierset;
152
static int hf_wmio_qualifierset_length;
153
static int hf_wmio_qualifier;
154
static int hf_wmio_qualifiername;
155
static int hf_wmio_cimtype;
156
static int hf_wmio_qualifiervalue;
157
static int hf_wmio_bytes;
158
static int hf_wmio_flavor;
159
static int hf_wmio_flavor_propagate_to_instance;
160
static int hf_wmio_flavor_propagate_to_derived_class;
161
static int hf_wmio_flavor_not_overridable;
162
static int hf_wmio_flavor_origin_propagated;
163
static int hf_wmio_flavor_origin_system;
164
static int hf_wmio_flavor_amended;
165
static int hf_wmio_propertylookuptable;
166
static int hf_wmio_propertylookuptable_count;
167
static int hf_wmio_propertylookup;
168
static int hf_wmio_propertynameref;
169
static int hf_wmio_propertyinforef;
170
static int hf_wmio_ndtable;
171
static int hf_wmio_heap;
172
static int hf_wmio_heap_length;
173
static int hf_methodspart;
174
static int hf_methodspart_length;
175
static int hf_methodspart_methodcount;
176
static int hf_methodspart_methods;
177
static int hf_methodspart_methoddescription;
178
static int hf_methoddescription_methodname;
179
static int hf_methoddescription_methodflags;
180
static int hf_methoddescription_methodqualifiers;
181
static int hf_parentclass;
182
static int hf_currentclass;
183
static int hf_methoddescription_methodorigin;
184
static int hf_methoddescription_inputsignature;
185
static int hf_methoddescription_outputsignature;
186
static int hf_heap_offset;
187
static int hf_property_info;
188
static int hf_declaration_order;
189
static int hf_propertyinfo_inherited;
190
static int hf_propertyinfo_valuetableoffset;
191
static int hf_propertyinfo_classoforigin;
192
static int hf_methodsignature_offset;
193
194
static hf_register_info hf[] = {
195
    { &hf_wmio,
196
    { "WMIO", "wmio", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
197
    { &hf_wmio_signature,
198
    { "Signature", "wmio.signature", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
199
    { &hf_wmio_objectencodinglength,
200
    { "Object Encoding Length", "wmio.objectencodinglength", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
201
    { &hf_wmio_object_flags,
202
    { "Object flags", "wmio.objectflags", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
203
    { &hf_wmio_object_flags_cim_class,
204
    { "CIM Class", "wmio.objectflags.cim_class", FT_BOOLEAN, 8, NULL, WMIO_OBJECT_FLAG_CIM_CLASS, NULL, HFILL }},
205
    { &hf_wmio_object_flags_cim_instance,
206
    { "CIM Instance", "wmio.objectflags.cim_Instance", FT_BOOLEAN, 8, NULL, WMIO_OBJECT_FLAG_CIM_INSTANCE, NULL, HFILL }},
207
    { &hf_wmio_object_flags_has_decoration,
208
    { "Has Decoration", "wmio.objectflags.has_decoration", FT_BOOLEAN, 8, NULL, WMIO_OBJECT_FLAG_HAS_DECORATION, NULL, HFILL }},
209
    { &hf_wmio_object_flags_prototype_result_object,
210
    { "Prototype Result Object", "wmio.objectflags.prototype_result_object", FT_BOOLEAN, 8, NULL, WMIO_OBJECT_FLAG_PROTOTYPE_RESULT_OBJECT, NULL, HFILL }},
211
    { &hf_wmio_object_flags_key_property_missing,
212
    { "Key Property Missing", "wmio.objectflags.key_property_missing", FT_BOOLEAN, 8, NULL, WMIO_OBJECT_FLAG_KEY_PROPERTY_MISSING, NULL, HFILL }},
213
    { &hf_wmio_encoded_string,
214
    { "Encoded String", "wmio.encoded_string", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
215
    { &hf_wmio_encoded_string_flags,
216
    { "Flag", "wmio.encoded_string.flags", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL }},
217
    { &hf_wmio_encoded_string_flags_unicode,
218
    { "Unicode", "wmio.encoded_string.flags.unicode", FT_BOOLEAN, 8, NULL, 0x1, NULL, HFILL }},
219
    { &hf_wmio_decoration,
220
    { "Decoration", "wmio.decoration", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
221
    { &hf_wmio_decoration_server_name,
222
    { "CIM Server Name", "wmio.decoration.server_name", FT_STRINGZ, BASE_NONE, NULL, 0x0, NULL, HFILL }},
223
    { &hf_wmio_decoration_namespace,
224
    { "CIM Namespace", "wmio.decoration.namespace", FT_STRINGZ, BASE_NONE, NULL, 0x0, NULL, HFILL }},
225
    { &hf_wmio_class_part,
226
    { "Class Part", "wmio.class.part", FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }},
227
    { &hf_wmio_class_header,
228
    { "Class Header", "wmio.class.header", FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }},
229
    { &hf_wmio_class_header_partlength,
230
    { "Class Header ClassPart Length", "wmio.class.header.length", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
231
    { &hf_wmio_class_header_nameref,
232
    { "Class Name Reference", "wmio.class.header.nameref", FT_STRINGZ, BASE_NONE, NULL, 0x0, NULL, HFILL }},
233
    { &hf_wmio_class_header_ndtablevaluetablelength,
234
    { "NdTable ValueTable Length", "wmio.class.header.ndtablevaluetablelength", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
235
    { &hf_wmio_class_derivation,
236
    { "Class Derivation", "wmio.class.derivation", FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }},
237
    { &hf_wmio_class_derivation_length,
238
    { "Class Derivation Length", "wmio.class.derivation.length", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
239
    { &hf_wmio_derivation_classname,
240
    { "Derivation", "wmio.derivation.classname", FT_STRINGZ, BASE_NONE, NULL, 0x0, NULL, HFILL }},
241
    { &hf_wmio_class_name_length,
242
    { "Class Name Length", "wmio.derivation.classname_length", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
243
    { &hf_wmio_qualifierset,
244
    { "Qualifier Set", "wmio.qualifierset", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
245
    { &hf_wmio_qualifierset_length,
246
    { "Qualifier Length", "wmio.derivation.qualifier_length", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
247
    { &hf_wmio_qualifier,
248
    { "Qualifier", "wmio.qualifier", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
249
    { &hf_wmio_qualifiername,
250
    { "Qualifier Name", "wmio.qualifier_name", FT_STRINGZ, BASE_NONE, NULL, 0x0, NULL, HFILL }},
251
    { &hf_wmio_flavor,
252
    { "Flavor", "wmio.flavor", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
253
    { &hf_wmio_flavor_propagate_to_instance,
254
    { "Propagate To Derived Instance", "wmio.flavor.propagate_to_instance", FT_BOOLEAN, 8, NULL, WBEM_FLAVOR_FLAG_PROPAGATE_TO_INSTANCE, NULL, HFILL }},
255
    { &hf_wmio_flavor_propagate_to_derived_class,
256
    { "Propagate To Derived Class", "wmio.flavor.propagate_to_derived_class", FT_BOOLEAN, 8, NULL, WBEM_FLAVOR_FLAG_PROPAGATE_TO_DERIVED_CLASS, NULL, HFILL }},
257
    { &hf_wmio_flavor_not_overridable,
258
    { "Not Overridable", "wmio.flavor.not_overridable", FT_BOOLEAN, 8, NULL, WBEM_FLAVOR_NOT_OVERRIDABLE, NULL, HFILL }},
259
    { &hf_wmio_flavor_origin_propagated,
260
    { "Origin Propagated", "wmio.flavor.origin_propagated", FT_BOOLEAN, 8, NULL, WBEM_FLAVOR_ORIGIN_PROPAGATED, NULL, HFILL }},
261
    { &hf_wmio_flavor_origin_system,
262
    { "Origin System", "wmio.flavor.origin_system", FT_BOOLEAN, 8, NULL, WBEM_FLAVOR_ORIGIN_SYSTEM, NULL, HFILL }},
263
    { &hf_wmio_flavor_amended,
264
    { "Amended", "wmio.flavor.amended", FT_BOOLEAN, 8, NULL, WBEM_FLAVOR_AMENDED, NULL, HFILL }},
265
    { &hf_wmio_cimtype,
266
    { "CIM Type", "wmio.cim_type", FT_UINT32, BASE_HEX, VALS(cim_types), 0, NULL, HFILL }},
267
    { &hf_wmio_propertylookuptable,
268
    { "Property Lookup Table", "wmio.property_lookup_table", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
269
    { &hf_wmio_propertylookuptable_count,
270
    { "Property Lookup Table Count", "wmio.property_lookup_table.count", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
271
    { &hf_wmio_ndtable,
272
    { "NdTable", "wmio.ndtable", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
273
    { &hf_wmio_propertylookup,
274
    { "Property Lookup", "wmio.property_lookup", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
275
    { &hf_wmio_propertynameref,
276
    { "Property Name Ref", "wmio.property_lookup.propertynameref", FT_STRINGZ, BASE_NONE, NULL, 0x0, NULL, HFILL }},
277
    { &hf_wmio_propertyinforef,
278
    { "Property Info Ref", "wmio.property_lookup.propertyinforef", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
279
    { &hf_wmio_heap,
280
    { "Heap", "wmio.heap", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
281
    { &hf_wmio_heap_length,
282
    { "HeapLength", "wmio.heap.length", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},
283
    { &hf_wmio_bytes,
284
    { "WMIO Bytes", "wmio.bytes", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }},
285
    { &hf_methodspart,
286
    { "Methodspart", "wmio.methodspart", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
287
    { &hf_methodspart_length,
288
    { "Methodspart Length", "wmio.methodspart.length", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
289
    { &hf_methodspart_methodcount,
290
    { "Methods Count", "wmio.methodspart.methodcount", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
291
    { &hf_methodspart_methods,
292
    { "Methods", "wmio.methodspart.methods", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
293
    { &hf_methodspart_methoddescription,
294
    { "MethodDescription", "wmio.methodspart.methoddescription", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
295
    { &hf_methoddescription_methodname,
296
    { "Methodname", "wmio.methodspart.methoddescription.methodname", FT_STRINGZ, BASE_NONE, NULL, 0x0, NULL, HFILL }},
297
    { &hf_methoddescription_methodflags,
298
    { "Methodflags", "wmio.methodspart.methoddescription.methodflags", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
299
    { &hf_methoddescription_methodorigin,
300
    { "Methodorigin", "wmio.methodspart.methoddescription.methodorigin", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
301
    { &hf_methoddescription_methodqualifiers,
302
    { "Methodqualifiers", "wmio.methodspart.methoddescription.methodqualifiers", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
303
    { &hf_methoddescription_inputsignature,
304
    { "Inputsignature", "wmio.methodspart.methoddescription.inputsignature", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
305
    { &hf_methoddescription_outputsignature,
306
    { "Outputsignature", "wmio.methodspart.methoddescription.outputsignature", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
307
    { &hf_parentclass,
308
    { "Parent Class", "wmio.parentclass", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
309
    { &hf_currentclass,
310
    { "Current Class", "wmio.currentclass", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
311
    { &hf_heap_offset,
312
    { "Heap Offset", "wmio.heapoffset", FT_UINT32, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL }},
313
    { &hf_wmio_qualifiervalue,
314
    { "Qualifier Value", "wmio.qualifier_value", FT_STRINGZ, BASE_NONE, NULL, 0x0, NULL, HFILL }},
315
    { &hf_property_info,
316
    { "Property Info", "wmio.property_info", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
317
    { &hf_declaration_order,
318
    { "Declaration Order", "wmio.declaration_order", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
319
    { &hf_propertyinfo_inherited,
320
    { "Inherited", "wmio.propertytype.inherited", FT_BOOLEAN, 32, NULL, INHERITED_PROPERTY_TYPE, NULL, HFILL }},
321
    { &hf_propertyinfo_valuetableoffset,
322
    { "ValueTable Offset", "wmio.propertytype.valuetableoffset", FT_UINT32, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL }},
323
    { &hf_propertyinfo_classoforigin,
324
    { "ClassOfOrigin", "wmio.propertytype.classoforigin", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
325
    { &hf_methodsignature_offset,
326
    { "Methodsignature Offset", "wmio.methodsignature.offset", FT_UINT32, BASE_HEX_DEC, NULL, 0x0, NULL, HFILL }},
327
};
328
329
static int * const wmio_object_flags[] = {
330
    &hf_wmio_object_flags_cim_class,
331
    &hf_wmio_object_flags_cim_instance,
332
    &hf_wmio_object_flags_has_decoration,
333
    &hf_wmio_object_flags_prototype_result_object,
334
    &hf_wmio_object_flags_key_property_missing,
335
    NULL
336
};
337
338
static int * const wmio_flavor[] = {
339
    &hf_wmio_flavor_propagate_to_instance,
340
    &hf_wmio_flavor_propagate_to_derived_class,
341
    &hf_wmio_flavor_not_overridable,
342
    &hf_wmio_flavor_origin_propagated,
343
    &hf_wmio_flavor_origin_system,
344
    &hf_wmio_flavor_amended,
345
    NULL
346
};
347
348
static int * const wmio_encoded_string_flags[] = {
349
    &hf_wmio_encoded_string_flags_unicode,
350
    NULL
351
};
352
353
static int ett_wmio;
354
static int ett_wmio_object_flags;
355
static int ett_wmio_encoded_string;
356
static int ett_wmio_encoded_string_flags;
357
static int ett_wmio_class_part;
358
static int ett_wmio_class_header;
359
static int ett_wmio_decoration;
360
static int ett_wmio_class_derivation;
361
static int ett_wmio_qualifierset;
362
static int ett_wmio_qualifier;
363
static int ett_wmio_flavor;
364
static int ett_wmio_propertylookuptable;
365
static int ett_wmio_propertylookup;
366
static int ett_wmio_heap;
367
static int ett_methodspart;
368
static int ett_parentclass;
369
static int ett_currentclass;
370
static int ett_methodspart_methods;
371
static int ett_methodspart_methoddescription;
372
static int ett_methodsignature;
373
static int ett_property_info;
374
375
/* Tree */
376
static int *ett[] = {
377
    &ett_wmio,
378
    &ett_wmio_object_flags,
379
    &ett_wmio_encoded_string,
380
    &ett_wmio_encoded_string_flags,
381
    &ett_wmio_class_part,
382
    &ett_wmio_class_header,
383
    &ett_wmio_decoration,
384
    &ett_wmio_class_derivation,
385
    &ett_wmio_qualifierset,
386
    &ett_wmio_qualifier,
387
    &ett_wmio_flavor,
388
    &ett_wmio_propertylookuptable,
389
    &ett_wmio_propertylookup,
390
    &ett_wmio_heap,
391
    &ett_methodspart,
392
    &ett_methodspart_methods,
393
    &ett_methodspart_methoddescription,
394
    &ett_methodsignature,
395
    &ett_parentclass,
396
    &ett_currentclass,
397
    &ett_property_info,
398
};
399
400
static int dissect_wmio_objectblock(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree);
401
static int dissect_wmio_object_decoration(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree);
402
static int dissect_wmio_encoded_string(tvbuff_t *tvb, int offset, int hfindex, packet_info *pinfo, proto_tree *tree, bool withlength, int heapoffset);
403
static int dissect_wmio_encoding_classtype(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree);
404
static int dissect_wmio_encoding_classandmethodspart(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, int hf_index, int ett, bool methods);
405
static int dissect_wmio_encoding_classpart(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree);
406
static int dissect_wmio_encoding_classheader(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, uint32_t *pPartlength, uint32_t *pNdLength, int classheapoffset);
407
static int dissect_wmio_encoding_methodpart(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree);
408
static int dissect_wmio_encoding_methodpart_methods(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, uint32_t methodscount, int methodsheapoffset);
409
static int dissect_wmio_encoding_methodpart_methoddescription(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, int methodsheapoffset);
410
static int dissect_wmio_encoding_derivationlist(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree);
411
static int dissect_wmio_encoding_qualifierset(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree, int classheapoffset);
412
413
/* DictionaryReference
414
 * https://learn.microsoft.com/de-de/openspecs/windows_protocols/ms-wmio/40adf451-f5bc-4b0a-ab97-d620bb638470
415
 */
416
static const char* stringDictionary[] =
417
  { "'"
418
  , "key"
419
  , ""
420
  , "read"
421
  , "write"
422
  , "volatile"
423
  , "provider"
424
  , "dynamic"
425
  , "cimwin32"
426
  , "DWORD"
427
  , "CIMTYPE"
428
  };
429
430
/* Encoded-String
431
 * https://learn.microsoft.com/de-de/openspecs/windows_protocols/ms-wmio/2f3afcf6-169e-41ff-80c2-367f2f74285b
432
 *  Encoded-String = Encoded-String-Flag *Character Null
433
 *  Encoded-String-Flag = OCTET
434
 *  Character = AnsiCharacter / UnicodeCharacter
435
 *  Null = Character
436
 *  AnsiCharacter = OCTET
437
 *  UnicodeCharacter = 2OCTET
438
 */
439
static int
440
dissect_wmio_encoded_string(tvbuff_t *tvb, int offset, int hfindex, packet_info *pinfo,
441
        proto_tree *tree, bool withlength, int heapoffset)
442
0
{
443
0
    proto_item *sub_item;
444
0
    proto_tree *sub_tree;
445
0
    int old_offset = offset;
446
0
    int fn_len = 0;
447
0
    header_field_info *hfinfo;
448
0
    char *s= NULL;
449
0
    uint32_t foffset = 0;
450
451
    /* Make sure this really is a string field. */
452
0
    hfinfo = proto_registrar_get_nth(hfindex);
453
0
    DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_STRINGZ);
454
455
0
    if(heapoffset > 0){
456
        /* HeapRef
457
         *   https://learn.microsoft.com/de-de/openspecs/windows_protocols/ms-wmio/f9d22d98-ed26-45d7-8792-aa0f210cffb2
458
         *   HeapRef is a reference to any HeapItem and is expressed in 31 bits. If the HeapItem referred to is a string,
459
         *   and the most significant bit of the 32-bit HeapStringRef value is set, the reference is actually to an implied
460
         *   dictionary-based string entry and does not point to a literal Encoded-String within the Heap.
461
         */
462
0
        foffset = tvb_get_uint32(tvb, offset, ENC_LITTLE_ENDIAN);
463
464
0
        if (foffset < 0x80000000){
465
0
            offset = heapoffset + foffset;
466
0
        }
467
0
    }
468
469
0
    sub_item = proto_tree_add_item(tree, hf_wmio_encoded_string, tvb, offset, -1, ENC_NA);
470
0
    sub_tree = proto_item_add_subtree(sub_item, ett_wmio_encoded_string);
471
472
0
    if((heapoffset > 0) && (foffset >= 0x80000000)){
473
0
        proto_tree_add_item(sub_tree, hf_heap_offset, tvb, old_offset, 4, ENC_LITTLE_ENDIAN);
474
        /*  https://learn.microsoft.com/de-de/openspecs/windows_protocols/ms-wmio/f9d22d98-ed26-45d7-8792-aa0f210cffb2
475
         *  If the value of HeapRef is 0xFFFFFFFF, then HeapItem is not present and MUST be considered NULL.
476
         */
477
0
        if(foffset == 0xFFFFFFFF){
478
            /* NULL String */
479
0
            proto_item_set_text(sub_tree, "%s: %s", proto_registrar_get_name(hfindex), "NULL");
480
0
            proto_item_set_len(sub_item, 4);
481
0
        } else {
482
0
            if (foffset & 0x80000000){
483
0
                foffset = 0x7FFFFFFF & foffset;
484
0
                if (foffset < array_length(stringDictionary)){
485
0
                    proto_item_set_text(sub_tree, "%s: %s", proto_registrar_get_name(hfindex), stringDictionary[foffset]);
486
0
                } else {
487
0
                    proto_item_set_text(sub_tree, "%s: Unknown Index %d", proto_registrar_get_name(hfindex), hfindex);
488
0
                }
489
0
                proto_item_set_len(sub_item, 4);
490
0
            }
491
0
        }
492
0
    } else {
493
0
        uint64_t encoded_string_flags;
494
495
0
        if(heapoffset > 0){
496
0
            proto_tree_add_item(sub_tree, hf_heap_offset, tvb, old_offset, 4, ENC_LITTLE_ENDIAN);
497
0
        }
498
499
0
        old_offset = offset;
500
501
0
        proto_tree_add_bitmask_ret_uint64(sub_tree, tvb, offset, hf_wmio_encoded_string_flags, ett_wmio_encoded_string_flags, wmio_encoded_string_flags, ENC_NA, &encoded_string_flags);
502
0
        offset++;
503
504
0
        if (encoded_string_flags == 0){
505
            /* ASCII */
506
0
            proto_tree_add_item_ret_length(sub_tree, hfindex, tvb, offset, -1, ENC_ASCII, &fn_len);
507
0
            s = (char*)tvb_get_string_enc(pinfo->pool, tvb, offset, fn_len, ENC_ASCII);
508
0
        } else if (encoded_string_flags == 1){
509
            /* UNICODE */
510
0
            proto_tree_add_item_ret_length(sub_tree, hfindex, tvb, offset, -1, ENC_UTF_16|ENC_LITTLE_ENDIAN, &fn_len);
511
0
            s = (char*)tvb_get_string_enc(pinfo->pool, tvb, offset, fn_len, ENC_UTF_16);
512
0
        }
513
0
        offset += fn_len;
514
515
0
        proto_item_set_text(sub_tree, "%s: %s", proto_registrar_get_name(hfindex), s);
516
517
0
        if(withlength){
518
0
            proto_tree_add_item(sub_tree, hf_wmio_class_name_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
519
0
            offset += 4;
520
0
        }
521
0
        proto_item_set_len(sub_item, offset-old_offset);
522
0
    }
523
0
    return offset;
524
0
}
525
526
/* ObjectBlock
527
 *  https://learn.microsoft.com/de-de/openspecs/windows_protocols/ms-wmio/4e74c9f9-4a47-4111-9e67-6476c896b7fb
528
 *  ObjectBlock = ObjectFlags [Decoration] Encoding
529
 */
530
static int
531
// NOLINTNEXTLINE(misc-no-recursion)
532
dissect_wmio_objectblock(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
533
0
{
534
0
    int8_t flags = tvb_get_uint8(tvb, offset);
535
536
0
    proto_tree_add_bitmask(tree, tvb, offset, hf_wmio_object_flags,
537
0
                ett_wmio_object_flags, wmio_object_flags, ENC_NA);
538
0
    offset+=1;
539
540
0
    increment_dissection_depth(pinfo);
541
542
0
    if (WMIO_OBJECT_FLAG_HAS_DECORATION & flags){
543
0
        offset = dissect_wmio_object_decoration(tvb, offset, pinfo, tree);
544
0
    }
545
546
0
    if (WMIO_OBJECT_FLAG_CIM_CLASS & flags){
547
0
        offset = dissect_wmio_encoding_classtype(tvb, offset, pinfo, tree);
548
0
    }
549
550
0
    decrement_dissection_depth(pinfo);
551
552
0
    return offset;
553
0
}
554
555
/* Decoration = DecServerName DecNamespaceName
556
 *  https://learn.microsoft.com/de-de/openspecs/windows_protocols/ms-wmio/0650ad93-88fa-49e9-aebc-e4462e4a7786
557
 *  Decoration = DecServerName DecNamespaceName
558
 */
559
static int
560
dissect_wmio_object_decoration(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree)
561
0
{
562
0
    proto_item *item = NULL;
563
0
    proto_tree *tree = NULL;
564
0
    int old_offset = offset;
565
566
0
    item = proto_tree_add_item(parent_tree, hf_wmio_decoration, tvb, offset, -1, ENC_NA);
567
0
    tree = proto_item_add_subtree(item, ett_wmio_decoration);
568
569
0
    offset = dissect_wmio_encoded_string(tvb, offset, hf_wmio_decoration_server_name, pinfo, tree, false, 0);
570
0
    offset = dissect_wmio_encoded_string(tvb, offset, hf_wmio_decoration_namespace, pinfo, tree, false, 0);
571
572
0
    proto_item_set_len(item, offset-old_offset);
573
574
0
    return offset;
575
0
}
576
577
static int
578
// NOLINTNEXTLINE(misc-no-recursion)
579
dissect_wmio_encoding_classtype(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
580
0
{
581
0
    increment_dissection_depth(pinfo);
582
583
    // ParentClass
584
0
    offset = dissect_wmio_encoding_classandmethodspart(tvb, offset, pinfo, tree, hf_parentclass, ett_parentclass, true);
585
586
    // CurrentClass
587
0
    offset = dissect_wmio_encoding_classandmethodspart(tvb, offset, pinfo, tree, hf_currentclass, ett_currentclass, true);
588
589
0
    decrement_dissection_depth(pinfo);
590
591
0
    return offset;
592
0
}
593
594
/* ClassAndMethodsPart = ClassPart [MethodsPart]
595
 *  https://learn.microsoft.com/de-de/openspecs/windows_protocols/ms-wmio/35589520-cee8-4bb1-b09e-bb009d1d1b88
596
 *  ClassAndMethodsPart = ClassPart [MethodsPart]
597
 */
598
static int
599
// NOLINTNEXTLINE(misc-no-recursion)
600
dissect_wmio_encoding_classandmethodspart(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree, int hf_index, int ett_id, bool methods)
601
0
{
602
0
    proto_item *item = NULL;
603
0
    proto_tree *tree = NULL;
604
0
    int old_offset = offset;
605
606
0
    item = proto_tree_add_item(parent_tree, hf_index, tvb, offset, -1, ENC_NA);
607
0
    tree = proto_item_add_subtree(item, ett_id);
608
609
0
    offset = dissect_wmio_encoding_classpart(tvb, offset, pinfo, tree);
610
0
    if (methods){
611
0
        offset = dissect_wmio_encoding_methodpart(tvb, offset, pinfo, tree);
612
0
    }
613
614
0
    proto_item_set_len(item, offset-old_offset);
615
0
    return offset;
616
0
}
617
618
/* Qualifier
619
 *  https://learn.microsoft.com/de-de/openspecs/windows_protocols/ms-wmio/f4c4ec0a-e38b-4591-8111-cbb03cc405c2
620
 *  Qualifier = QualifierName QualifierFlavor QualifierType QualifierValue
621
 */
622
static int
623
dissect_wmio_qualifier(tvbuff_t *tvb, int offset, packet_info *pinfo,
624
        proto_tree *parent_tree, int classheapoffset)
625
0
{
626
0
    proto_item *item = NULL;
627
0
    proto_tree *tree = NULL;
628
0
    int old_offset = offset;
629
630
0
    item = proto_tree_add_item(parent_tree, hf_wmio_qualifier, tvb, offset, -1, ENC_NA);
631
0
    tree = proto_item_add_subtree(item, ett_wmio_qualifier);
632
633
0
    dissect_wmio_encoded_string(tvb, offset, hf_wmio_qualifiername, pinfo, tree, false, classheapoffset);
634
0
    offset+= 4;
635
636
0
    proto_tree_add_bitmask(tree, tvb, offset, hf_wmio_flavor, ett_wmio_flavor, wmio_flavor, ENC_NA);
637
0
    offset+= 1;
638
639
    // QualifierType = CimType
640
    // CimType is a 32-bit value
641
0
    int32_t cimType = tvb_get_uint32(tvb, offset, ENC_LITTLE_ENDIAN);
642
0
    proto_tree_add_item(tree, hf_wmio_cimtype, tvb, offset, 4, ENC_LITTLE_ENDIAN);
643
0
    offset+= 4;
644
645
    // QualifierValue = EncodedValue
646
0
    if (cimType & CIM_ARRAY_FLAG){
647
0
        uint32_t array_count = tvb_get_uint32(tvb, offset, ENC_LITTLE_ENDIAN);
648
0
        offset += 4;
649
650
        // CimArrayType
651
0
        switch(cimType){
652
0
            case CIM_ARRAY_SINT8:
653
0
                offset += array_count;
654
0
                break;
655
0
            case CIM_ARRAY_UINT8:
656
0
                offset += array_count;
657
0
                break;
658
0
            case CIM_ARRAY_SINT16:
659
0
                offset += (sizeof(int16_t) * array_count);
660
0
                break;
661
0
            case CIM_ARRAY_UINT16:
662
0
                offset += (sizeof(uint16_t) * array_count);
663
0
                break;
664
0
            case CIM_ARRAY_SINT32:
665
0
                offset += (sizeof(int32_t) * array_count);
666
0
                break;
667
0
            case CIM_ARRAY_UINT32:
668
0
                offset += (sizeof(uint32_t) * array_count);
669
0
                break;
670
0
            case CIM_ARRAY_SINT64:
671
0
                offset += (sizeof(int64_t) * array_count);
672
0
                break;
673
0
            case CIM_ARRAY_UINT64:
674
0
                offset += (sizeof(uint64_t) * array_count);
675
0
                break;
676
0
            case CIM_ARRAY_REAL32:
677
0
                offset += (sizeof(int32_t) * array_count);
678
0
                break;
679
0
            case CIM_ARRAY_REAL64:
680
0
                offset += (sizeof(int64_t) * array_count);
681
0
                break;
682
0
            case CIM_ARRAY_BOOLEAN:
683
0
                offset += (2 * array_count);
684
0
                break;
685
0
            case CIM_ARRAY_STRING:
686
0
            case CIM_ARRAY_DATETIME:
687
0
            case CIM_ARRAY_REFERENCE:
688
                // TODO
689
0
                break;
690
0
            case CIM_ARRAY_CHAR16:
691
0
                offset += (sizeof(int16_t) * array_count);
692
0
                break;
693
0
            case CIM_ARRAY_OBJECT:
694
0
                {
695
0
                    for (uint32_t i=0; i < array_count; i++){
696
0
                        int32_t objEncLength = tvb_get_uint32(tvb, offset, ENC_LITTLE_ENDIAN);
697
0
                        offset += objEncLength;
698
0
                    }
699
0
                    break;
700
0
                }
701
0
            default:
702
0
                break;
703
0
        }
704
0
    } else {
705
        // CimBaseType
706
0
        switch(cimType){
707
0
            case CIM_TYPE_SINT8:
708
0
                {
709
0
                proto_item *vitem = proto_tree_add_item(tree, hf_wmio_qualifiervalue, tvb, offset, -1, ENC_ASCII);
710
0
                proto_item_set_text(vitem, "%s: %d", proto_registrar_get_name(hf_wmio_qualifiervalue), tvb_get_int8(tvb, offset));
711
0
                proto_item_set_len(vitem, 1);
712
0
                offset+= 1;
713
0
                }
714
0
                break;
715
0
            case CIM_TYPE_UINT8:
716
0
                {
717
0
                proto_item *vitem = proto_tree_add_item(tree, hf_wmio_qualifiervalue, tvb, offset, -1, ENC_ASCII);
718
0
                proto_item_set_text(vitem, "%s: %u", proto_registrar_get_name(hf_wmio_qualifiervalue), tvb_get_int8(tvb, offset));
719
0
                proto_item_set_len(vitem, 1);
720
0
                offset+= 1;
721
0
                }
722
0
                break;
723
0
            case CIM_TYPE_SINT16:
724
0
            case CIM_TYPE_CHAR16:
725
0
                {
726
0
                proto_item *vitem = proto_tree_add_item(tree, hf_wmio_qualifiervalue, tvb, offset, -1, ENC_ASCII);
727
0
                proto_item_set_text(vitem, "%s: %d", proto_registrar_get_name(hf_wmio_qualifiervalue), tvb_get_int16(tvb, offset, ENC_LITTLE_ENDIAN));
728
0
                proto_item_set_len(vitem, 2);
729
0
                offset+= 2;
730
0
                }
731
0
                break;
732
0
            case CIM_TYPE_UINT16:
733
0
                {
734
0
                proto_item *vitem = proto_tree_add_item(tree, hf_wmio_qualifiervalue, tvb, offset, -1, ENC_ASCII);
735
0
                proto_item_set_text(tree, "%s: %u", proto_registrar_get_name(hf_wmio_qualifiervalue), tvb_get_uint16(tvb, offset, ENC_LITTLE_ENDIAN));
736
0
                proto_item_set_len(vitem, 2);
737
0
                offset+= 2;
738
0
                }
739
0
                break;
740
0
            case CIM_TYPE_SINT32:
741
0
                {
742
0
                proto_item *vitem = proto_tree_add_item(tree, hf_wmio_qualifiervalue, tvb, offset, -1, ENC_ASCII);
743
0
                proto_item_set_text(vitem, "%s: %d", proto_registrar_get_name(hf_wmio_qualifiervalue), tvb_get_int32(tvb, offset, ENC_LITTLE_ENDIAN));
744
0
                proto_item_set_len(vitem, 4);
745
0
                offset+= 4;
746
0
                }
747
0
                break;
748
0
            case CIM_TYPE_UINT32:
749
0
                {
750
0
                proto_item *vitem = proto_tree_add_item(tree, hf_wmio_qualifiervalue, tvb, offset, -1, ENC_ASCII);
751
0
                proto_item_set_text(vitem, "%s: %u", proto_registrar_get_name(hf_wmio_qualifiervalue), tvb_get_uint32(tvb, offset, ENC_LITTLE_ENDIAN));
752
0
                proto_item_set_len(vitem, 4);
753
0
                offset+= 4;
754
0
                }
755
0
                break;
756
0
            case CIM_TYPE_SINT64:
757
0
                {
758
0
                proto_item *vitem = proto_tree_add_item(tree, hf_wmio_qualifiervalue, tvb, offset, -1, ENC_ASCII);
759
0
                proto_item_set_text(vitem, "%s: %" PRIi64, proto_registrar_get_name(hf_wmio_qualifiervalue), tvb_get_int64(tvb, offset, ENC_LITTLE_ENDIAN));
760
0
                proto_item_set_len(vitem, 8);
761
0
                offset+= 8;
762
0
                }
763
0
                break;
764
0
            case CIM_TYPE_UINT64:
765
0
                {
766
0
                proto_item *vitem = proto_tree_add_item(tree, hf_wmio_qualifiervalue, tvb, offset, -1, ENC_ASCII);
767
0
                proto_item_set_text(vitem, "%s: %" PRIu64, proto_registrar_get_name(hf_wmio_qualifiervalue), tvb_get_uint64(tvb, offset, ENC_LITTLE_ENDIAN));
768
0
                proto_item_set_len(vitem, 8);
769
0
                offset+= 8;
770
0
                }
771
0
                break;
772
0
            case CIM_TYPE_REAL32:
773
0
                {
774
0
                proto_item *vitem = proto_tree_add_item(tree, hf_wmio_qualifiervalue, tvb, offset, -1, ENC_ASCII);
775
0
                proto_item_set_text(vitem, "%s: %f", proto_registrar_get_name(hf_wmio_qualifiervalue), tvb_get_ieee_float(tvb, offset, ENC_LITTLE_ENDIAN));
776
0
                proto_item_set_len(vitem, 4);
777
0
                offset+= 4;
778
0
                }
779
0
                break;
780
0
            case CIM_TYPE_REAL64:
781
0
                {
782
0
                proto_item *vitem = proto_tree_add_item(tree, hf_wmio_qualifiervalue, tvb, offset, -1, ENC_ASCII);
783
0
                proto_item_set_text(vitem, "%s: %lf", proto_registrar_get_name(hf_wmio_qualifiervalue), tvb_get_ieee_double(tvb, offset, ENC_LITTLE_ENDIAN));
784
0
                proto_item_set_len(vitem, 8);
785
0
                offset+= 8;
786
0
                }
787
0
                break;
788
0
            case CIM_TYPE_BOOLEAN:
789
0
                {
790
0
                proto_item *vitem = proto_tree_add_item(tree, hf_wmio_qualifiervalue, tvb, offset, -1, ENC_ASCII);
791
0
                proto_item_set_text(vitem, "%s: %s", proto_registrar_get_name(hf_wmio_qualifiervalue), 0 != tvb_get_uint16(tvb, offset, ENC_LITTLE_ENDIAN) ? "TRUE" : "FALSE");
792
0
                proto_item_set_len(vitem, 2);
793
0
                offset+= 2;
794
0
                }
795
0
                break;
796
0
            case CIM_TYPE_STRING:
797
0
            case CIM_TYPE_DATETIME:
798
0
            case CIM_TYPE_REFERENCE:
799
0
                dissect_wmio_encoded_string(tvb, offset, hf_wmio_qualifiervalue, pinfo, tree, false, classheapoffset);
800
0
                offset+= 4;
801
0
                break;
802
0
            case CIM_TYPE_OBJECT:
803
0
                {
804
0
                    int32_t objEncLength = tvb_get_uint32(tvb, offset, ENC_LITTLE_ENDIAN);
805
0
                    offset += objEncLength;
806
0
                }
807
0
                break;
808
0
            default:
809
0
                break;
810
0
        }
811
0
    }
812
813
0
    proto_item_set_len(item, offset - old_offset);
814
815
0
    return offset;
816
0
}
817
818
/* QualifierSet
819
 *  https://learn.microsoft.com/de-de/openspecs/windows_protocols/ms-wmio/224c7463-01df-4e09-bd71-650ec0b8adaf
820
 *  QualifierSet = EncodingLength *Qualifier
821
 */
822
static int
823
dissect_wmio_encoding_qualifierset(tvbuff_t *tvb, int offset, packet_info *pinfo,
824
        proto_tree *parent_tree, int classheapoffset)
825
0
{
826
0
    proto_item *item = NULL;
827
0
    proto_tree *tree = NULL;
828
0
    int old_offset = offset;
829
0
    uint32_t length;
830
831
0
    item = proto_tree_add_item(parent_tree, hf_wmio_qualifierset, tvb, offset, -1, ENC_NA);
832
0
    tree = proto_item_add_subtree(item, ett_wmio_qualifierset);
833
834
0
    proto_tree_add_item_ret_uint(tree, hf_wmio_qualifierset_length, tvb, offset, 4, ENC_LITTLE_ENDIAN, &length);
835
0
    offset += 4;
836
837
0
    while((uint32_t)offset < (old_offset + length)){
838
        /* N.B. guaranteed to advance offset */
839
0
        offset = dissect_wmio_qualifier(tvb, offset, pinfo, tree, classheapoffset);
840
0
    }
841
842
0
    proto_item_set_len(item, offset - old_offset);
843
844
0
    return old_offset+length;
845
0
}
846
847
/* PropertyInfo
848
 *  https://learn.microsoft.com/de-de/openspecs/windows_protocols/ms-wmio/563356b2-7bc7-4016-a88b-6685d3e09b59
849
 *  PropertyInfo = PropertyType DeclarationOrder ValueTableOffset ClassOfOrigin PropertyQualifierSet
850
 */
851
static void
852
dissect_wmio_encoding_propertyinfo(tvbuff_t *tvb, int offset, packet_info *pinfo,
853
        proto_tree *parent_tree, int classheapoffset)
854
0
{
855
0
    proto_item *item = NULL;
856
0
    proto_tree *tree = NULL;
857
0
    uint32_t propertyinfo_offset;
858
0
    int old_offset = 0;
859
860
0
    item = proto_tree_add_item(parent_tree, hf_property_info, tvb, offset, -1, ENC_NA);
861
0
    tree = proto_item_add_subtree(item, ett_property_info);
862
863
0
    proto_tree_add_item_ret_uint(tree, hf_wmio_propertyinforef, tvb, offset, 4, ENC_LITTLE_ENDIAN, &propertyinfo_offset);
864
865
0
    offset = classheapoffset + propertyinfo_offset;
866
0
    old_offset = offset;
867
868
0
    int32_t propType = tvb_get_uint32(tvb, offset, ENC_LITTLE_ENDIAN);
869
0
    proto_tree_add_uint(tree, hf_wmio_cimtype, tvb, offset, 4, propType & 0x3FFF);
870
0
    proto_tree_add_boolean(tree, hf_propertyinfo_inherited, tvb, offset, 4, propType);
871
0
    offset += 4;
872
873
0
    proto_tree_add_item(tree, hf_declaration_order, tvb, offset, 2, ENC_LITTLE_ENDIAN);
874
0
    offset += 2;
875
876
0
    proto_tree_add_item(tree, hf_propertyinfo_valuetableoffset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
877
0
    offset += 4;
878
879
0
    proto_tree_add_item(tree, hf_propertyinfo_classoforigin, tvb, offset, 4, ENC_LITTLE_ENDIAN);
880
0
    offset += 4;
881
882
0
    offset = dissect_wmio_encoding_qualifierset(tvb, offset, pinfo, tree, classheapoffset);
883
884
0
    proto_item_set_len(item, offset - old_offset);
885
0
}
886
887
/* PropertyLookup
888
 *  https://learn.microsoft.com/de-de/openspecs/windows_protocols/ms-wmio/e401de4a-58fa-423b-89e0-4b832a99d0e9
889
 *  PropertyLookup = PropertyNameRef PropertyInfoRef
890
 */
891
static int
892
dissect_wmio_encoding_propertylookup(tvbuff_t *tvb, int offset, packet_info *pinfo,
893
        proto_tree *parent_tree, int classheapoffset)
894
0
{
895
0
    proto_item *item = NULL;
896
0
    proto_tree *tree = NULL;
897
0
    int old_offset = offset;
898
899
0
    item = proto_tree_add_item(parent_tree, hf_wmio_propertylookup, tvb, offset, -1, ENC_NA);
900
0
    tree = proto_item_add_subtree(item, ett_wmio_propertylookup);
901
902
0
    dissect_wmio_encoded_string(tvb, offset, hf_wmio_propertynameref, pinfo, tree, false, classheapoffset);
903
0
    offset += 4;
904
905
906
0
    dissect_wmio_encoding_propertyinfo(tvb, offset, pinfo, tree, classheapoffset);
907
0
    offset += 4;
908
909
0
    proto_item_set_len(item, offset - old_offset);
910
911
0
    return offset;
912
0
}
913
914
/* PropertyLookupTable
915
 *  https://learn.microsoft.com/de-de/openspecs/windows_protocols/ms-wmio/d4927ca8-b358-48eb-8879-a57ea4f090c3
916
 *  PropertyLookupTable = PropertyCount *PropertyLookup
917
 */
918
static int
919
dissect_wmio_encoding_propertylookuptable(tvbuff_t *tvb, int offset, packet_info *pinfo,
920
        proto_tree *parent_tree, uint32_t *property_count, int classheapoffset)
921
0
{
922
0
    proto_item *item = NULL;
923
0
    proto_tree *tree = NULL;
924
0
    int old_offset = offset;
925
0
    uint32_t count;
926
927
0
    item = proto_tree_add_item(parent_tree, hf_wmio_propertylookuptable, tvb, offset, -1, ENC_NA);
928
0
    tree = proto_item_add_subtree(item, ett_wmio_propertylookuptable);
929
930
    // PropertyCount
931
0
    proto_tree_add_item_ret_uint(tree, hf_wmio_propertylookuptable_count, tvb, offset, 4, ENC_LITTLE_ENDIAN, &count);
932
0
    offset += 4;
933
934
0
    for(uint32_t i = 0; i < count; ++i){
935
0
        offset = dissect_wmio_encoding_propertylookup(tvb, offset, pinfo, tree, classheapoffset);
936
0
    }
937
938
0
    *property_count = count;
939
940
0
    proto_item_set_len(item, offset - old_offset);
941
942
0
    return offset;
943
0
}
944
945
/* ClassPart
946
 *  https://learn.microsoft.com/de-de/openspecs/windows_protocols/ms-wmio/06ec93f3-b4df-4f7e-b2ba-090cd435becc
947
 *  ClassPart = ClassHeader DerivationList ClassQualifierSet PropertyLookupTable [NdTable ValueTable] ClassHeap
948
 */
949
static int
950
dissect_wmio_encoding_classpart(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree)
951
0
{
952
0
    proto_item *item = NULL;
953
0
    proto_tree *tree = NULL;
954
0
    int old_offset = offset;
955
0
    int classheapoffset = 0;
956
957
0
    uint32_t partlength, ndLength;
958
0
    uint32_t property_count;
959
960
0
    item = proto_tree_add_item(parent_tree, hf_wmio_class_part, tvb, offset, -1, ENC_NA);
961
0
    tree = proto_item_add_subtree(item, ett_wmio_class_part);
962
963
0
    {
964
        /* Jump through the various structures to find the heap offset. */
965
0
        uint32_t derivationListLength = tvb_get_uint32(tvb, offset + CLASS_HEADER_LENGTH, ENC_LITTLE_ENDIAN);
966
0
        uint32_t classQualifierSetLength = tvb_get_uint32(tvb, offset + CLASS_HEADER_LENGTH + derivationListLength, ENC_LITTLE_ENDIAN);
967
0
        uint32_t propertyLookupTableLength = 4 + 8 * tvb_get_uint32(tvb, offset + CLASS_HEADER_LENGTH + derivationListLength + classQualifierSetLength, ENC_LITTLE_ENDIAN);
968
0
        uint32_t ndTableLength = tvb_get_uint32(tvb, offset + (CLASS_HEADER_LENGTH - 4), ENC_LITTLE_ENDIAN);
969
970
0
        classheapoffset = offset                    /* Starting offset */
971
0
                        + CLASS_HEADER_LENGTH       /* ClassHeader */
972
0
                        + derivationListLength      /* DerivationList */
973
0
                        + classQualifierSetLength   /* ClassQualifierSet */
974
0
                        + propertyLookupTableLength /* PropertyLookupTable */
975
0
                        + ndTableLength;            /* NdTable */
976
0
    }
977
978
0
    offset = dissect_wmio_encoding_classheader(tvb, offset, pinfo, tree, &partlength, &ndLength, classheapoffset+4);
979
0
    offset = dissect_wmio_encoding_derivationlist(tvb, offset, pinfo, tree);
980
0
    offset = dissect_wmio_encoding_qualifierset(tvb, offset, pinfo, tree,classheapoffset+4);
981
0
    offset = dissect_wmio_encoding_propertylookuptable(tvb, offset, pinfo, tree, &property_count, classheapoffset+4);
982
983
0
    if(ndLength > 0){
984
0
        proto_tree_add_item(tree, hf_wmio_ndtable, tvb, offset, ndLength, ENC_NA);
985
0
        offset += ndLength;
986
0
    }
987
988
0
    {
989
0
        proto_item *heapitem = NULL;
990
0
        proto_tree *heaptree = NULL;
991
992
0
        heapitem = proto_tree_add_item(tree, hf_wmio_heap, tvb, offset, -1, ENC_NA);
993
0
        heaptree = proto_item_add_subtree(heapitem, ett_wmio_heap);
994
995
0
        int32_t heaplength = 0x7FFFFFFF & tvb_get_uint32(tvb, offset, ENC_LITTLE_ENDIAN);
996
997
0
        proto_tree_add_uint(heaptree, hf_wmio_heap_length, tvb, offset, 4, heaplength);
998
999
0
        proto_item_set_len(heapitem, heaplength);
1000
0
    }
1001
1002
0
    proto_item_set_len(item, partlength);
1003
1004
0
    return old_offset + partlength;
1005
0
}
1006
1007
/* ClassHeader
1008
 *  https://learn.microsoft.com/de-de/openspecs/windows_protocols/ms-wmio/b179b579-9585-47b8-bef8-8fdca9f5a94d
1009
 *  ClassHeader = EncodingLength ReservedOctet ClassNameRef NdTableValueTableLength
1010
 */
1011
static int
1012
dissect_wmio_encoding_classheader(tvbuff_t *tvb, int offset, packet_info *pinfo,
1013
        proto_tree *parent_tree, uint32_t *pPartlength, uint32_t *pNdLength, int classheapoffset)
1014
0
{
1015
0
    proto_item *item = NULL;
1016
0
    proto_tree *tree = NULL;
1017
0
    int old_offset = offset;
1018
1019
0
    uint32_t partlength, length;
1020
1021
0
    item = proto_tree_add_item(parent_tree, hf_wmio_class_header, tvb, offset, -1, ENC_NA);
1022
0
    tree = proto_item_add_subtree(item, ett_wmio_class_header);
1023
1024
0
    proto_tree_add_item_ret_uint(tree, hf_wmio_class_header_partlength, tvb, offset, 4, ENC_LITTLE_ENDIAN, &partlength);
1025
0
    offset+= 4;
1026
0
    *pPartlength = partlength;
1027
1028
    // ReservedOctet
1029
0
    offset+= 1;
1030
1031
0
    dissect_wmio_encoded_string(tvb, offset, hf_wmio_class_header_nameref, pinfo, tree, false, classheapoffset);
1032
0
    offset+= 4;
1033
1034
0
    proto_tree_add_item_ret_uint(tree, hf_wmio_class_header_ndtablevaluetablelength, tvb, offset, 4, ENC_LITTLE_ENDIAN, &length);
1035
0
    offset+= 4;
1036
0
    *pNdLength = length;
1037
1038
0
    proto_item_set_len(item, offset-old_offset);
1039
1040
0
    return offset;
1041
0
}
1042
1043
/* DerivationList
1044
 *  https://learn.microsoft.com/de-de/openspecs/windows_protocols/ms-wmio/3bfbcac6-318c-4b0a-ab87-13bfbc86f36f
1045
 *  DerivationList = EncodingLength *ClassNameEncoding
1046
 */
1047
static int
1048
dissect_wmio_encoding_derivationlist(tvbuff_t *tvb, int offset, packet_info *pinfo,
1049
        proto_tree *parent_tree)
1050
0
{
1051
0
    proto_item *item = NULL;
1052
0
    proto_tree *tree = NULL;
1053
0
    int old_offset = offset;
1054
1055
0
    uint32_t length;
1056
1057
0
    item = proto_tree_add_item(parent_tree, hf_wmio_class_derivation, tvb, offset, -1, ENC_NA);
1058
0
    tree = proto_item_add_subtree(item, ett_wmio_class_derivation);
1059
1060
0
    proto_tree_add_item_ret_uint(tree, hf_wmio_class_derivation_length, tvb, offset, 4, ENC_LITTLE_ENDIAN, &length);
1061
0
    offset+= 4;
1062
1063
0
    while((uint32_t)offset < (old_offset + length)) {
1064
        /* Offset is guaranteed to increase here as heapoffset (last arg) is 0 */
1065
0
        offset = dissect_wmio_encoded_string(tvb, offset, hf_wmio_derivation_classname, pinfo, tree, true, 0);
1066
0
    }
1067
1068
0
    proto_item_set_len(item, length);
1069
1070
0
    return offset;
1071
0
}
1072
1073
/* MethodSignature
1074
 *  https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-wmio/a9d7c0d1-f99a-4762-b460-e881a8c7d566
1075
 *  MethodSignature = HeapMethodSignatureBlockRef
1076
 */
1077
static void
1078
// NOLINTNEXTLINE(misc-no-recursion)
1079
dissect_wmio_encoding_methodsignature(tvbuff_t *tvb, int offset, packet_info *pinfo,
1080
    proto_tree *parent_tree, int hfindex, int methodsheapoffset)
1081
0
{
1082
0
    proto_item *item = NULL;
1083
0
    proto_tree *tree = NULL;
1084
0
    int old_offset = 0;
1085
1086
0
    int32_t signatureHeapOffset = tvb_get_uint32(tvb, offset, ENC_LITTLE_ENDIAN);
1087
1088
0
    old_offset = methodsheapoffset + signatureHeapOffset;
1089
1090
0
    item = proto_tree_add_item(parent_tree, hfindex, tvb, old_offset, -1, ENC_NA);
1091
0
    tree = proto_item_add_subtree(item, ett_methodsignature);
1092
1093
0
    proto_tree_add_item(tree, hf_methodsignature_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1094
1095
0
    offset = old_offset;
1096
1097
0
    proto_tree_add_item(tree, hf_wmio_objectencodinglength, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1098
0
    offset+= 4;
1099
1100
0
    offset = dissect_wmio_objectblock(tvb, offset, pinfo, tree);
1101
1102
0
    proto_item_set_len(item, offset - old_offset);
1103
0
}
1104
1105
/* MethodDescription
1106
 *  https://learn.microsoft.com/de-de/openspecs/windows_protocols/ms-wmio/8c81e4fa-634a-469f-8434-4ef87f2f256e
1107
 *  MethodDescription = MethodName MethodFlags MethodPadding MethodOrigin MethodQualifiers InputSignature OutputSignature
1108
 */
1109
static int
1110
// NOLINTNEXTLINE(misc-no-recursion)
1111
dissect_wmio_encoding_methodpart_methoddescription(tvbuff_t *tvb, int offset, packet_info *pinfo,
1112
    proto_tree *parent_tree, int methodsheapoffset)
1113
0
{
1114
0
    proto_item *item = NULL;
1115
0
    proto_tree *tree = NULL;
1116
0
    int old_offset = offset;
1117
1118
0
    item = proto_tree_add_item(parent_tree, hf_methodspart_methoddescription, tvb, offset, -1, ENC_NA);
1119
0
    tree = proto_item_add_subtree(item, ett_methodspart_methoddescription);
1120
1121
0
    dissect_wmio_encoded_string(tvb, offset, hf_methoddescription_methodname, pinfo, tree, false, methodsheapoffset);
1122
0
    offset+= 4;
1123
1124
0
    proto_tree_add_item(tree, hf_methoddescription_methodflags, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1125
0
    offset+= 1;
1126
1127
    // MethodPadding
1128
0
    offset+= 3;
1129
1130
0
    proto_tree_add_item(tree, hf_methoddescription_methodorigin, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1131
0
    offset+= 4;
1132
1133
0
    proto_tree_add_item(tree, hf_methoddescription_methodqualifiers, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1134
0
    offset+= 4;
1135
1136
0
    dissect_wmio_encoding_methodsignature(tvb, offset, pinfo, tree, hf_methoddescription_inputsignature, methodsheapoffset);
1137
0
    offset+= 4;
1138
1139
0
    dissect_wmio_encoding_methodsignature(tvb, offset, pinfo, tree, hf_methoddescription_outputsignature, methodsheapoffset);
1140
0
    offset+= 4;
1141
1142
0
    proto_item_set_len(item, offset - old_offset);
1143
1144
0
    return offset;
1145
0
}
1146
1147
static int
1148
// NOLINTNEXTLINE(misc-no-recursion)
1149
dissect_wmio_encoding_methodpart_methods(tvbuff_t *tvb, int offset, packet_info *pinfo,
1150
    proto_tree *parent_tree, uint32_t methodscount, int methodsheapoffset)
1151
0
{
1152
0
    proto_item *item = NULL;
1153
0
    proto_tree *tree = NULL;
1154
0
    int old_offset = offset;
1155
1156
0
    item = proto_tree_add_item(parent_tree, hf_methodspart_methods, tvb, offset, -1, ENC_NA);
1157
0
    tree = proto_item_add_subtree(item, ett_methodspart_methods);
1158
1159
0
    for(uint32_t methodi = 0; methodi < methodscount; ++methodi){
1160
0
        offset = dissect_wmio_encoding_methodpart_methoddescription(tvb, offset, pinfo, tree, methodsheapoffset);
1161
0
    }
1162
1163
0
    proto_item_set_len(item, offset - old_offset);
1164
0
    return offset;
1165
0
}
1166
1167
/* MethodsPart
1168
 *  https://learn.microsoft.com/de-de/openspecs/windows_protocols/ms-wmio/e00d7c6c-fa1e-4b1d-85c5-5a91a5d71299
1169
 *  MethodsPart = EncodingLength MethodCount MethodCountPadding *MethodDescription MethodHeap
1170
 */
1171
static int
1172
// NOLINTNEXTLINE(misc-no-recursion)
1173
dissect_wmio_encoding_methodpart(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree)
1174
0
{
1175
0
    proto_item *item = NULL;
1176
0
    proto_tree *tree = NULL;
1177
0
    int old_offset = offset;
1178
1179
0
    uint32_t length;
1180
0
    uint32_t methodscount;
1181
1182
0
    item = proto_tree_add_item(parent_tree, hf_methodspart, tvb, offset, -1, ENC_NA);
1183
0
    tree = proto_item_add_subtree(item, ett_methodspart);
1184
1185
0
    proto_tree_add_item_ret_uint(tree, hf_methodspart_length, tvb, offset, 4, ENC_LITTLE_ENDIAN, &length);
1186
0
    offset+= 4;
1187
1188
0
    proto_tree_add_item_ret_uint(tree, hf_methodspart_methodcount, tvb, offset, 2, ENC_LITTLE_ENDIAN, &methodscount);
1189
0
    offset+= 2;
1190
1191
    // MethodCountPadding
1192
0
    offset+= 2;
1193
1194
0
    if(methodscount > 0){
1195
0
        int methodsHeapOffset = offset + (methodscount * 24);
1196
0
        methodsHeapOffset += 4;
1197
0
        offset = dissect_wmio_encoding_methodpart_methods(tvb, offset, pinfo, tree, methodscount, methodsHeapOffset);
1198
0
    }
1199
1200
0
    {
1201
0
        proto_item *heapitem = NULL;
1202
0
        proto_tree *heaptree = NULL;
1203
1204
0
        heapitem = proto_tree_add_item(tree, hf_wmio_heap, tvb, offset, -1, ENC_NA);
1205
0
        heaptree = proto_item_add_subtree(heapitem, ett_wmio_heap);
1206
1207
0
        int32_t heaplength = 0x7FFFFFFF & tvb_get_uint32(tvb, offset, ENC_LITTLE_ENDIAN);
1208
1209
0
        proto_tree_add_uint(heaptree, hf_wmio_heap_length, tvb, offset, 4, heaplength);
1210
1211
0
        proto_item_set_len(heapitem, heaplength);
1212
0
    }
1213
1214
0
    proto_item_set_len(item, length);
1215
1216
0
    return old_offset+length;
1217
0
}
1218
1219
1220
static unsigned
1221
dissect_wmio(tvbuff_t *tvb, unsigned offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di _U_, uint8_t *drep _U_, int size)
1222
0
{
1223
0
    proto_item *sub_item;
1224
0
    proto_tree *sub_tree;
1225
0
    unsigned old_offset = offset;
1226
0
    uint32_t signature;
1227
1228
0
    sub_item = proto_tree_add_item(tree, hf_wmio, tvb, offset, size, ENC_NA);
1229
0
    sub_tree = proto_item_add_subtree(sub_item, ett_wmio);
1230
1231
0
    proto_tree_add_item_ret_uint(sub_tree, hf_wmio_signature, tvb, offset, 4, ENC_LITTLE_ENDIAN, &signature);
1232
0
    offset+= 4;
1233
1234
0
    if (signature != wmio_signature){
1235
0
        return old_offset + size;
1236
0
    }
1237
1238
0
    proto_tree_add_item(sub_tree, hf_wmio_objectencodinglength, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1239
0
    offset+= 4;
1240
1241
0
    dissect_wmio_objectblock(tvb, offset, pinfo, sub_tree);
1242
1243
0
    return old_offset + size;
1244
0
}
1245
1246
void
1247
register_dcom_wmio (void)
1248
0
{
1249
0
    dcom_register_routine(dissect_wmio, &iid_WMIO);
1250
0
}
1251
1252
void
1253
proto_register_WMIO (void)
1254
15
{
1255
15
    proto_WMIO = proto_register_protocol ("WMIO", "WMIO", "WMIO");
1256
15
    proto_register_field_array (proto_WMIO, hf, array_length (hf));
1257
15
    proto_register_subtree_array (ett, array_length (ett));
1258
15
}