Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-wmio.c
blob3dea51c91d7c83070e56c6b42a8e523689f39e72
1 /* packet-wmio.c
2 * Wireshark's WMIO dissector.
4 * Copyright 2024, Hiddencodes Sec <hidd3ncod3s[]gmail.com>
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
13 #include "config.h"
15 #include <epan/packet.h>
16 #include "packet-dcerpc.h"
17 #include <packet-dcom.h>
19 void proto_register_WMIO (void);
20 void proto_reg_handoff_WMIO (void);
22 static int proto_WMIO;
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
28 static e_guid_t iid_WMIO = { 0xdc12a681, 0x737f, 0x11cf, { 0x88, 0x4d, 0x00, 0xaa, 0x00, 0x4b, 0x2e, 0x24} };
30 static uint32_t wmio_signature = 0x12345678;
32 #define CLASS_HEADER_LENGTH 13
34 #define WMIO_OBJECT_FLAG_CIM_CLASS 0X01
35 #define WMIO_OBJECT_FLAG_CIM_INSTANCE 0X02
36 #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
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
47 #define CIM_ARRAY_FLAG 0x2000
48 #define INHERITED_PROPERTY_TYPE 0x00004000
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.
54 #define CIM_TYPE_SINT16 2
55 #define CIM_TYPE_SINT32 3
56 #define CIM_TYPE_REAL32 4
57 #define CIM_TYPE_REAL64 5
58 #define CIM_TYPE_STRING 8
59 #define CIM_TYPE_BOOLEAN 11
60 #define CIM_TYPE_OBJECT 13
61 #define CIM_TYPE_SINT8 16
62 #define CIM_TYPE_UINT8 17
63 #define CIM_TYPE_UINT16 18
64 #define CIM_TYPE_UINT32 19
65 #define CIM_TYPE_SINT64 20
66 #define CIM_TYPE_UINT64 21
67 #define CIM_TYPE_DATETIME 101
68 #define CIM_TYPE_REFERENCE 102
69 #define CIM_TYPE_CHAR16 103
71 #define CIM_ARRAY_TYPE(X) (CIM_ARRAY_FLAG | X)
73 #define CIM_ARRAY_SINT8 CIM_ARRAY_TYPE(CIM_TYPE_SINT8)
74 #define CIM_ARRAY_UINT8 CIM_ARRAY_TYPE(CIM_TYPE_UINT8)
75 #define CIM_ARRAY_SINT16 CIM_ARRAY_TYPE(CIM_TYPE_SINT16)
76 #define CIM_ARRAY_UINT16 CIM_ARRAY_TYPE(CIM_TYPE_UINT16)
77 #define CIM_ARRAY_SINT32 CIM_ARRAY_TYPE(CIM_TYPE_SINT32)
78 #define CIM_ARRAY_UINT32 CIM_ARRAY_TYPE(CIM_TYPE_UINT32)
79 #define CIM_ARRAY_SINT64 CIM_ARRAY_TYPE(CIM_TYPE_SINT64)
80 #define CIM_ARRAY_UINT64 CIM_ARRAY_TYPE(CIM_TYPE_UINT64)
81 #define CIM_ARRAY_REAL32 CIM_ARRAY_TYPE(CIM_TYPE_REAL32)
82 #define CIM_ARRAY_REAL64 CIM_ARRAY_TYPE(CIM_TYPE_REAL64)
83 #define CIM_ARRAY_BOOLEAN CIM_ARRAY_TYPE(CIM_TYPE_BOOLEAN)
84 #define CIM_ARRAY_STRING CIM_ARRAY_TYPE(CIM_TYPE_STRING)
85 #define CIM_ARRAY_DATETIME CIM_ARRAY_TYPE(CIM_TYPE_DATETIME)
86 #define CIM_ARRAY_REFERENCE CIM_ARRAY_TYPE(CIM_TYPE_REFERENCE)
87 #define CIM_ARRAY_CHAR16 CIM_ARRAY_TYPE(CIM_TYPE_CHAR16)
88 #define CIM_ARRAY_OBJECT CIM_ARRAY_TYPE(CIM_TYPE_OBJECT)
90 #define STRINGFY(X) { X, #X}
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 } };
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;
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 }},
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
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
348 static int * const wmio_encoded_string_flags[] = {
349 &hf_wmio_encoded_string_flags_unicode,
350 NULL
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;
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,
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);
413 /* DictionaryReference
414 * https://learn.microsoft.com/de-de/openspecs/windows_protocols/ms-wmio/40adf451-f5bc-4b0a-ab97-d620bb638470
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"
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
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)
443 proto_item *sub_item;
444 proto_tree *sub_tree;
445 int old_offset = offset;
446 int fn_len = 0;
447 header_field_info *hfinfo;
448 char *s= NULL;
449 uint32_t foffset = 0;
451 /* Make sure this really is a string field. */
452 hfinfo = proto_registrar_get_nth(hfindex);
453 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_STRINGZ);
455 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.
462 foffset = tvb_get_uint32(tvb, offset, ENC_LITTLE_ENDIAN);
464 if (foffset < 0x80000000){
465 offset = heapoffset + foffset;
469 sub_item = proto_tree_add_item(tree, hf_wmio_encoded_string, tvb, offset, -1, ENC_NA);
470 sub_tree = proto_item_add_subtree(sub_item, ett_wmio_encoded_string);
472 if((heapoffset > 0) && (foffset >= 0x80000000)){
473 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.
477 if(foffset == 0xFFFFFFFF){
478 /* NULL String */
479 proto_item_set_text(sub_tree, "%s: %s", proto_registrar_get_name(hfindex), "NULL");
480 proto_item_set_len(sub_item, 4);
481 } else {
482 if (foffset & 0x80000000){
483 foffset = 0x7FFFFFFF & foffset;
484 if (foffset < array_length(stringDictionary)){
485 proto_item_set_text(sub_tree, "%s: %s", proto_registrar_get_name(hfindex), stringDictionary[foffset]);
486 } else {
487 proto_item_set_text(sub_tree, "%s: Unknown Index %d", proto_registrar_get_name(hfindex), hfindex);
489 proto_item_set_len(sub_item, 4);
492 } else {
493 uint64_t encoded_string_flags;
495 if(heapoffset > 0){
496 proto_tree_add_item(sub_tree, hf_heap_offset, tvb, old_offset, 4, ENC_LITTLE_ENDIAN);
499 old_offset = offset;
501 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 offset++;
504 if (encoded_string_flags == 0){
505 /* ASCII */
506 proto_tree_add_item_ret_length(sub_tree, hfindex, tvb, offset, -1, ENC_ASCII, &fn_len);
507 s = tvb_get_string_enc(pinfo->pool, tvb, offset, fn_len, ENC_ASCII);
508 } else if (encoded_string_flags == 1){
509 /* UNICODE */
510 proto_tree_add_item_ret_length(sub_tree, hfindex, tvb, offset, -1, ENC_UTF_16|ENC_LITTLE_ENDIAN, &fn_len);
511 s = tvb_get_string_enc(pinfo->pool, tvb, offset, fn_len, ENC_UTF_16);
513 offset += fn_len;
515 proto_item_set_text(sub_tree, "%s: %s", proto_registrar_get_name(hfindex), s);
517 if(withlength){
518 proto_tree_add_item(sub_tree, hf_wmio_class_name_length, tvb, offset, 4, ENC_LITTLE_ENDIAN);
519 offset += 4;
521 proto_item_set_len(sub_item, offset-old_offset);
523 return offset;
526 /* ObjectBlock
527 * https://learn.microsoft.com/de-de/openspecs/windows_protocols/ms-wmio/4e74c9f9-4a47-4111-9e67-6476c896b7fb
528 * ObjectBlock = ObjectFlags [Decoration] Encoding
530 static int
531 // NOLINTNEXTLINE(misc-no-recursion)
532 dissect_wmio_objectblock(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
534 int8_t flags = tvb_get_uint8(tvb, offset);
536 proto_tree_add_bitmask(tree, tvb, offset, hf_wmio_object_flags,
537 ett_wmio_object_flags, wmio_object_flags, ENC_NA);
538 offset+=1;
540 increment_dissection_depth(pinfo);
542 if (WMIO_OBJECT_FLAG_HAS_DECORATION & flags){
543 offset = dissect_wmio_object_decoration(tvb, offset, pinfo, tree);
546 if (WMIO_OBJECT_FLAG_CIM_CLASS & flags){
547 offset = dissect_wmio_encoding_classtype(tvb, offset, pinfo, tree);
550 decrement_dissection_depth(pinfo);
552 return offset;
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
559 static int
560 dissect_wmio_object_decoration(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree)
562 proto_item *item = NULL;
563 proto_tree *tree = NULL;
564 int old_offset = offset;
566 item = proto_tree_add_item(parent_tree, hf_wmio_decoration, tvb, offset, -1, ENC_NA);
567 tree = proto_item_add_subtree(item, ett_wmio_decoration);
569 offset = dissect_wmio_encoded_string(tvb, offset, hf_wmio_decoration_server_name, pinfo, tree, false, 0);
570 offset = dissect_wmio_encoded_string(tvb, offset, hf_wmio_decoration_namespace, pinfo, tree, false, 0);
572 proto_item_set_len(item, offset-old_offset);
574 return offset;
577 static int
578 // NOLINTNEXTLINE(misc-no-recursion)
579 dissect_wmio_encoding_classtype(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree)
581 increment_dissection_depth(pinfo);
583 // ParentClass
584 offset = dissect_wmio_encoding_classandmethodspart(tvb, offset, pinfo, tree, hf_parentclass, ett_parentclass, true);
586 // CurrentClass
587 offset = dissect_wmio_encoding_classandmethodspart(tvb, offset, pinfo, tree, hf_currentclass, ett_currentclass, true);
589 decrement_dissection_depth(pinfo);
591 return offset;
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]
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)
602 proto_item *item = NULL;
603 proto_tree *tree = NULL;
604 int old_offset = offset;
606 item = proto_tree_add_item(parent_tree, hf_index, tvb, offset, -1, ENC_NA);
607 tree = proto_item_add_subtree(item, ett_id);
609 offset = dissect_wmio_encoding_classpart(tvb, offset, pinfo, tree);
610 if (methods){
611 offset = dissect_wmio_encoding_methodpart(tvb, offset, pinfo, tree);
614 proto_item_set_len(item, offset-old_offset);
615 return offset;
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
622 static int
623 dissect_wmio_qualifier(tvbuff_t *tvb, int offset, packet_info *pinfo,
624 proto_tree *parent_tree, int classheapoffset)
626 proto_item *item = NULL;
627 proto_tree *tree = NULL;
628 int old_offset = offset;
630 item = proto_tree_add_item(parent_tree, hf_wmio_qualifier, tvb, offset, -1, ENC_NA);
631 tree = proto_item_add_subtree(item, ett_wmio_qualifier);
633 dissect_wmio_encoded_string(tvb, offset, hf_wmio_qualifiername, pinfo, tree, false, classheapoffset);
634 offset+= 4;
636 proto_tree_add_bitmask(tree, tvb, offset, hf_wmio_flavor, ett_wmio_flavor, wmio_flavor, ENC_NA);
637 offset+= 1;
639 // QualifierType = CimType
640 // CimType is a 32-bit value
641 int32_t cimType = tvb_get_uint32(tvb, offset, ENC_LITTLE_ENDIAN);
642 proto_tree_add_item(tree, hf_wmio_cimtype, tvb, offset, 4, ENC_LITTLE_ENDIAN);
643 offset+= 4;
645 // QualifierValue = EncodedValue
646 if (cimType & CIM_ARRAY_FLAG){
647 uint32_t array_count = tvb_get_uint32(tvb, offset, ENC_LITTLE_ENDIAN);
648 offset += 4;
650 // CimArrayType
651 switch(cimType){
652 case CIM_ARRAY_SINT8:
653 offset += array_count;
654 break;
655 case CIM_ARRAY_UINT8:
656 offset += array_count;
657 break;
658 case CIM_ARRAY_SINT16:
659 offset += (sizeof(int16_t) * array_count);
660 break;
661 case CIM_ARRAY_UINT16:
662 offset += (sizeof(uint16_t) * array_count);
663 break;
664 case CIM_ARRAY_SINT32:
665 offset += (sizeof(int32_t) * array_count);
666 break;
667 case CIM_ARRAY_UINT32:
668 offset += (sizeof(uint32_t) * array_count);
669 break;
670 case CIM_ARRAY_SINT64:
671 offset += (sizeof(int64_t) * array_count);
672 break;
673 case CIM_ARRAY_UINT64:
674 offset += (sizeof(uint64_t) * array_count);
675 break;
676 case CIM_ARRAY_REAL32:
677 offset += (sizeof(int32_t) * array_count);
678 break;
679 case CIM_ARRAY_REAL64:
680 offset += (sizeof(int64_t) * array_count);
681 break;
682 case CIM_ARRAY_BOOLEAN:
683 offset += (2 * array_count);
684 break;
685 case CIM_ARRAY_STRING:
686 case CIM_ARRAY_DATETIME:
687 case CIM_ARRAY_REFERENCE:
688 // TODO
689 break;
690 case CIM_ARRAY_CHAR16:
691 offset += (sizeof(int16_t) * array_count);
692 break;
693 case CIM_ARRAY_OBJECT:
695 for (uint32_t i=0; i < array_count; i++){
696 int32_t objEncLength = tvb_get_uint32(tvb, offset, ENC_LITTLE_ENDIAN);
697 offset += objEncLength;
699 break;
701 default:
702 break;
704 } else {
705 // CimBaseType
706 switch(cimType){
707 case CIM_TYPE_SINT8:
709 proto_item *vitem = proto_tree_add_item(tree, hf_wmio_qualifiervalue, tvb, offset, -1, ENC_ASCII);
710 proto_item_set_text(vitem, "%s: %d", proto_registrar_get_name(hf_wmio_qualifiervalue), tvb_get_int8(tvb, offset));
711 proto_item_set_len(vitem, 1);
712 offset+= 1;
714 break;
715 case CIM_TYPE_UINT8:
717 proto_item *vitem = proto_tree_add_item(tree, hf_wmio_qualifiervalue, tvb, offset, -1, ENC_ASCII);
718 proto_item_set_text(vitem, "%s: %u", proto_registrar_get_name(hf_wmio_qualifiervalue), tvb_get_int8(tvb, offset));
719 proto_item_set_len(vitem, 1);
720 offset+= 1;
722 break;
723 case CIM_TYPE_SINT16:
724 case CIM_TYPE_CHAR16:
726 proto_item *vitem = proto_tree_add_item(tree, hf_wmio_qualifiervalue, tvb, offset, -1, ENC_ASCII);
727 proto_item_set_text(vitem, "%s: %d", proto_registrar_get_name(hf_wmio_qualifiervalue), tvb_get_int16(tvb, offset, ENC_LITTLE_ENDIAN));
728 proto_item_set_len(vitem, 2);
729 offset+= 2;
731 break;
732 case CIM_TYPE_UINT16:
734 proto_item *vitem = proto_tree_add_item(tree, hf_wmio_qualifiervalue, tvb, offset, -1, ENC_ASCII);
735 proto_item_set_text(tree, "%s: %u", proto_registrar_get_name(hf_wmio_qualifiervalue), tvb_get_uint16(tvb, offset, ENC_LITTLE_ENDIAN));
736 proto_item_set_len(vitem, 2);
737 offset+= 2;
739 break;
740 case CIM_TYPE_SINT32:
742 proto_item *vitem = proto_tree_add_item(tree, hf_wmio_qualifiervalue, tvb, offset, -1, ENC_ASCII);
743 proto_item_set_text(vitem, "%s: %d", proto_registrar_get_name(hf_wmio_qualifiervalue), tvb_get_int32(tvb, offset, ENC_LITTLE_ENDIAN));
744 proto_item_set_len(vitem, 4);
745 offset+= 4;
747 break;
748 case CIM_TYPE_UINT32:
750 proto_item *vitem = proto_tree_add_item(tree, hf_wmio_qualifiervalue, tvb, offset, -1, ENC_ASCII);
751 proto_item_set_text(vitem, "%s: %u", proto_registrar_get_name(hf_wmio_qualifiervalue), tvb_get_uint32(tvb, offset, ENC_LITTLE_ENDIAN));
752 proto_item_set_len(vitem, 4);
753 offset+= 4;
755 break;
756 case CIM_TYPE_SINT64:
758 proto_item *vitem = proto_tree_add_item(tree, hf_wmio_qualifiervalue, tvb, offset, -1, ENC_ASCII);
759 proto_item_set_text(vitem, "%s: %" PRIi64, proto_registrar_get_name(hf_wmio_qualifiervalue), tvb_get_int64(tvb, offset, ENC_LITTLE_ENDIAN));
760 proto_item_set_len(vitem, 8);
761 offset+= 8;
763 break;
764 case CIM_TYPE_UINT64:
766 proto_item *vitem = proto_tree_add_item(tree, hf_wmio_qualifiervalue, tvb, offset, -1, ENC_ASCII);
767 proto_item_set_text(vitem, "%s: %" PRIu64, proto_registrar_get_name(hf_wmio_qualifiervalue), tvb_get_uint64(tvb, offset, ENC_LITTLE_ENDIAN));
768 proto_item_set_len(vitem, 8);
769 offset+= 8;
771 break;
772 case CIM_TYPE_REAL32:
774 proto_item *vitem = proto_tree_add_item(tree, hf_wmio_qualifiervalue, tvb, offset, -1, ENC_ASCII);
775 proto_item_set_text(vitem, "%s: %f", proto_registrar_get_name(hf_wmio_qualifiervalue), tvb_get_ieee_float(tvb, offset, ENC_LITTLE_ENDIAN));
776 proto_item_set_len(vitem, 4);
777 offset+= 4;
779 break;
780 case CIM_TYPE_REAL64:
782 proto_item *vitem = proto_tree_add_item(tree, hf_wmio_qualifiervalue, tvb, offset, -1, ENC_ASCII);
783 proto_item_set_text(vitem, "%s: %lf", proto_registrar_get_name(hf_wmio_qualifiervalue), tvb_get_ieee_double(tvb, offset, ENC_LITTLE_ENDIAN));
784 proto_item_set_len(vitem, 8);
785 offset+= 8;
787 break;
788 case CIM_TYPE_BOOLEAN:
790 proto_item *vitem = proto_tree_add_item(tree, hf_wmio_qualifiervalue, tvb, offset, -1, ENC_ASCII);
791 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 proto_item_set_len(vitem, 2);
793 offset+= 2;
795 break;
796 case CIM_TYPE_STRING:
797 case CIM_TYPE_DATETIME:
798 case CIM_TYPE_REFERENCE:
799 dissect_wmio_encoded_string(tvb, offset, hf_wmio_qualifiervalue, pinfo, tree, false, classheapoffset);
800 offset+= 4;
801 break;
802 case CIM_TYPE_OBJECT:
804 int32_t objEncLength = tvb_get_uint32(tvb, offset, ENC_LITTLE_ENDIAN);
805 offset += objEncLength;
807 break;
808 default:
809 break;
813 proto_item_set_len(item, offset - old_offset);
815 return offset;
818 /* QualifierSet
819 * https://learn.microsoft.com/de-de/openspecs/windows_protocols/ms-wmio/224c7463-01df-4e09-bd71-650ec0b8adaf
820 * QualifierSet = EncodingLength *Qualifier
822 static int
823 dissect_wmio_encoding_qualifierset(tvbuff_t *tvb, int offset, packet_info *pinfo,
824 proto_tree *parent_tree, int classheapoffset)
826 proto_item *item = NULL;
827 proto_tree *tree = NULL;
828 int old_offset = offset;
829 uint32_t length;
831 item = proto_tree_add_item(parent_tree, hf_wmio_qualifierset, tvb, offset, -1, ENC_NA);
832 tree = proto_item_add_subtree(item, ett_wmio_qualifierset);
834 proto_tree_add_item_ret_uint(tree, hf_wmio_qualifierset_length, tvb, offset, 4, ENC_LITTLE_ENDIAN, &length);
835 offset += 4;
837 while((uint32_t)offset < (old_offset + length)){
838 /* N.B. guaranteed to advance offset */
839 offset = dissect_wmio_qualifier(tvb, offset, pinfo, tree, classheapoffset);
842 proto_item_set_len(item, offset - old_offset);
844 return old_offset+length;
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
851 static void
852 dissect_wmio_encoding_propertyinfo(tvbuff_t *tvb, int offset, packet_info *pinfo,
853 proto_tree *parent_tree, int classheapoffset)
855 proto_item *item = NULL;
856 proto_tree *tree = NULL;
857 uint32_t propertyinfo_offset;
858 int old_offset = 0;
860 item = proto_tree_add_item(parent_tree, hf_property_info, tvb, offset, -1, ENC_NA);
861 tree = proto_item_add_subtree(item, ett_property_info);
863 proto_tree_add_item_ret_uint(tree, hf_wmio_propertyinforef, tvb, offset, 4, ENC_LITTLE_ENDIAN, &propertyinfo_offset);
865 offset = classheapoffset + propertyinfo_offset;
866 old_offset = offset;
868 int32_t propType = tvb_get_uint32(tvb, offset, ENC_LITTLE_ENDIAN);
869 proto_tree_add_uint(tree, hf_wmio_cimtype, tvb, offset, 4, propType & 0x3FFF);
870 proto_tree_add_boolean(tree, hf_propertyinfo_inherited, tvb, offset, 4, propType);
871 offset += 4;
873 proto_tree_add_item(tree, hf_declaration_order, tvb, offset, 2, ENC_LITTLE_ENDIAN);
874 offset += 2;
876 proto_tree_add_item(tree, hf_propertyinfo_valuetableoffset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
877 offset += 4;
879 proto_tree_add_item(tree, hf_propertyinfo_classoforigin, tvb, offset, 4, ENC_LITTLE_ENDIAN);
880 offset += 4;
882 offset = dissect_wmio_encoding_qualifierset(tvb, offset, pinfo, tree, classheapoffset);
884 proto_item_set_len(item, offset - old_offset);
887 /* PropertyLookup
888 * https://learn.microsoft.com/de-de/openspecs/windows_protocols/ms-wmio/e401de4a-58fa-423b-89e0-4b832a99d0e9
889 * PropertyLookup = PropertyNameRef PropertyInfoRef
891 static int
892 dissect_wmio_encoding_propertylookup(tvbuff_t *tvb, int offset, packet_info *pinfo,
893 proto_tree *parent_tree, int classheapoffset)
895 proto_item *item = NULL;
896 proto_tree *tree = NULL;
897 int old_offset = offset;
899 item = proto_tree_add_item(parent_tree, hf_wmio_propertylookup, tvb, offset, -1, ENC_NA);
900 tree = proto_item_add_subtree(item, ett_wmio_propertylookup);
902 dissect_wmio_encoded_string(tvb, offset, hf_wmio_propertynameref, pinfo, tree, false, classheapoffset);
903 offset += 4;
906 dissect_wmio_encoding_propertyinfo(tvb, offset, pinfo, tree, classheapoffset);
907 offset += 4;
909 proto_item_set_len(item, offset - old_offset);
911 return offset;
914 /* PropertyLookupTable
915 * https://learn.microsoft.com/de-de/openspecs/windows_protocols/ms-wmio/d4927ca8-b358-48eb-8879-a57ea4f090c3
916 * PropertyLookupTable = PropertyCount *PropertyLookup
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)
922 proto_item *item = NULL;
923 proto_tree *tree = NULL;
924 int old_offset = offset;
925 uint32_t count;
927 item = proto_tree_add_item(parent_tree, hf_wmio_propertylookuptable, tvb, offset, -1, ENC_NA);
928 tree = proto_item_add_subtree(item, ett_wmio_propertylookuptable);
930 // PropertyCount
931 proto_tree_add_item_ret_uint(tree, hf_wmio_propertylookuptable_count, tvb, offset, 4, ENC_LITTLE_ENDIAN, &count);
932 offset += 4;
934 for(uint32_t i = 0; i < count; ++i){
935 offset = dissect_wmio_encoding_propertylookup(tvb, offset, pinfo, tree, classheapoffset);
938 *property_count = count;
940 proto_item_set_len(item, offset - old_offset);
942 return offset;
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
949 static int
950 dissect_wmio_encoding_classpart(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *parent_tree)
952 proto_item *item = NULL;
953 proto_tree *tree = NULL;
954 int old_offset = offset;
955 int classheapoffset = 0;
957 uint32_t partlength, ndLength;
958 uint32_t property_count;
960 item = proto_tree_add_item(parent_tree, hf_wmio_class_part, tvb, offset, -1, ENC_NA);
961 tree = proto_item_add_subtree(item, ett_wmio_class_part);
964 /* Jump through the various structures to find the heap offset. */
965 uint32_t derivationListLength = tvb_get_uint32(tvb, offset + CLASS_HEADER_LENGTH, ENC_LITTLE_ENDIAN);
966 uint32_t classQualifierSetLength = tvb_get_uint32(tvb, offset + CLASS_HEADER_LENGTH + derivationListLength, ENC_LITTLE_ENDIAN);
967 uint32_t propertyLookupTableLength = 4 + 8 * tvb_get_uint32(tvb, offset + CLASS_HEADER_LENGTH + derivationListLength + classQualifierSetLength, ENC_LITTLE_ENDIAN);
968 uint32_t ndTableLength = tvb_get_uint32(tvb, offset + (CLASS_HEADER_LENGTH - 4), ENC_LITTLE_ENDIAN);
970 classheapoffset = offset /* Starting offset */
971 + CLASS_HEADER_LENGTH /* ClassHeader */
972 + derivationListLength /* DerivationList */
973 + classQualifierSetLength /* ClassQualifierSet */
974 + propertyLookupTableLength /* PropertyLookupTable */
975 + ndTableLength; /* NdTable */
978 offset = dissect_wmio_encoding_classheader(tvb, offset, pinfo, tree, &partlength, &ndLength, classheapoffset+4);
979 offset = dissect_wmio_encoding_derivationlist(tvb, offset, pinfo, tree);
980 offset = dissect_wmio_encoding_qualifierset(tvb, offset, pinfo, tree,classheapoffset+4);
981 offset = dissect_wmio_encoding_propertylookuptable(tvb, offset, pinfo, tree, &property_count, classheapoffset+4);
983 if(ndLength > 0){
984 proto_tree_add_item(tree, hf_wmio_ndtable, tvb, offset, ndLength, ENC_NA);
985 offset += ndLength;
989 proto_item *heapitem = NULL;
990 proto_tree *heaptree = NULL;
992 heapitem = proto_tree_add_item(tree, hf_wmio_heap, tvb, offset, -1, ENC_NA);
993 heaptree = proto_item_add_subtree(heapitem, ett_wmio_heap);
995 int32_t heaplength = 0x7FFFFFFF & tvb_get_uint32(tvb, offset, ENC_LITTLE_ENDIAN);
997 proto_tree_add_uint(heaptree, hf_wmio_heap_length, tvb, offset, 4, heaplength);
999 proto_item_set_len(heapitem, heaplength);
1002 proto_item_set_len(item, partlength);
1004 return old_offset + partlength;
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
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)
1015 proto_item *item = NULL;
1016 proto_tree *tree = NULL;
1017 int old_offset = offset;
1019 uint32_t partlength, length;
1021 item = proto_tree_add_item(parent_tree, hf_wmio_class_header, tvb, offset, -1, ENC_NA);
1022 tree = proto_item_add_subtree(item, ett_wmio_class_header);
1024 proto_tree_add_item_ret_uint(tree, hf_wmio_class_header_partlength, tvb, offset, 4, ENC_LITTLE_ENDIAN, &partlength);
1025 offset+= 4;
1026 *pPartlength = partlength;
1028 // ReservedOctet
1029 offset+= 1;
1031 dissect_wmio_encoded_string(tvb, offset, hf_wmio_class_header_nameref, pinfo, tree, false, classheapoffset);
1032 offset+= 4;
1034 proto_tree_add_item_ret_uint(tree, hf_wmio_class_header_ndtablevaluetablelength, tvb, offset, 4, ENC_LITTLE_ENDIAN, &length);
1035 offset+= 4;
1036 *pNdLength = length;
1038 proto_item_set_len(item, offset-old_offset);
1040 return offset;
1043 /* DerivationList
1044 * https://learn.microsoft.com/de-de/openspecs/windows_protocols/ms-wmio/3bfbcac6-318c-4b0a-ab87-13bfbc86f36f
1045 * DerivationList = EncodingLength *ClassNameEncoding
1047 static int
1048 dissect_wmio_encoding_derivationlist(tvbuff_t *tvb, int offset, packet_info *pinfo,
1049 proto_tree *parent_tree)
1051 proto_item *item = NULL;
1052 proto_tree *tree = NULL;
1053 int old_offset = offset;
1055 uint32_t length;
1057 item = proto_tree_add_item(parent_tree, hf_wmio_class_derivation, tvb, offset, -1, ENC_NA);
1058 tree = proto_item_add_subtree(item, ett_wmio_class_derivation);
1060 proto_tree_add_item_ret_uint(tree, hf_wmio_class_derivation_length, tvb, offset, 4, ENC_LITTLE_ENDIAN, &length);
1061 offset+= 4;
1063 while((uint32_t)offset < (old_offset + length)) {
1064 /* Offset is guaranteed to increase here as heapoffset (last arg) is 0 */
1065 offset = dissect_wmio_encoded_string(tvb, offset, hf_wmio_derivation_classname, pinfo, tree, true, 0);
1068 proto_item_set_len(item, length);
1070 return offset;
1073 /* MethodSignature
1074 * https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-wmio/a9d7c0d1-f99a-4762-b460-e881a8c7d566
1075 * MethodSignature = HeapMethodSignatureBlockRef
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)
1082 proto_item *item = NULL;
1083 proto_tree *tree = NULL;
1084 int old_offset = 0;
1086 int32_t signatureHeapOffset = tvb_get_uint32(tvb, offset, ENC_LITTLE_ENDIAN);
1088 old_offset = methodsheapoffset + signatureHeapOffset;
1090 item = proto_tree_add_item(parent_tree, hfindex, tvb, old_offset, -1, ENC_NA);
1091 tree = proto_item_add_subtree(item, ett_methodsignature);
1093 proto_tree_add_item(tree, hf_methodsignature_offset, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1095 offset = old_offset;
1097 proto_tree_add_item(tree, hf_wmio_objectencodinglength, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1098 offset+= 4;
1100 offset = dissect_wmio_objectblock(tvb, offset, pinfo, tree);
1102 proto_item_set_len(item, offset - old_offset);
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
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)
1114 proto_item *item = NULL;
1115 proto_tree *tree = NULL;
1116 int old_offset = offset;
1118 item = proto_tree_add_item(parent_tree, hf_methodspart_methoddescription, tvb, offset, -1, ENC_NA);
1119 tree = proto_item_add_subtree(item, ett_methodspart_methoddescription);
1121 dissect_wmio_encoded_string(tvb, offset, hf_methoddescription_methodname, pinfo, tree, false, methodsheapoffset);
1122 offset+= 4;
1124 proto_tree_add_item(tree, hf_methoddescription_methodflags, tvb, offset, 1, ENC_LITTLE_ENDIAN);
1125 offset+= 1;
1127 // MethodPadding
1128 offset+= 3;
1130 proto_tree_add_item(tree, hf_methoddescription_methodorigin, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1131 offset+= 4;
1133 proto_tree_add_item(tree, hf_methoddescription_methodqualifiers, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1134 offset+= 4;
1136 dissect_wmio_encoding_methodsignature(tvb, offset, pinfo, tree, hf_methoddescription_inputsignature, methodsheapoffset);
1137 offset+= 4;
1139 dissect_wmio_encoding_methodsignature(tvb, offset, pinfo, tree, hf_methoddescription_outputsignature, methodsheapoffset);
1140 offset+= 4;
1142 proto_item_set_len(item, offset - old_offset);
1144 return offset;
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)
1152 proto_item *item = NULL;
1153 proto_tree *tree = NULL;
1154 int old_offset = offset;
1156 item = proto_tree_add_item(parent_tree, hf_methodspart_methods, tvb, offset, -1, ENC_NA);
1157 tree = proto_item_add_subtree(item, ett_methodspart_methods);
1159 for(uint32_t methodi = 0; methodi < methodscount; ++methodi){
1160 offset = dissect_wmio_encoding_methodpart_methoddescription(tvb, offset, pinfo, tree, methodsheapoffset);
1163 proto_item_set_len(item, offset - old_offset);
1164 return offset;
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
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)
1175 proto_item *item = NULL;
1176 proto_tree *tree = NULL;
1177 int old_offset = offset;
1179 uint32_t length;
1180 uint32_t methodscount;
1182 item = proto_tree_add_item(parent_tree, hf_methodspart, tvb, offset, -1, ENC_NA);
1183 tree = proto_item_add_subtree(item, ett_methodspart);
1185 proto_tree_add_item_ret_uint(tree, hf_methodspart_length, tvb, offset, 4, ENC_LITTLE_ENDIAN, &length);
1186 offset+= 4;
1188 proto_tree_add_item_ret_uint(tree, hf_methodspart_methodcount, tvb, offset, 2, ENC_LITTLE_ENDIAN, &methodscount);
1189 offset+= 2;
1191 // MethodCountPadding
1192 offset+= 2;
1194 if(methodscount > 0){
1195 int methodsHeapOffset = offset + (methodscount * 24);
1196 methodsHeapOffset += 4;
1197 offset = dissect_wmio_encoding_methodpart_methods(tvb, offset, pinfo, tree, methodscount, methodsHeapOffset);
1201 proto_item *heapitem = NULL;
1202 proto_tree *heaptree = NULL;
1204 heapitem = proto_tree_add_item(tree, hf_wmio_heap, tvb, offset, -1, ENC_NA);
1205 heaptree = proto_item_add_subtree(heapitem, ett_wmio_heap);
1207 int32_t heaplength = 0x7FFFFFFF & tvb_get_uint32(tvb, offset, ENC_LITTLE_ENDIAN);
1209 proto_tree_add_uint(heaptree, hf_wmio_heap_length, tvb, offset, 4, heaplength);
1211 proto_item_set_len(heapitem, heaplength);
1214 proto_item_set_len(item, length);
1216 return old_offset+length;
1220 static int
1221 dissect_wmio(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di _U_, uint8_t *drep _U_, int size)
1223 proto_item *sub_item;
1224 proto_tree *sub_tree;
1225 int old_offset = offset;
1226 uint32_t signature;
1228 sub_item = proto_tree_add_item(tree, hf_wmio, tvb, offset, size, ENC_NA);
1229 sub_tree = proto_item_add_subtree(sub_item, ett_wmio);
1231 proto_tree_add_item_ret_uint(sub_tree, hf_wmio_signature, tvb, offset, 4, ENC_LITTLE_ENDIAN, &signature);
1232 offset+= 4;
1234 if (signature != wmio_signature){
1235 return old_offset + size;
1238 proto_tree_add_item(sub_tree, hf_wmio_objectencodinglength, tvb, offset, 4, ENC_LITTLE_ENDIAN);
1239 offset+= 4;
1241 dissect_wmio_objectblock(tvb, offset, pinfo, sub_tree);
1243 return old_offset + size;
1246 void
1247 register_dcom_wmio (void)
1249 dcom_register_routine(dissect_wmio, &iid_WMIO);
1252 void
1253 proto_register_WMIO (void)
1255 proto_WMIO = proto_register_protocol ("WMIO", "WMIO", "WMIO");
1256 proto_register_field_array (proto_WMIO, hf, array_length (hf));
1257 proto_register_subtree_array (ett, array_length (ett));