1 /* packet-dcom-typeinfo.c
2  * Routines for DCOM ITypeInfo
3  * Copyright 2019, Alex Sirr <alexsirruw@gmail.com>
4  *
5  * Wireshark - Network traffic analyzer
6  * By Gerald Combs <gerald@wireshark.org>
7  * Copyright 1998 Gerald Combs
8  *
9  * SPDX-License-Identifier: GPL-2.0-or-later
10  */
11 
12 /* see packet-dcom.c for details about DCOM */
13 
14 #include "config.h"
15 
16 #include <epan/packet.h>
17 #include "packet-dcerpc.h"
18 #include "packet-dcom.h"
19 
20 #include "packet-dcerpc-nt.h"
21 
22 void proto_register_dcom_typeinfo(void);
23 void proto_reg_handoff_dcom_typeinfo(void);
24 
25 static gint ett_typeinfo_funcdesc = -1;
26 static int hf_typeinfo_funcdesc = -1;
27 static int hf_typeinfo_funcdesc_funcflags = -1;
28 static gint ett_typeinfo_funcdesc_funcflags = -1;
29 static int hf_typeinfo_funcdesc_funcflags_frestricted = -1;
30 static int hf_typeinfo_funcdesc_funcflags_fsource = -1;
31 static int hf_typeinfo_funcdesc_funcflags_fbindable = -1;
32 static int hf_typeinfo_funcdesc_funcflags_frequestedit = -1;
33 static int hf_typeinfo_funcdesc_funcflags_fdisplaybind = -1;
34 static int hf_typeinfo_funcdesc_funcflags_fdefaultbind = -1;
35 static int hf_typeinfo_funcdesc_funcflags_fhidden = -1;
36 static int hf_typeinfo_funcdesc_funcflags_fusesgetlasterror = -1;
37 static int hf_typeinfo_funcdesc_funcflags_fdefaultcollelem = -1;
38 static int hf_typeinfo_funcdesc_funcflags_fuidefault = -1;
39 static int hf_typeinfo_funcdesc_funcflags_fnowbrowsable = -1;
40 static int hf_typeinfo_funcdesc_funcflags_freplaceable = -1;
41 static int hf_typeinfo_funcdesc_funcflags_fimmediatebind = -1;
42 
43 #define FUNCFLAG_FRESTRICTED 0x1
44 #define FUNCFLAG_FSOURCE 0x2
45 #define FUNCFLAG_FBINDABLE 0x4
46 #define FUNCFLAG_FREQUESTEDIT 0x8
47 #define FUNCFLAG_FDISPLAYBIND 0x10
48 #define FUNCFLAG_FDEFAULTBIND 0x20
49 #define FUNCFLAG_FHIDDEN 0x40
50 #define FUNCFLAG_FUSESGETLASTERROR 0x80
51 #define FUNCFLAG_FDEFAULTCOLLELEM 0x100
52 #define FUNCFLAG_FUIDEFAULT 0x200
53 #define FUNCFLAG_FNONBROWSABLE 0x400
54 #define FUNCFLAG_FREPLACEABLE 0x800
55 #define FUNCFLAG_FIMMEDIATEBIND 0x1000
56 
57 static int hf_typeinfo_funcdesc_funckind = -1;
58 static int hf_typeinfo_funcdesc_invkind = -1;
59 static int hf_typeinfo_funcdesc_callconv = -1;
60 static int hf_typeinfo_funcdesc_params = -1;
61 static int hf_typeinfo_funcdesc_paramsopt = -1;
62 static int hf_typeinfo_funcdesc_memid = -1;
63 static int hf_typeinfo_funcdesc_vft = -1;
64 static int hf_typeinfo_funcdesc_resv16 = -1;
65 static int hf_typeinfo_funcdesc_resv32 = -1;
66 static gint ett_typeinfo_elemdesc = -1;
67 static int hf_typeinfo_funcdesc_elemdesc = -1;
68 
69 static gint ett_typeinfo_typedesc = -1;
70 static int hf_typeinfo_typedesc = -1;
71 
72 static gint ett_typeinfo_paramdesc = -1;
73 static int hf_typeinfo_paramdesc = -1;
74 static gint ett_typeinfo_paramdesc_paramflags = -1;
75 static int hf_typeinfo_paramdesc_paramflags = -1;
76 static int hf_typeinfo_paramdesc_paramflags_fin = -1;
77 static int hf_typeinfo_paramdesc_paramflags_fout = -1;
78 static int hf_typeinfo_paramdesc_paramflags_flcid = -1;
79 static int hf_typeinfo_paramdesc_paramflags_fretval = -1;
80 static int hf_typeinfo_paramdesc_paramflags_fopt = -1;
81 static int hf_typeinfo_paramdesc_paramflags_fhasdefault = -1;
82 static int hf_typeinfo_paramdesc_paramflags_fhascustdata = -1;
83 
84 #define PARAMFLAG_FIN 0x1
85 #define PARAMFLAG_FOUT 0x2
86 #define PARAMFLAG_FLCID 0x4
87 #define PARAMFLAG_FRETVAL 0x8
88 #define PARAMFLAG_FOPT 0x10
89 #define PARAMFLAG_FHASDEFAULT 0x20
90 #define PARAMFLAG_FHASCUSTDATA 0x40
91 
92 static gint ett_typeinfo_paramdescex = -1;
93 static int hf_typeinfo_paramdescex = -1;
94 static int hf_typeinfo_paramdescex_cbytes = -1;
95 static int hf_typeinfo_paramdescex_varDefaultValue = -1;
96 
97 static int hf_typeinfo_typedesc_vtret = -1;
98 static int hf_typeinfo_typedesc_hreftype = -1;
99 
100 static int hf_typeinfo_opnum = -1;
101 static int hf_typeinfo_index = -1;
102 
103 static int hf_typeinfo_memid = -1;
104 static int hf_typeinfo_reserved32 = -1;
105 static int hf_typeinfo_reserved16 = -1;
106 
107 static int hf_typeinfo_names = -1;
108 static int hf_typeinfo_names_value = -1;
109 static int hf_typeinfo_maxnames = -1;
110 
111 static int hf_typeinfo_docname = -1;
112 static int hf_typeinfo_docstring = -1;
113 static int hf_typeinfo_helpctx = -1;
114 static int hf_typeinfo_helpfile = -1;
115 
116 static gint ett_typeinfo_docflags = -1;
117 static int hf_typeinfo_docflags = -1;
118 static int hf_typeinfo_docflags_name = -1;
119 static int hf_typeinfo_docflags_docstring = -1;
120 static int hf_typeinfo_docflags_helpctx = -1;
121 static int hf_typeinfo_docflags_helpfile = -1;
122 
123 #define TYPEINFO_DOCFLAGS_NameArg 1
124 #define TYPEINFO_DOCFLAGS_DocStringArg 2
125 #define TYPEINFO_DOCFLAGS_HelpContextArg 4
126 #define TYPEINFO_DOCFLAGS_HelpFileArg 8
127 
128 static gint ett_typeinfo_typeflags = -1;
129 static int hf_typeinfo_typeflags = -1;
130 static int hf_typeinfo_typeflags_fappobject = -1;
131 static int hf_typeinfo_typeflags_fcancreate = -1;
132 static int hf_typeinfo_typeflags_flicensed = -1;
133 static int hf_typeinfo_typeflags_fpredeclid = -1;
134 static int hf_typeinfo_typeflags_fhidden = -1;
135 static int hf_typeinfo_typeflags_fcontrol = -1;
136 static int hf_typeinfo_typeflags_fdual = -1;
137 static int hf_typeinfo_typeflags_fnonextensible = -1;
138 static int hf_typeinfo_typeflags_foleautomation = -1;
139 static int hf_typeinfo_typeflags_frestricted = -1;
140 static int hf_typeinfo_typeflags_faggregatable = -1;
141 static int hf_typeinfo_typeflags_freplaceable = -1;
142 static int hf_typeinfo_typeflags_fdispatchable = -1;
143 static int hf_typeinfo_typeflags_fproxy = -1;
144 
145 #define TYPEINFO_TYPEFLAG_FAPPOBJECT 0x1
146 #define TYPEINFO_TYPEFLAG_FCANCREATE 0x2
147 #define TYPEINFO_TYPEFLAG_FLICENSED 0x4
148 #define TYPEINFO_TYPEFLAG_FPREDECLID 0x8
149 #define TYPEINFO_TYPEFLAG_FHIDDEN 0x10
150 #define TYPEINFO_TYPEFLAG_FCONTROL 0x20
151 #define TYPEINFO_TYPEFLAG_FDUAL 0x40
152 #define TYPEINFO_TYPEFLAG_FNONEXTENSIBLE 0x80
153 #define TYPEINFO_TYPEFLAG_FOLEAUTOMATION 0x100
154 #define TYPEINFO_TYPEFLAG_FRESTRICTED 0x200
155 #define TYPEINFO_TYPEFLAG_FAGGREGATABLE 0x400
156 #define TYPEINFO_TYPEFLAG_FREPLACEABLE 0x800
157 #define TYPEINFO_TYPEFLAG_FDISPATCHABLE 0x1000
158 #define TYPEINFO_TYPEFLAG_FPROXY 0x4000
159 
160 static gint ett_typeinfo_typeattr = -1;
161 static int hf_typeinfo_typeattr = -1;
162 static int hf_typeinfo_guid = -1;
163 static int hf_typeinfo_lcid = -1;
164 static int hf_typeinfo_sizeInstance = -1;
165 static int hf_typeinfo_typekind = -1;
166 static int hf_typeinfo_cFuncs = -1;
167 static int hf_typeinfo_cVars = -1;
168 static int hf_typeinfo_cImplTypes = -1;
169 static int hf_typeinfo_cbSizeVft = -1;
170 static int hf_typeinfo_cbAlignment = -1;
171 static int hf_typeinfo_wMajorVerNum = -1;
172 static int hf_typeinfo_wMinorVerNum = -1;
173 
174 static gint ett_typeinfo_names = -1;
175 
176 static e_guid_t uuid_typeinfo = {0x00020401, 0x0000, 0x0000, {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}};
177 static guint16 ver_typeinfo = 0;
178 static gint ett_typeinfo = -1;
179 static int proto_typeinfo = -1;
180 
181 static const value_string dcom_lcid_vals[] = {
182     {0x0000, "Language neutral"},
183     {0x0400, "LOCALE_USER_DEFAULT"},
184     {0x0409, "English (United States)"},
185     {0x0800, "LOCALE_SYSTEM_DEFAULT"},
186     {0, NULL}};
187 
188 static const value_string typekind_vals[] = {
189     {0x0, "TKIND_ENUM"},
190     {0x01, "TKIND_RECORD"},
191     {0x02, "TKIND_MODULE"},
192     {0x03, "TKIND_INTERFACE"},
193     {0x04, "TKIND_DISPATCH"},
194     {0x05, "TKIND_COCLASS"},
195     {0x06, "TKIND_ALIAS"},
196     {0x07, "TKIND_UNION"},
197     {0, NULL}};
198 
199 
200 
201 static int dissect_typeinfo_PARAMDESCEX(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep, int hfindex);
202 static int dissect_typeinfo_PARAMDESCEX_through_pointer(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep);
203 static int dissect_typeinfo_PARAMDESC(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep, int hfindex);
204 static int dissect_typeinfo_TYPEDESC_item(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep);
205 static int dissect_typeinfo_TYPEDESC(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep, int hfindex);
206 static int dissect_typeinfo_ELEMDESC(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep, int hfindex);
207 static int dissect_typeinfo_ELEMDESC_through_pointer(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep);
208 static int dissect_typeinfo_ELEMDESC_array(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep);
209 static int dissect_typeinfo_FUNCDESC(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep, int hfindex);
210 static int dissect_typeinfo_TYPEATTR(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep, int hfindex);
211 static int dissect_typeinfo_TYPEATTR_through_pointer(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep);
212 static int dissect_typeinfo_FUNCDESC_through_pointer(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep);
213 static int dissect_ITypeInfo_GetFuncDesc_rqst(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep);
214 static int dissect_ITypeInfo_GetFuncDesc_resp(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep);
215 static int dissect_ITypeInfo_GetNames_rqst(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep);
216 static int dissect_ITypeInfo_GetNames_resp(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep);
217 static int dissect_ITypeInfo_GetDocumentation_rqst(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep);
218 static int dissect_ITypeInfo_GetDocumentation_resp(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep);
219 static int dissect_ITypeInfo_GetTypeAttr_rqst(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep);
220 static int dissect_ITypeInfo_GetTypeAttr_resp(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep);
221 
dissect_typeinfo_PARAMDESCEX(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep,int hfindex)222 int dissect_typeinfo_PARAMDESCEX(tvbuff_t *tvb, int offset, packet_info *pinfo,
223                              proto_tree *tree, dcerpc_info *di, guint8 *drep, int hfindex)
224 {
225     guint32 u32Pointer;
226 
227     proto_item *sub_item;
228     proto_tree *sub_tree;
229     guint32 u32SubStart;
230 
231     /* alignment of 4 needed for a PARAMDESCEX */
232     ALIGN_TO_4_BYTES;
233 
234     sub_item = proto_tree_add_item(tree, hfindex, tvb, offset, 0, ENC_NA);
235     sub_tree = proto_item_add_subtree(sub_item, ett_typeinfo_paramdescex);
236 
237     u32SubStart = offset;
238 
239     offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, di, drep,
240                                 hf_typeinfo_paramdescex_cbytes, NULL);
241 
242     offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep, &u32Pointer);
243 
244     if (u32Pointer)
245     {
246         offset = dissect_dcom_VARIANT(tvb, offset, pinfo, sub_tree, di, drep,
247                                       hf_typeinfo_paramdescex_varDefaultValue);
248     }
249 
250     proto_item_set_len(sub_item, offset - u32SubStart);
251     return offset;
252 }
253 
dissect_typeinfo_PARAMDESCEX_through_pointer(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)254 int dissect_typeinfo_PARAMDESCEX_through_pointer(tvbuff_t *tvb, int offset, packet_info *pinfo,
255                                              proto_tree *tree, dcerpc_info *di, guint8 *drep)
256 {
257     return dissect_typeinfo_PARAMDESCEX(tvb, offset, pinfo, tree, di, drep, hf_typeinfo_paramdescex);
258 }
259 
dissect_typeinfo_PARAMDESC(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep,int hfindex)260 int dissect_typeinfo_PARAMDESC(tvbuff_t *tvb, int offset, packet_info *pinfo,
261                            proto_tree *tree, dcerpc_info *di, guint8 *drep, int hfindex)
262 {
263     guint16 u16wParamFlags;
264 
265     proto_item *sub_item;
266     proto_tree *sub_tree;
267     guint32 u32SubStart;
268 
269     static int * const flags[] = {
270         &hf_typeinfo_paramdesc_paramflags_fin,
271         &hf_typeinfo_paramdesc_paramflags_fout,
272         &hf_typeinfo_paramdesc_paramflags_flcid,
273         &hf_typeinfo_paramdesc_paramflags_fretval,
274         &hf_typeinfo_paramdesc_paramflags_fopt,
275         &hf_typeinfo_paramdesc_paramflags_fhasdefault,
276         &hf_typeinfo_paramdesc_paramflags_fhascustdata,
277         NULL};
278 
279     /* alignment of 4 needed for a PARAMDESC */
280     ALIGN_TO_4_BYTES;
281 
282     sub_item = proto_tree_add_item(tree, hfindex, tvb, offset, 0, ENC_NA);
283     sub_tree = proto_item_add_subtree(sub_item, ett_typeinfo_paramdesc);
284 
285     u32SubStart = offset;
286 
287     // pparamdescex
288     offset = dissect_ndr_embedded_pointer(tvb, offset, pinfo, sub_tree, di, drep, dissect_typeinfo_PARAMDESCEX_through_pointer,
289                                           NDR_POINTER_PTR, "Pointer to ParamDescEx", hf_typeinfo_paramdescex);
290 
291     // wParamFlags
292     guint16 u16TmpOffset;
293     u16TmpOffset = dissect_dcom_WORD(tvb, offset, pinfo, NULL, di, drep, -1, &u16wParamFlags);
294 
295     proto_tree_add_bitmask_value(sub_tree, tvb, offset, hf_typeinfo_paramdesc_paramflags,
296                                  ett_typeinfo_paramdesc_paramflags, flags, u16wParamFlags);
297 
298     offset = u16TmpOffset;
299 
300     proto_item_set_len(sub_item, offset - u32SubStart);
301     return offset;
302 }
303 
dissect_typeinfo_TYPEDESC_item(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)304 int dissect_typeinfo_TYPEDESC_item(tvbuff_t *tvb, int offset, packet_info *pinfo,
305                                proto_tree *tree, dcerpc_info *di, guint8 *drep)
306 {
307     return dissect_typeinfo_TYPEDESC(tvb, offset, pinfo, tree, di, drep, hf_typeinfo_typedesc);
308 }
309 
dissect_typeinfo_TYPEDESC(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep,int hfindex)310 int dissect_typeinfo_TYPEDESC(tvbuff_t *tvb, int offset, packet_info *pinfo,
311                           proto_tree *tree, dcerpc_info *di, guint8 *drep, int hfindex)
312 {
313     guint16 u16vtrettag;
314 
315     proto_item *sub_item;
316     proto_tree *sub_tree;
317     guint32 u32SubStart;
318 
319     /* alignment of 4 needed for a TYPEDESC */
320     ALIGN_TO_4_BYTES;
321 
322     sub_item = proto_tree_add_item(tree, hfindex, tvb, offset, 0, ENC_NA);
323     sub_tree = proto_item_add_subtree(sub_item, ett_typeinfo_typedesc);
324 
325     u32SubStart = offset;
326 
327     // vt of ret (union tag)
328     offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep,
329                                hf_typeinfo_typedesc_vtret, &u16vtrettag);
330 
331     if (u16vtrettag == 26 || u16vtrettag == 27) // WIRESHARK_VT_PTR || WIRESHARK_VT_SAFEARRAY
332     {
333         offset = dissect_ndr_embedded_pointer(tvb, offset, pinfo, sub_tree, di, drep, dissect_typeinfo_TYPEDESC_item,
334                                               NDR_POINTER_PTR, "TypeDesc", hf_typeinfo_typedesc);
335     }
336     else if (u16vtrettag == 28) //WIRESHARK_VT_CARRAY
337     {
338         // NOT IMPLEMENTED
339     }
340     else if (u16vtrettag == 29) //WIRESHARK_VT_USERDEFINED
341     {
342         // typedef DWORD HREFTYPE;
343         offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, di, drep,
344                                     hf_typeinfo_typedesc_hreftype, NULL);
345     }
346 
347     // vt of ret
348     offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep,
349                                hf_typeinfo_typedesc_vtret, NULL);
350 
351     proto_item_set_len(sub_item, offset - u32SubStart);
352     return offset;
353 }
354 
dissect_typeinfo_ELEMDESC(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep,int hfindex)355 int dissect_typeinfo_ELEMDESC(tvbuff_t *tvb, int offset, packet_info *pinfo,
356                           proto_tree *tree, dcerpc_info *di, guint8 *drep, int hfindex)
357 {
358     proto_item *sub_item;
359     proto_tree *sub_tree;
360     guint32 u32SubStart;
361 
362     /* alignment of 4 needed for a ELEMDESC */
363     ALIGN_TO_4_BYTES;
364 
365     sub_item = proto_tree_add_item(tree, hfindex, tvb, offset, 0, ENC_NA);
366     sub_tree = proto_item_add_subtree(sub_item, ett_typeinfo_elemdesc);
367 
368     u32SubStart = offset;
369 
370     offset = dissect_typeinfo_TYPEDESC(tvb, offset, pinfo, sub_tree, di, drep, hf_typeinfo_typedesc);
371     offset = dissect_typeinfo_PARAMDESC(tvb, offset, pinfo, sub_tree, di, drep, hf_typeinfo_paramdesc);
372 
373     proto_item_set_len(sub_item, offset - u32SubStart);
374 
375     return offset;
376 }
377 
dissect_typeinfo_ELEMDESC_through_pointer(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)378 int dissect_typeinfo_ELEMDESC_through_pointer(tvbuff_t *tvb, int offset,
379                                      packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
380 {
381     return dissect_typeinfo_ELEMDESC(tvb, offset, pinfo, tree, di, drep, hf_typeinfo_funcdesc_elemdesc);
382 }
383 
dissect_typeinfo_ELEMDESC_array(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)384 int dissect_typeinfo_ELEMDESC_array(tvbuff_t *tvb, int offset,
385                            packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
386 {
387     return dissect_ndr_ucarray(tvb, offset, pinfo, tree, di, drep, dissect_typeinfo_ELEMDESC_through_pointer);
388 }
389 
dissect_typeinfo_FUNCDESC(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep,int hfindex)390 int dissect_typeinfo_FUNCDESC(tvbuff_t *tvb, int offset,
391                           packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep, int hfindex)
392 {
393     guint16 u16Funcflags;
394 
395     proto_item *sub_item;
396     proto_tree *sub_tree;
397 
398     proto_item *func_elemdesc_sub_item;
399     proto_tree *func_elemdesc_tree;
400 
401     guint32 u32SubStart;
402 
403     static int * const flags[] = {
404         &hf_typeinfo_funcdesc_funcflags_frestricted,
405         &hf_typeinfo_funcdesc_funcflags_fsource,
406         &hf_typeinfo_funcdesc_funcflags_fbindable,
407         &hf_typeinfo_funcdesc_funcflags_frequestedit,
408         &hf_typeinfo_funcdesc_funcflags_fdisplaybind,
409         &hf_typeinfo_funcdesc_funcflags_fdefaultbind,
410         &hf_typeinfo_funcdesc_funcflags_fhidden,
411         &hf_typeinfo_funcdesc_funcflags_fusesgetlasterror,
412         &hf_typeinfo_funcdesc_funcflags_fdefaultcollelem,
413         &hf_typeinfo_funcdesc_funcflags_fuidefault,
414         &hf_typeinfo_funcdesc_funcflags_fnowbrowsable,
415         &hf_typeinfo_funcdesc_funcflags_freplaceable,
416         &hf_typeinfo_funcdesc_funcflags_fimmediatebind,
417         NULL};
418 
419     sub_item = proto_tree_add_item(tree, hfindex, tvb, offset, 0, ENC_NA);
420     sub_tree = proto_item_add_subtree(sub_item, ett_typeinfo_funcdesc);
421 
422     u32SubStart = offset;
423 
424     // memid
425     offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, di, drep,
426                                 hf_typeinfo_funcdesc_memid, NULL);
427 
428     // lReserved1
429     offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, di, drep,
430                                 hf_typeinfo_funcdesc_resv32, NULL);
431     // lprgelemdescParam
432     offset = dissect_ndr_embedded_pointer(tvb, offset, pinfo, sub_tree, di, drep,
433                                           dissect_typeinfo_ELEMDESC_array, NDR_POINTER_PTR, "Parameter ElemDesc", hf_typeinfo_funcdesc_elemdesc);
434 
435     // funckind
436     offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, di, drep,
437                                 hf_typeinfo_funcdesc_funckind, NULL);
438 
439     // invkind
440     offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, di, drep,
441                                 hf_typeinfo_funcdesc_invkind, NULL);
442 
443     // callconv
444     offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, di, drep,
445                                 hf_typeinfo_funcdesc_callconv, NULL);
446 
447     // cParams
448     offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep,
449                                hf_typeinfo_funcdesc_params, NULL);
450 
451     // cParamsOpt
452     offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep,
453                                hf_typeinfo_funcdesc_paramsopt, NULL);
454 
455     // oVft
456     offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep,
457                                hf_typeinfo_funcdesc_vft, NULL);
458 
459     // cReserved2
460     offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep,
461                                hf_typeinfo_funcdesc_resv16, NULL);
462 
463     // create tree for function element description
464     func_elemdesc_sub_item = proto_tree_add_item(sub_tree, hfindex, tvb, offset, 0, ENC_NA);
465     func_elemdesc_tree = proto_tree_add_subtree(sub_tree, tvb, offset, 0,
466                                                 ett_typeinfo_elemdesc, &func_elemdesc_sub_item, "Function ElemDesc");
467     // elemdescFunc
468     offset = dissect_typeinfo_ELEMDESC(tvb, offset, pinfo, func_elemdesc_tree, di, drep, hf_typeinfo_funcdesc_elemdesc);
469 
470     // func flags
471     guint16 u16TmpOffset;
472     u16TmpOffset = dissect_dcom_WORD(tvb, offset, pinfo, NULL, di, drep, -1, &u16Funcflags);
473 
474     proto_tree_add_bitmask_value(sub_tree, tvb, offset, hf_typeinfo_funcdesc_funcflags,
475                                  ett_typeinfo_funcdesc_funcflags, flags, u16Funcflags);
476 
477     offset = u16TmpOffset;
478 
479     proto_item_set_len(sub_item, offset - u32SubStart);
480 
481     return offset;
482 }
483 
dissect_typeinfo_FUNCDESC_through_pointer(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)484 int dissect_typeinfo_FUNCDESC_through_pointer(tvbuff_t *tvb, int offset, packet_info *pinfo,
485                                           proto_tree *tree, dcerpc_info *di, guint8 *drep)
486 {
487     return dissect_typeinfo_FUNCDESC(tvb, offset, pinfo, tree, di, drep, hf_typeinfo_funcdesc);
488 }
489 
dissect_typeinfo_TYPEATTR(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep,int hfindex)490 int dissect_typeinfo_TYPEATTR(tvbuff_t *tvb, int offset, packet_info *pinfo,
491                               proto_tree *tree, dcerpc_info *di, guint8 *drep, int hfindex)
492 {
493     guint16 u16wTypeFlags;
494 
495     proto_item *sub_item;
496     proto_tree *sub_tree;
497     guint32 u32SubStart;
498 
499     static int * const flags[] = {
500         &hf_typeinfo_typeflags_fappobject,
501         &hf_typeinfo_typeflags_fcancreate,
502         &hf_typeinfo_typeflags_flicensed,
503         &hf_typeinfo_typeflags_fpredeclid,
504         &hf_typeinfo_typeflags_fhidden,
505         &hf_typeinfo_typeflags_fcontrol,
506         &hf_typeinfo_typeflags_fdual,
507         &hf_typeinfo_typeflags_fnonextensible,
508         &hf_typeinfo_typeflags_foleautomation,
509         &hf_typeinfo_typeflags_frestricted,
510         &hf_typeinfo_typeflags_faggregatable,
511         &hf_typeinfo_typeflags_freplaceable,
512         &hf_typeinfo_typeflags_fdispatchable,
513         &hf_typeinfo_typeflags_fproxy,
514         NULL};
515 
516     sub_item = proto_tree_add_item(tree, hfindex, tvb, offset, 0, ENC_NA);
517     sub_tree = proto_item_add_subtree(sub_item, ett_typeinfo_typeattr);
518 
519     u32SubStart = offset;
520 
521     // guid
522     offset = dissect_dcom_UUID(tvb, offset, pinfo, sub_tree, di, drep,
523                                hf_typeinfo_guid, NULL);
524 
525     // lcid
526     offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, di, drep,
527                                 hf_typeinfo_lcid, NULL);
528 
529     // dwReserved1
530     offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, di, drep,
531                                 hf_typeinfo_reserved32, NULL);
532 
533     // dwReserved2
534     offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, di, drep,
535                                 hf_typeinfo_reserved32, NULL);
536 
537     // dwReserved3
538     offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, di, drep,
539                                 hf_typeinfo_reserved32, NULL);
540 
541     // lpstrReserved4
542     offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, di, drep,
543                                 hf_typeinfo_reserved32, NULL);
544 
545     // cbSizeInstance
546     offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, di, drep,
547                                 hf_typeinfo_sizeInstance, NULL);
548 
549     // typekind
550     offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, di, drep,
551                                 hf_typeinfo_typekind, NULL);
552 
553     // cFuncs
554     offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep,
555                                hf_typeinfo_cFuncs, NULL);
556 
557     // cVars
558     offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep,
559                                hf_typeinfo_cVars, NULL);
560 
561     // cImplTypes
562     offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep,
563                                hf_typeinfo_cImplTypes, NULL);
564 
565     // cbSizeVft
566     offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep,
567                                hf_typeinfo_cbSizeVft, NULL);
568 
569     // cbAlignment
570     offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep,
571                                hf_typeinfo_cbAlignment, NULL);
572 
573     // wTypeFlags
574     guint16 u16TmpOffset;
575     u16TmpOffset = dissect_dcom_WORD(tvb, offset, pinfo, NULL, di, drep, -1, &u16wTypeFlags);
576 
577     proto_tree_add_bitmask_value(sub_tree, tvb, offset, hf_typeinfo_typeflags,
578                                  ett_typeinfo_typeflags, flags, u16wTypeFlags);
579 
580     offset = u16TmpOffset;
581 
582     // wMajorVerNum
583     offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep,
584                                hf_typeinfo_wMajorVerNum, NULL);
585 
586     // wMinorVerNum
587     offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep,
588                                hf_typeinfo_wMinorVerNum, NULL);
589 
590     offset = dissect_typeinfo_TYPEDESC(tvb, offset, pinfo, sub_tree, di, drep, hf_typeinfo_typedesc);
591 
592     // dwReserved5
593     offset = dissect_dcom_DWORD(tvb, offset, pinfo, sub_tree, di, drep,
594                                 hf_typeinfo_reserved32, NULL);
595 
596     // wReserved6
597     offset = dissect_dcom_WORD(tvb, offset, pinfo, sub_tree, di, drep,
598                                hf_typeinfo_reserved16, NULL);
599 
600     proto_item_set_len(sub_item, offset - u32SubStart);
601 
602     return offset;
603 }
604 
dissect_typeinfo_TYPEATTR_through_pointer(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)605 int dissect_typeinfo_TYPEATTR_through_pointer(tvbuff_t *tvb, int offset, packet_info *pinfo,
606                                               proto_tree *tree, dcerpc_info *di, guint8 *drep)
607 {
608     offset = dissect_typeinfo_TYPEATTR(tvb, offset, pinfo, tree, di, drep, hf_typeinfo_typeattr);
609 
610     return offset;
611 }
612 
613 static int
dissect_bstr_through_pointer(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)614 dissect_bstr_through_pointer(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
615 {
616     gchar szName[1000] = {0};
617     offset = dissect_dcom_BSTR(tvb, offset, pinfo, tree, di, drep,
618                                di->hf_index, szName, sizeof(szName));
619     return offset;
620 }
621 
622 static int
dissect_dword_through_pointer(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)623 dissect_dword_through_pointer(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
624 {
625     offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
626                                 di->hf_index, NULL);
627 
628     return offset;
629 }
630 
dissect_ITypeInfo_GetFuncDesc_rqst(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)631 int dissect_ITypeInfo_GetFuncDesc_rqst(tvbuff_t *tvb, int offset,
632                                        packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
633 {
634     offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
635 
636     offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
637                                 hf_typeinfo_index, NULL);
638 
639     return offset;
640 }
641 
dissect_ITypeInfo_GetFuncDesc_resp(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)642 int dissect_ITypeInfo_GetFuncDesc_resp(tvbuff_t *tvb, int offset,
643                                        packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
644 {
645     offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
646 
647     // funcdesc
648     offset = dissect_ndr_toplevel_pointer(tvb, offset, pinfo, tree, di, drep, dissect_typeinfo_FUNCDESC_through_pointer, NDR_POINTER_UNIQUE, "Pointer to FuncDesc", hf_typeinfo_funcdesc);
649 
650     // reserved
651     offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
652                                 hf_typeinfo_reserved32, NULL);
653 
654     /* HRESULT of call */
655     offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep,
656                                   NULL);
657 
658     return offset;
659 }
660 
dissect_ITypeInfo_GetNames_rqst(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)661 int dissect_ITypeInfo_GetNames_rqst(tvbuff_t *tvb, int offset,
662                                     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
663 {
664     offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
665 
666     // memid
667     offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
668                                 hf_typeinfo_memid, NULL);
669 
670     // cMaxNames
671     offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
672                                 hf_typeinfo_maxnames, NULL);
673 
674     return offset;
675 }
676 
dissect_ITypeInfo_GetNames_resp(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)677 int dissect_ITypeInfo_GetNames_resp(tvbuff_t *tvb, int offset,
678                                     packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
679 {
680     guint32 u32ArrayLength;
681     guint32 u32Pointer;
682 
683     guint32 u32VarOffset;
684     guint32 u32Tmp;
685 
686     gchar szName[1000] = {0};
687 
688     proto_item *sub_item;
689     proto_tree *sub_tree;
690     guint32 u32SubStart;
691 
692     offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
693 
694     sub_item = proto_tree_add_item(tree, hf_typeinfo_names, tvb, offset, 0, ENC_NA);
695     sub_tree = proto_item_add_subtree(sub_item, ett_typeinfo_names);
696 
697     u32SubStart = offset;
698 
699     offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, sub_tree, di, drep, NULL);
700     offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep, NULL);
701     offset = dissect_dcom_dcerpc_array_size(tvb, offset, pinfo, sub_tree, di, drep,
702                                             &u32ArrayLength);
703 
704     u32VarOffset = offset + u32ArrayLength * 4;
705     u32Tmp = u32ArrayLength;
706     while (u32Tmp--)
707     {
708         offset = dissect_dcom_dcerpc_pointer(tvb, offset, pinfo, sub_tree, di, drep,
709                                              &u32Pointer);
710         if (u32Pointer)
711         {
712             u32VarOffset = dissect_dcom_BSTR(tvb, u32VarOffset, pinfo, sub_tree, di, drep,
713                                              hf_typeinfo_names_value, szName, sizeof(szName));
714         }
715     }
716     offset = u32VarOffset;
717 
718     col_append_fstr(pinfo->cinfo, COL_INFO,
719                     " %u Names", u32ArrayLength);
720 
721     proto_item_set_len(sub_item, offset - u32SubStart);
722 
723     // pcNames
724     offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
725                                 hf_typeinfo_maxnames, NULL);
726 
727     /* HRESULT of call */
728     offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep, NULL);
729 
730     return offset;
731 }
732 
dissect_ITypeInfo_GetDocumentation_rqst(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)733 int dissect_ITypeInfo_GetDocumentation_rqst(tvbuff_t *tvb, int offset,
734                                             packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
735 {
736     guint32 u32Flags;
737 
738     guint32 u32TmpOffset;
739 
740     static int * const flags[] = {
741         &hf_typeinfo_docflags_name,
742         &hf_typeinfo_docflags_docstring,
743         &hf_typeinfo_docflags_helpctx,
744         &hf_typeinfo_docflags_helpfile,
745         NULL};
746 
747     offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
748 
749     // memid
750     offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
751                                 hf_typeinfo_memid, NULL);
752 
753     // refPtrFlags
754     u32TmpOffset = dissect_dcom_DWORD(tvb, offset, pinfo, NULL, di, drep, -1, &u32Flags);
755 
756     proto_tree_add_bitmask_value(tree, tvb, offset, hf_typeinfo_docflags,
757                                  ett_typeinfo_docflags, flags, u32Flags);
758 
759     offset = u32TmpOffset;
760 
761     return offset;
762 }
763 
dissect_ITypeInfo_GetDocumentation_resp(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)764 int dissect_ITypeInfo_GetDocumentation_resp(tvbuff_t *tvb, int offset,
765                                             packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
766 {
767     offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
768 
769     // pBstrDocName
770     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep, dissect_bstr_through_pointer, NDR_POINTER_UNIQUE, "Pointer to Doc Name", hf_typeinfo_docname);
771 
772     // pBstrDocString
773     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep, dissect_bstr_through_pointer, NDR_POINTER_UNIQUE, "Pointer to Doc String", hf_typeinfo_docstring);
774 
775     // pdwHelpContext
776     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep, dissect_dword_through_pointer, NDR_POINTER_UNIQUE, "Pointer to Help Context", hf_typeinfo_helpctx);
777 
778     // pBstrHelpFile
779     offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep, dissect_bstr_through_pointer, NDR_POINTER_UNIQUE, "Pointer to Help File", hf_typeinfo_helpfile);
780 
781     /* HRESULT of call */
782     offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep, NULL);
783     return offset;
784 }
785 
dissect_ITypeInfo_GetTypeAttr_rqst(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)786 int dissect_ITypeInfo_GetTypeAttr_rqst(tvbuff_t *tvb, int offset,
787                                        packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
788 {
789     offset = dissect_dcom_this(tvb, offset, pinfo, tree, di, drep);
790     return offset;
791 }
792 
dissect_ITypeInfo_GetTypeAttr_resp(tvbuff_t * tvb,int offset,packet_info * pinfo,proto_tree * tree,dcerpc_info * di,guint8 * drep)793 int dissect_ITypeInfo_GetTypeAttr_resp(tvbuff_t *tvb, int offset,
794                                        packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
795 {
796     offset = dissect_dcom_that(tvb, offset, pinfo, tree, di, drep);
797 
798     offset = dissect_ndr_toplevel_pointer(tvb, offset, pinfo, tree, di, drep, dissect_typeinfo_TYPEATTR_through_pointer, NDR_POINTER_UNIQUE, "Pointer to TypeAttr", hf_typeinfo_typeattr);
799 
800     // reserved
801     offset = dissect_dcom_DWORD(tvb, offset, pinfo, tree, di, drep,
802                                 hf_typeinfo_reserved32, NULL);
803 
804     /* HRESULT of call */
805     offset = dissect_dcom_HRESULT(tvb, offset, pinfo, tree, di, drep, NULL);
806 
807     return offset;
808 }
809 
810 /* sub dissector table of ITypeInfo interface */
811 static dcerpc_sub_dissector typeinfo_dissectors[] = {
812     {3, "GetTypeAttr", dissect_ITypeInfo_GetTypeAttr_rqst, dissect_ITypeInfo_GetTypeAttr_resp},
813     {4, "GetTypeComp", NULL, NULL},
814     {5, "GetFuncDesc", dissect_ITypeInfo_GetFuncDesc_rqst, dissect_ITypeInfo_GetFuncDesc_resp},
815     {6, "GetVarDesc", NULL, NULL},
816     {7, "GetNames", dissect_ITypeInfo_GetNames_rqst, dissect_ITypeInfo_GetNames_resp},
817     {8, "GetRefTypeOfImplType", NULL, NULL},
818     {9, "GetImplTypeFlags", NULL, NULL},
819     {12, "GetDocumentation", dissect_ITypeInfo_GetDocumentation_rqst, dissect_ITypeInfo_GetDocumentation_resp},
820     {13, "GetDllEntry", NULL, NULL},
821     {14, "GetRefTypeInfo", NULL, NULL},
822     {16, "CreateInstance", NULL, NULL},
823     {17, "GetMops", NULL, NULL},
824     {18, "GetContainingTypeLib", NULL, NULL},
825 
826     {0, NULL, NULL, NULL},
827 };
828 
proto_register_dcom_typeinfo(void)829 void proto_register_dcom_typeinfo(void)
830 {
831     static hf_register_info hf_typeinfo_typedesc_array[] = {
832         {&hf_typeinfo_typedesc,
833          {"TypeDesc", "typeinfo.typedesc", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}},
834         {&hf_typeinfo_typedesc_vtret,
835          {"VT Return Type", "typeinfo.typedesc.vtret", FT_UINT16, BASE_HEX, VALS(dcom_variant_type_vals), 0x0, NULL, HFILL}},
836         {&hf_typeinfo_typedesc_hreftype,
837          {"Ref Type", "typeinfo.typedesc.reftype", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}},
838     };
839     static hf_register_info hf_typeinfo_paramdesc_array[] = {
840         {&hf_typeinfo_paramdesc,
841          {"ParamDesc", "typeinfo.paramdesc", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}},
842         {&hf_typeinfo_paramdesc_paramflags,
843          {"Param Flags", "typeinfo.paramdesc.paramflags", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL}},
844         {&hf_typeinfo_paramdesc_paramflags_fin,
845          {"FIN", "typeinfo.paramdesc.paramflags_fin", FT_BOOLEAN, 32, TFS(&tfs_set_notset), PARAMFLAG_FIN, NULL, HFILL}},
846         {&hf_typeinfo_paramdesc_paramflags_fout,
847          {"FOUT", "typeinfo.paramdesc.paramflags_fout", FT_BOOLEAN, 32, TFS(&tfs_set_notset), PARAMFLAG_FOUT, NULL, HFILL}},
848         {&hf_typeinfo_paramdesc_paramflags_flcid,
849          {"FLCID", "typeinfo.paramdesc.paramflags_flcid", FT_BOOLEAN, 32, TFS(&tfs_set_notset), PARAMFLAG_FLCID, NULL, HFILL}},
850         {&hf_typeinfo_paramdesc_paramflags_fretval,
851          {"FRETVAL", "typeinfo.paramdesc.paramflags_fretval", FT_BOOLEAN, 32, TFS(&tfs_set_notset), PARAMFLAG_FRETVAL, NULL, HFILL}},
852         {&hf_typeinfo_paramdesc_paramflags_fopt,
853          {"FOPT", "typeinfo.paramdesc.paramflags_fopt", FT_BOOLEAN, 32, TFS(&tfs_set_notset), PARAMFLAG_FOPT, NULL, HFILL}},
854         {&hf_typeinfo_paramdesc_paramflags_fhasdefault,
855          {"FHASDEFAULT", "typeinfo.paramdesc.paramflags_fhasdefault", FT_BOOLEAN, 32, TFS(&tfs_set_notset), PARAMFLAG_FHASDEFAULT, NULL, HFILL}},
856         {&hf_typeinfo_paramdesc_paramflags_fhascustdata,
857          {"FHASCUSTDATA", "typeinfo.paramdesc.paramflags_fhascustdata", FT_BOOLEAN, 32, TFS(&tfs_set_notset), PARAMFLAG_FHASCUSTDATA, NULL, HFILL}},
858     };
859 
860     static hf_register_info hf_typeinfo_paramdescex_array[] = {
861         {&hf_typeinfo_paramdescex,
862          {"ParamDescEx", "typeinfo.paramdescex", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}},
863         {&hf_typeinfo_paramdescex_cbytes,
864          {"Length", "typeinfo.paramdescex.len", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL}},
865         {&hf_typeinfo_paramdescex_varDefaultValue,
866          {"VT Default Value", "typeinfo.paramdescex.vtdefaultval", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}},
867     };
868 
869     static hf_register_info hf_typeinfo_funcdesc_array[] = {
870         {&hf_typeinfo_funcdesc,
871          {"FuncDesc", "typeinfo.funcdesc", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}},
872         {&hf_typeinfo_funcdesc_memid,
873          {"MemberID", "typeinfo.funcdesc.memberid", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}},
874         {&hf_typeinfo_funcdesc_funckind,
875          {"Function Kind", "typeinfo.funcdesc.funckind", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}},
876         {&hf_typeinfo_funcdesc_invkind,
877          {"Invoke Kind", "typeinfo.funcdesc.invkind", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}},
878         {&hf_typeinfo_funcdesc_callconv,
879          {"Call Conv", "typeinfo.funcdesc.callconv", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}},
880         {&hf_typeinfo_funcdesc_params,
881          {"Param Count", "typeinfo.funcdesc.params", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
882         {&hf_typeinfo_funcdesc_paramsopt,
883          {"Param Optional Count", "typeinfo.funcdesc.paramsopt", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
884         {&hf_typeinfo_funcdesc_vft,
885          {"VFT Offset", "typeinfo.funcdesc.ovft", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL}},
886         {&hf_typeinfo_funcdesc_resv16,
887          {"Reserved", "typeinfo.funcdesc.resv", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL}},
888         {&hf_typeinfo_funcdesc_resv32,
889          {"Reserved", "typeinfo.funcdesc.resv", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}},
890         {&hf_typeinfo_funcdesc_elemdesc,
891          {"ElemDesc", "typeinfo.funcdesc.elemdesc", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}},
892 
893         {&hf_typeinfo_funcdesc_funcflags,
894          {"FuncFlags", "typeinfo.funcdesc.funcflags", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL}},
895         {&hf_typeinfo_funcdesc_funcflags_frestricted,
896          {"FRESTRICTED", "typeinfo.funcdesc.funcflags_frestricted", FT_BOOLEAN, 32, TFS(&tfs_set_notset), FUNCFLAG_FRESTRICTED, NULL, HFILL}},
897         {&hf_typeinfo_funcdesc_funcflags_fsource,
898          {"FSOURCE", "typeinfo.funcdesc.funcflags_fsource", FT_BOOLEAN, 32, TFS(&tfs_set_notset), FUNCFLAG_FSOURCE, NULL, HFILL}},
899         {&hf_typeinfo_funcdesc_funcflags_fbindable,
900          {"FBINDABLE", "typeinfo.funcdesc.funcflags_fbindable", FT_BOOLEAN, 32, TFS(&tfs_set_notset), FUNCFLAG_FBINDABLE, NULL, HFILL}},
901         {&hf_typeinfo_funcdesc_funcflags_frequestedit,
902          {"FREQUESTEDIT", "typeinfo.funcdesc.funcflags_frequestedit", FT_BOOLEAN, 32, TFS(&tfs_set_notset), FUNCFLAG_FREQUESTEDIT, NULL, HFILL}},
903         {&hf_typeinfo_funcdesc_funcflags_fdisplaybind,
904          {"FDISPLAYBIND", "typeinfo.funcdesc.funcflags_fdisplaybind", FT_BOOLEAN, 32, TFS(&tfs_set_notset), FUNCFLAG_FDISPLAYBIND, NULL, HFILL}},
905         {&hf_typeinfo_funcdesc_funcflags_fdefaultbind,
906          {"FDEFAULTBIND", "typeinfo.funcdesc.funcflags_fdefaultbind", FT_BOOLEAN, 32, TFS(&tfs_set_notset), FUNCFLAG_FDEFAULTBIND, NULL, HFILL}},
907         {&hf_typeinfo_funcdesc_funcflags_fhidden,
908          {"FHIDDEN", "typeinfo.funcdesc.funcflags_fhidden", FT_BOOLEAN, 32, TFS(&tfs_set_notset), FUNCFLAG_FHIDDEN, NULL, HFILL}},
909         {&hf_typeinfo_funcdesc_funcflags_fusesgetlasterror,
910          {"FUSESGETLASTERROR", "typeinfo.funcdesc.funcflags_fusesgetlasterror", FT_BOOLEAN, 32, TFS(&tfs_set_notset), FUNCFLAG_FUSESGETLASTERROR, NULL, HFILL}},
911         {&hf_typeinfo_funcdesc_funcflags_fdefaultcollelem,
912          {"FDEFAULTCOLLELEM", "typeinfo.funcdesc.funcflags_fdefaultcollelem", FT_BOOLEAN, 32, TFS(&tfs_set_notset), FUNCFLAG_FDEFAULTCOLLELEM, NULL, HFILL}},
913         {&hf_typeinfo_funcdesc_funcflags_fuidefault,
914          {"FUIDEFAULT", "typeinfo.funcdesc.funcflags_fuidefault", FT_BOOLEAN, 32, TFS(&tfs_set_notset), FUNCFLAG_FUIDEFAULT, NULL, HFILL}},
915         {&hf_typeinfo_funcdesc_funcflags_fnowbrowsable,
916          {"FNONBROWSABLE", "typeinfo.funcdesc.funcflags_fnowbrowsable", FT_BOOLEAN, 32, TFS(&tfs_set_notset), FUNCFLAG_FNONBROWSABLE, NULL, HFILL}},
917         {&hf_typeinfo_funcdesc_funcflags_freplaceable,
918          {"FREPLACEABLE", "typeinfo.funcdesc.funcflags_freplaceable", FT_BOOLEAN, 32, TFS(&tfs_set_notset), FUNCFLAG_FREPLACEABLE, NULL, HFILL}},
919         {&hf_typeinfo_funcdesc_funcflags_fimmediatebind,
920          {"FIMMEDIATEBIND", "typeinfo.funcdesc.funcflags_fimmediatebind", FT_BOOLEAN, 32, TFS(&tfs_set_notset), FUNCFLAG_FIMMEDIATEBIND, NULL, HFILL}},
921 
922     };
923 
924     static hf_register_info hf_typeinfo_array[] = {
925         {&hf_typeinfo_opnum,
926          {"Operation", "typeinfo.opnum", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
927         {&hf_typeinfo_index,
928          {"Function Index", "typeinfo.funcindex", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL}},
929         {&hf_typeinfo_reserved32,
930          {"Reserved", "typeinfo.resv", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}},
931         {&hf_typeinfo_reserved16,
932          {"Reserved", "typeinfo.resv", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL}},
933 
934         {&hf_typeinfo_memid,
935          {"MemberID", "typeinfo.memberid", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}},
936 
937         {&hf_typeinfo_names,
938          {"Names", "typeinfo.names", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}},
939         {&hf_typeinfo_names_value,
940          {"Value", "typeinfo.names.value", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL}},
941         {&hf_typeinfo_maxnames,
942          {"Max Names", "typeinfo.maxnames", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL}},
943 
944         {&hf_typeinfo_docflags,
945          {"Documentation Flags", "typeinfo.docflags", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}},
946 
947         {&hf_typeinfo_docflags_name,
948          {"NameArg", "typeinfo.docflags_namearg", FT_BOOLEAN, 32, TFS(&tfs_set_notset), TYPEINFO_DOCFLAGS_NameArg, NULL, HFILL}},
949         {&hf_typeinfo_docflags_docstring,
950          {"DocStringArg", "typeinfo.docflags_docstringarg", FT_BOOLEAN, 32, TFS(&tfs_set_notset), TYPEINFO_DOCFLAGS_DocStringArg, NULL, HFILL}},
951         {&hf_typeinfo_docflags_helpctx,
952          {"HelpContextArg", "typeinfo.docflags_helpctxarg", FT_BOOLEAN, 32, TFS(&tfs_set_notset), TYPEINFO_DOCFLAGS_HelpContextArg, NULL, HFILL}},
953         {&hf_typeinfo_docflags_helpfile,
954          {"HelpFileArg", "typeinfo.docflags_helpfilearg", FT_BOOLEAN, 32, TFS(&tfs_set_notset), TYPEINFO_DOCFLAGS_HelpFileArg, NULL, HFILL}},
955 
956         {&hf_typeinfo_docname,
957          {"Doc Name", "typeinfo.docname", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL}},
958         {&hf_typeinfo_docstring,
959          {"Doc String", "typeinfo.docstring", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL}},
960         {&hf_typeinfo_helpfile,
961          {"Help File", "typeinfo.helpfile", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL}},
962         {&hf_typeinfo_helpctx,
963          {"Help Ctx", "typeinfo.helpctx", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}},
964 
965         {&hf_typeinfo_typeattr,
966          {"TypeAttr", "typeinfo.typeattr", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}},
967         {&hf_typeinfo_guid,
968          {"GUID", "typeinfo.guid", FT_GUID, BASE_NONE, NULL, 0x0, NULL, HFILL}},
969         {&hf_typeinfo_lcid,
970          {"LCID", "typeinfo.lcid", FT_UINT32, BASE_HEX, VALS(dcom_lcid_vals), 0x0, NULL, HFILL}},
971         {&hf_typeinfo_sizeInstance,
972          {"Size Instance", "typeinfo.sizeinstance", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}},
973         {&hf_typeinfo_typekind,
974          {"Type Kind", "typeinfo.typekind", FT_UINT32, BASE_HEX, VALS(typekind_vals), 0x0, NULL, HFILL}},
975         {&hf_typeinfo_cFuncs,
976          {"Func Count", "typeinfo.funcs", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
977         {&hf_typeinfo_cVars,
978          {"Variables Count", "typeinfo.vars", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
979         {&hf_typeinfo_cImplTypes,
980          {"Implemented Interface Count", "typeinfo.impltypes", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
981         {&hf_typeinfo_cbSizeVft,
982          {"Virtual Table Size", "typeinfo.sizevft", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL}},
983         {&hf_typeinfo_cbAlignment,
984          {"Byte Alignment", "typeinfo.balignment", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL}},
985         {&hf_typeinfo_wMajorVerNum,
986          {"MajorVerNum", "typeinfo.majorvernum", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL}},
987         {&hf_typeinfo_wMinorVerNum,
988          {"MinorVerNum", "typeinfo.minorvernum", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL}},
989 
990         {&hf_typeinfo_typeflags,
991          {"Type Flags", "typeinfo.typeflags", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL}},
992         {&hf_typeinfo_typeflags_fappobject,
993          {"FAPPOBJECT", "typeinfo.typeflags_fappobject", FT_BOOLEAN, 32, TFS(&tfs_set_notset), TYPEINFO_TYPEFLAG_FAPPOBJECT, NULL, HFILL}},
994         {&hf_typeinfo_typeflags_fcancreate,
995          {"FCANCREATE", "typeinfo.typeflags_fcancreate", FT_BOOLEAN, 32, TFS(&tfs_set_notset), TYPEINFO_TYPEFLAG_FCANCREATE, NULL, HFILL}},
996         {&hf_typeinfo_typeflags_flicensed,
997          {"FLICENSED", "typeinfo.typeflags_flicensed", FT_BOOLEAN, 32, TFS(&tfs_set_notset), TYPEINFO_TYPEFLAG_FLICENSED, NULL, HFILL}},
998         {&hf_typeinfo_typeflags_fpredeclid,
999          {"FPREDECLID", "typeinfo.typeflags_fpredeclid", FT_BOOLEAN, 32, TFS(&tfs_set_notset), TYPEINFO_TYPEFLAG_FPREDECLID, NULL, HFILL}},
1000         {&hf_typeinfo_typeflags_fhidden,
1001          {"FHIDDEN", "typeinfo.typeflags_fhidden", FT_BOOLEAN, 32, TFS(&tfs_set_notset), TYPEINFO_TYPEFLAG_FHIDDEN, NULL, HFILL}},
1002         {&hf_typeinfo_typeflags_fcontrol,
1003          {"FCONTROL", "typeinfo.typeflags_fcontrol", FT_BOOLEAN, 32, TFS(&tfs_set_notset), TYPEINFO_TYPEFLAG_FCONTROL, NULL, HFILL}},
1004         {&hf_typeinfo_typeflags_fdual,
1005          {"FDUAL", "typeinfo.typeflags_fdual", FT_BOOLEAN, 32, TFS(&tfs_set_notset), TYPEINFO_TYPEFLAG_FDUAL, NULL, HFILL}},
1006         {&hf_typeinfo_typeflags_fnonextensible,
1007          {"FNONEXTENSIBLE", "typeinfo.typeflags_fnonextensible", FT_BOOLEAN, 32, TFS(&tfs_set_notset), TYPEINFO_TYPEFLAG_FNONEXTENSIBLE, NULL, HFILL}},
1008         {&hf_typeinfo_typeflags_foleautomation,
1009          {"FOLEAUTOMATION", "typeinfo.typeflags_foleautomation", FT_BOOLEAN, 32, TFS(&tfs_set_notset), TYPEINFO_TYPEFLAG_FOLEAUTOMATION, NULL, HFILL}},
1010         {&hf_typeinfo_typeflags_frestricted,
1011          {"FRESTRICTED", "typeinfo.typeflags_frestricted", FT_BOOLEAN, 32, TFS(&tfs_set_notset), TYPEINFO_TYPEFLAG_FRESTRICTED, NULL, HFILL}},
1012         {&hf_typeinfo_typeflags_faggregatable,
1013          {"FAGGREGATABLE", "typeinfo.typeflags_faggregatable", FT_BOOLEAN, 32, TFS(&tfs_set_notset), TYPEINFO_TYPEFLAG_FAGGREGATABLE, NULL, HFILL}},
1014         {&hf_typeinfo_typeflags_freplaceable,
1015          {"FREPLACEABLE", "typeinfo.typeflags_freplaceable", FT_BOOLEAN, 32, TFS(&tfs_set_notset), TYPEINFO_TYPEFLAG_FREPLACEABLE, NULL, HFILL}},
1016         {&hf_typeinfo_typeflags_fdispatchable,
1017          {"FDISPATCHABLE", "typeinfo.typeflags_fdispatchable", FT_BOOLEAN, 32, TFS(&tfs_set_notset), TYPEINFO_TYPEFLAG_FDISPATCHABLE, NULL, HFILL}},
1018         {&hf_typeinfo_typeflags_fproxy,
1019          {"FPROXY", "typeinfo.typeflags_fproxy", FT_BOOLEAN, 32, TFS(&tfs_set_notset), TYPEINFO_TYPEFLAG_FPROXY, NULL, HFILL}},
1020     };
1021 
1022     static gint *ett[] = {
1023         &ett_typeinfo,
1024         &ett_typeinfo_docflags,
1025         &ett_typeinfo_typeflags,
1026         &ett_typeinfo_names,
1027         &ett_typeinfo_typeattr,
1028         &ett_typeinfo_elemdesc,
1029         &ett_typeinfo_typedesc,
1030         &ett_typeinfo_paramdesc,
1031         &ett_typeinfo_paramdesc_paramflags,
1032         &ett_typeinfo_paramdescex,
1033         &ett_typeinfo_funcdesc,
1034         &ett_typeinfo_funcdesc_funcflags,
1035     };
1036 
1037     /* ITypeInfo currently only partially implemented */
1038     proto_typeinfo = proto_register_protocol("DCOM ITypeInfo", "ITypeInfo", "typeinfo");
1039     proto_register_field_array(proto_typeinfo, hf_typeinfo_typedesc_array, array_length(hf_typeinfo_typedesc_array));
1040     proto_register_field_array(proto_typeinfo, hf_typeinfo_paramdesc_array, array_length(hf_typeinfo_paramdesc_array));
1041     proto_register_field_array(proto_typeinfo, hf_typeinfo_paramdescex_array, array_length(hf_typeinfo_paramdescex_array));
1042     proto_register_field_array(proto_typeinfo, hf_typeinfo_funcdesc_array, array_length(hf_typeinfo_funcdesc_array));
1043     proto_register_field_array(proto_typeinfo, hf_typeinfo_array, array_length(hf_typeinfo_array));
1044     proto_register_subtree_array(ett, array_length(ett));
1045 }
1046 
proto_reg_handoff_dcom_typeinfo(void)1047 void proto_reg_handoff_dcom_typeinfo(void)
1048 {
1049     dcerpc_init_uuid(proto_typeinfo, ett_typeinfo,
1050                      &uuid_typeinfo, ver_typeinfo,
1051                      typeinfo_dissectors, hf_typeinfo_opnum);
1052 }
1053 
1054 /*
1055  * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
1056  *
1057  * Local variables:
1058  * c-basic-offset: 8
1059  * tab-width: 8
1060  * indent-tabs-mode: t
1061  * End:
1062  *
1063  * vi: set shiftwidth=8 tabstop=8 noexpandtab:
1064  * :indentSize=8:tabSize=8:noTabs=false:
1065  */
1066