1 /* packet-dcom-remunkn.c
2 * Routines for the IRemUnknown interface
3 * Copyright 2004, Jelmer Vernooij <jelmer@samba.org>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
12 /* see packet-dcom.c for details about DCOM */
16 #include <epan/packet.h>
17 #include "packet-dcerpc.h"
18 #include "packet-dcom.h"
20 void proto_register_remunk(void);
21 void proto_reg_handoff_remunk(void);
23 static int hf_remunk_opnum
;
26 static int hf_remunk_refs
;
27 static int hf_remunk_iids
;
29 /* static int hf_remunk_flags; */
30 static int hf_remunk_qiresult
;
32 static int ett_remunk_reminterfaceref
;
33 static int hf_remunk_reminterfaceref
;
34 static int hf_remunk_interface_refs
;
35 static int hf_remunk_public_refs
;
36 static int hf_remunk_private_refs
;
39 static int ett_remunk_rqi_result
;
42 static int ett_remunk
;
43 static e_guid_t uuid_remunk
= { 0x00000131, 0x0000, 0x0000, { 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 } };
44 static uint16_t ver_remunk
;
45 static int proto_remunk
;
47 static e_guid_t ipid_remunk
= { 0x00000131, 0x1234, 0x5678, { 0xCA, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 } };
49 /* There is a little bit confusion about the IRemUnknown2 interface UUIDs */
50 /* DCOM documentation tells us: 0x00000142 (7 methods) */
51 /* win2000 registry tells us: 0x00000142 IRemoteQI (4 methods) */
52 /* win2000 registry tells us: 0x00000143 IRemUnknown2 (7 methods) */
53 /* There is some evidence, that the DCOM documentation is wrong, so using 143 for IRemUnknown2 now. */
55 static int ett_remunk2
;
56 static e_guid_t uuid_remunk2
= { 0x00000143, 0x0000, 0x0000, { 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 } };
57 static uint16_t ver_remunk2
;
58 static int proto_remunk2
;
61 typedef struct remunk_remqueryinterface_call_s
{
64 } remunk_remqueryinterface_call_t
;
68 dissect_remunk_remqueryinterface_rqst(tvbuff_t
*tvb
, int offset
,
69 packet_info
*pinfo
, proto_tree
*tree
, dcerpc_info
*di
, uint8_t *drep
)
74 uint32_t u32ArraySize
;
77 remunk_remqueryinterface_call_t
*call
;
80 offset
= dissect_dcom_this(tvb
, offset
, pinfo
, tree
, di
, drep
);
82 offset
= dissect_dcom_UUID(tvb
, offset
, pinfo
, tree
, di
, drep
,
85 offset
= dissect_dcom_DWORD(tvb
, offset
, pinfo
, tree
, di
, drep
,
86 hf_remunk_refs
, &u32Refs
);
88 offset
= dissect_dcom_WORD(tvb
, offset
, pinfo
, tree
, di
, drep
,
89 hf_remunk_iids
, &u16IIDs
);
91 offset
= dissect_dcom_dcerpc_array_size(tvb
, offset
, pinfo
, tree
, di
, drep
,
94 /* limit the allocation to a reasonable size */
95 if(u32ArraySize
< 100) {
96 call
= (remunk_remqueryinterface_call_t
*)wmem_alloc0(wmem_file_scope(), sizeof(remunk_remqueryinterface_call_t
) + u32ArraySize
* sizeof(e_guid_t
));
97 call
->iid_count
= u32ArraySize
;
98 call
->iids
= (e_guid_t
*) (call
+1);
99 di
->call_data
->private_data
= call
;
104 for (u32ItemIdx
= 0; u32ArraySize
--; u32ItemIdx
++) {
105 offset
= dissect_dcom_append_UUID(tvb
, offset
, pinfo
, tree
, di
, drep
,
106 hf_dcom_iid
, u32ItemIdx
+1, &iid
);
108 call
->iids
[u32ItemIdx
] = iid
;
117 dissect_remunk_remqueryinterface_resp(tvbuff_t
*tvb
, int offset
,
118 packet_info
*pinfo
, proto_tree
*tree
, dcerpc_info
*di
, uint8_t *drep
)
121 uint32_t u32ArraySize
;
123 proto_item
*sub_item
;
124 proto_tree
*sub_tree
;
126 uint32_t u32SubStart
;
128 e_guid_t iid_null
= DCERPC_UUID_NULL
;
129 remunk_remqueryinterface_call_t
*call
= (remunk_remqueryinterface_call_t
*)di
->call_data
->private_data
;
135 offset
= dissect_dcom_that(tvb
, offset
, pinfo
, tree
, di
, drep
);
137 offset
= dissect_dcom_dcerpc_pointer(tvb
, offset
, pinfo
, tree
, di
, drep
,
139 offset
= dissect_dcom_dcerpc_array_size(tvb
, offset
, pinfo
, tree
, di
, drep
,
143 while (u32ArraySize
--) {
145 sub_item
= proto_tree_add_item(tree
, hf_remunk_qiresult
, tvb
, offset
, 0, ENC_NA
);
146 sub_tree
= proto_item_add_subtree(sub_item
, ett_remunk_rqi_result
);
149 offset
= dissect_dcom_HRESULT(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
151 u32SubStart
= offset
- 4;
152 offset
= dissect_dcom_dcerpc_pointer(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
155 /* try to read the iid from the request */
156 if(call
!= NULL
&& u32ItemIdx
<= call
->iid_count
) {
157 iid
= call
->iids
[u32ItemIdx
-1];
162 /* XXX - this doesn't seem to be dependent on the pointer above?!? */
163 /*if (u32Pointer) {*/
164 offset
= dissect_dcom_STDOBJREF(tvb
, offset
, pinfo
, sub_tree
, di
, drep
, 0 /* hfindex */,
168 /* add interface instance to database (we currently only handle IPv4) */
169 if(pinfo
->net_src
.type
== AT_IPv4
) {
170 dcom_interface_new(pinfo
,
172 &iid
, oxid
, oid
, &ipid
);
176 proto_item_append_text(sub_item
, "[%u]: %s",
178 val_to_str(u32HResult
, dcom_hresult_vals
, "Unknown (0x%08x)") );
179 proto_item_set_len(sub_item
, offset
- u32SubStart
);
181 /* update column info now */
182 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " %s[%u]",
183 val_to_str(u32HResult
, dcom_hresult_vals
, "Unknown (0x%08x)"),
188 /* HRESULT of call */
189 offset
= dissect_dcom_HRESULT(tvb
, offset
, pinfo
, tree
, di
, drep
,
192 /* update column info now */
193 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " -> %s",
194 val_to_str(u32HResult
, dcom_hresult_vals
, "Unknown (0x%08x)"));
201 dissect_remunk_remrelease_rqst(tvbuff_t
*tvb
, int offset
,
202 packet_info
*pinfo
, proto_tree
*tree
, dcerpc_info
*di
, uint8_t *drep
)
208 uint32_t u32PublicRefs
;
209 uint32_t u32PrivateRefs
;
210 const char *pszFormat
;
211 proto_item
*sub_item
;
212 proto_tree
*sub_tree
;
213 uint32_t u32SubStart
;
216 offset
= dissect_dcom_this(tvb
, offset
, pinfo
, tree
, di
, drep
);
218 offset
= dissect_dcom_dcerpc_pointer(tvb
, offset
, pinfo
, tree
, di
, drep
,
221 offset
= dissect_dcom_DWORD(tvb
, offset
, pinfo
, tree
, di
, drep
,
222 hf_remunk_interface_refs
, &u32IntRefs
);
224 /* update column info now */
226 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " Cnt=%u Refs=", u32IntRefs
);
228 col_append_str(pinfo
->cinfo
, COL_INFO
, " Cnt=0");
233 while (u32IntRefs
--) {
235 sub_item
= proto_tree_add_item(tree
, hf_remunk_reminterfaceref
, tvb
, offset
, 0, ENC_NA
);
236 sub_tree
= proto_item_add_subtree(sub_item
, ett_remunk_reminterfaceref
);
237 u32SubStart
= offset
;
239 offset
= dissect_dcom_UUID(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
240 hf_dcom_ipid
, &ipid
);
242 offset
= dissect_dcom_DWORD(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
243 hf_remunk_public_refs
, &u32PublicRefs
);
245 offset
= dissect_dcom_DWORD(tvb
, offset
, pinfo
, sub_tree
, di
, drep
,
246 hf_remunk_private_refs
, &u32PrivateRefs
);
249 proto_item_append_text(sub_item
, "[%u]: IPID=%s, PublicRefs=%u, PrivateRefs=%u",
251 guids_resolve_guid_to_str(&ipid
, pinfo
->pool
),
252 u32PublicRefs
, u32PrivateRefs
);
253 proto_item_set_len(sub_item
, offset
- u32SubStart
);
255 /* update column info now */
257 if (u32ItemIdx
== 1) {
259 } else if (u32ItemIdx
< 10) {
260 pszFormat
= ",%u-%u";
261 } else if (u32ItemIdx
== 10) {
264 col_append_fstr(pinfo
->cinfo
, COL_INFO
, pszFormat
, u32PublicRefs
, u32PrivateRefs
);
273 /* sub dissector table of IRemUnknown interface */
274 static const dcerpc_sub_dissector remunk_dissectors
[] = {
275 { 0, "QueryInterface", NULL
, NULL
},
276 { 1, "AddRef", NULL
, NULL
},
277 { 2, "Release", NULL
, NULL
},
279 { 3, "RemQueryInterface", dissect_remunk_remqueryinterface_rqst
, dissect_remunk_remqueryinterface_resp
},
280 { 4, "RemAddRef", NULL
, NULL
},
281 { 5, "RemRelease", dissect_remunk_remrelease_rqst
, dissect_dcom_simple_resp
},
282 { 0, NULL
, NULL
, NULL
}
285 /* sub dissector table of IRemUnknown2 interface */
286 static const dcerpc_sub_dissector remunk2_dissectors
[] = {
287 { 0, "QueryInterface", NULL
, NULL
},
288 { 1, "AddRef", NULL
, NULL
},
289 { 2, "Release", NULL
, NULL
},
291 { 3, "RemQueryInterface", dissect_remunk_remqueryinterface_rqst
, dissect_remunk_remqueryinterface_resp
},
292 { 4, "RemAddRef", NULL
, NULL
},
293 { 5, "RemRelease", dissect_remunk_remrelease_rqst
, dissect_dcom_simple_resp
},
295 { 6, "RemQueryInterface2", NULL
, NULL
},
296 { 0, NULL
, NULL
, NULL
}
302 proto_register_remunk (void)
304 static hf_register_info hf_remunk_rqi_array
[] = {
306 { "Operation", "remunk.opnum", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
309 { "Refs", "remunk.refs", FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
311 { "IIDs", "remunk.iids", FT_UINT16
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
312 { &hf_remunk_qiresult
,
313 { "QIResult", "remunk.qiresult", FT_NONE
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
316 { "Flags", "remunk.flags", FT_UINT32
, BASE_HEX
, NULL
, 0x0, NULL
, HFILL
}},
318 { &hf_remunk_public_refs
,
319 { "PublicRefs", "remunk.public_refs", FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
320 { &hf_remunk_reminterfaceref
,
321 { "RemInterfaceRef", "remunk.reminterfaceref", FT_NONE
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
322 { &hf_remunk_interface_refs
,
323 { "InterfaceRefs", "remunk.int_refs", FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}},
324 { &hf_remunk_private_refs
,
325 { "PrivateRefs", "remunk.private_refs", FT_UINT32
, BASE_DEC
, NULL
, 0x0, NULL
, HFILL
}}
328 static int *ett_remunk_array
[] = {
330 &ett_remunk_rqi_result
,
332 &ett_remunk_reminterfaceref
335 proto_remunk
= proto_register_protocol ("IRemUnknown", "IRemUnknown", "remunk");
336 proto_register_field_array (proto_remunk
, hf_remunk_rqi_array
, array_length (hf_remunk_rqi_array
));
338 proto_remunk2
= proto_register_protocol ("IRemUnknown2", "IRemUnknown2", "remunk2");
340 proto_register_subtree_array (ett_remunk_array
, array_length (ett_remunk_array
));
344 proto_reg_handoff_remunk (void)
347 /* Register the IPID */
348 guids_add_uuid(&ipid_remunk
, "IPID-IRemUnknown");
350 /* Register the interfaces */
351 dcerpc_init_uuid(proto_remunk
, ett_remunk
,
352 &uuid_remunk
, ver_remunk
,
353 remunk_dissectors
, hf_remunk_opnum
);
355 dcerpc_init_uuid(proto_remunk2
, ett_remunk2
,
356 &uuid_remunk2
, ver_remunk2
,
357 remunk2_dissectors
, hf_remunk_opnum
);
361 * Editor modelines - https://www.wireshark.org/tools/modelines.html
366 * indent-tabs-mode: nil
369 * vi: set shiftwidth=4 tabstop=8 expandtab:
370 * :indentSize=4:tabSize=8:noTabs=true: