2 * Routines for SMB \PIPE\winreg packet disassembly
3 * Copyright 2001-2003 Tim Potter <tpot@samba.org>
5 * $Id: packet-dcerpc-reg.c,v 1.17 2003/06/05 04:22:03 guy Exp $
7 * Ethereal - Network traffic analyzer
8 * By Gerald Combs <gerald@ethereal.com>
9 * Copyright 1998 Gerald Combs
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31 #include <epan/packet.h>
32 #include "packet-dcerpc.h"
33 #include "packet-dcerpc-nt.h"
34 #include "packet-dcerpc-reg.h"
37 /* Global hf index fields */
39 static int hf_rc = -1;
40 static int hf_hnd = -1;
41 static int hf_access_mask = -1;
45 static int hf_openhklm_unknown1 = -1;
46 static int hf_openhklm_unknown2 = -1;
50 static int hf_querykey_class = -1;
51 static int hf_querykey_num_subkeys = -1;
52 static int hf_querykey_max_subkey_len = -1;
53 static int hf_querykey_reserved = -1;
54 static int hf_querykey_num_values = -1;
55 static int hf_querykey_max_valname_len = -1;
56 static int hf_querykey_max_valbuf_size = -1;
57 static int hf_querykey_secdesc = -1;
58 static int hf_querykey_modtime = -1;
62 static int hf_keyname = -1;
63 static int hf_openentry_unknown1 = -1;
67 static int hf_unknown1A_unknown1 = -1;
69 /* Data that is passed to a open call */
72 dissect_open_data(tvbuff_t *tvb, int offset, packet_info *pinfo,
73 proto_tree *tree, char *drep)
75 offset = dissect_ndr_uint16(
76 tvb, offset, pinfo, tree, drep,
77 hf_openhklm_unknown1, NULL);
79 offset = dissect_ndr_uint16(
80 tvb, offset, pinfo, tree, drep,
81 hf_openhklm_unknown1, NULL);
83 offset = dissect_ndr_uint32(
84 tvb, offset, pinfo, tree, drep,
85 hf_access_mask, NULL);
95 RegOpenHKLM_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
96 proto_tree *tree, char *drep)
100 offset = dissect_ndr_pointer(
101 tvb, offset, pinfo, tree, drep,
103 NDR_POINTER_UNIQUE, "Unknown", -1);
105 dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
111 RegOpenHKLM_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
112 proto_tree *tree, char *drep)
114 e_ctx_hnd policy_hnd;
115 proto_item *hnd_item;
120 offset = dissect_nt_policy_hnd(
121 tvb, offset, pinfo, tree, drep,
122 hf_hnd, &policy_hnd, &hnd_item, TRUE, FALSE);
124 offset = dissect_ntstatus(tvb, offset, pinfo, tree, drep,
128 dcerpc_smb_store_pol_name(&policy_hnd, pinfo, "HKLM handle");
129 if (hnd_item != NULL)
130 proto_item_append_text(hnd_item, ": HKLM handle");
133 dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
143 RegOpenHKU_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
144 proto_tree *tree, char *drep)
148 offset = dissect_ndr_pointer(
149 tvb, offset, pinfo, tree, drep,
151 NDR_POINTER_UNIQUE, "Unknown", -1);
153 dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
159 RegOpenHKU_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
160 proto_tree *tree, char *drep)
162 e_ctx_hnd policy_hnd;
163 proto_item *hnd_item;
168 offset = dissect_nt_policy_hnd(
169 tvb, offset, pinfo, tree, drep,
170 hf_hnd, &policy_hnd, &hnd_item, TRUE, FALSE);
172 offset = dissect_ntstatus(
173 tvb, offset, pinfo, tree, drep, hf_rc, &status);
176 dcerpc_smb_store_pol_name(&policy_hnd, pinfo, "HKU handle");
177 if (hnd_item != NULL)
178 proto_item_append_text(hnd_item, ": HKU handle");
181 dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
191 RegOpenHKCR_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
192 proto_tree *tree, char *drep)
196 offset = dissect_ndr_pointer(
197 tvb, offset, pinfo, tree, drep,
199 NDR_POINTER_UNIQUE, "Unknown", -1);
201 dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
207 RegOpenHKCR_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
208 proto_tree *tree, char *drep)
210 e_ctx_hnd policy_hnd;
211 proto_item *hnd_item;
216 offset = dissect_nt_policy_hnd(
217 tvb, offset, pinfo, tree, drep,
218 hf_hnd, &policy_hnd, &hnd_item, TRUE, FALSE);
220 offset = dissect_ntstatus(
221 tvb, offset, pinfo, tree, drep, hf_rc, &status);
224 dcerpc_smb_store_pol_name(&policy_hnd, pinfo, "HKCR handle");
225 if (hnd_item != NULL)
226 proto_item_append_text(hnd_item, ": HKCR handle");
229 dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
239 RegClose_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
240 proto_tree *tree, char *drep)
244 offset = dissect_nt_policy_hnd(
245 tvb, offset, pinfo, tree, drep,
246 hf_hnd, NULL, NULL, FALSE, TRUE);
248 dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
254 RegClose_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
255 proto_tree *tree, char *drep)
259 offset = dissect_nt_policy_hnd(
260 tvb, offset, pinfo, tree, drep,
261 hf_hnd, NULL, NULL, FALSE, FALSE);
263 offset = dissect_ntstatus(
264 tvb, offset, pinfo, tree, drep, hf_rc, NULL);
266 dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
276 RegQueryKey_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
277 proto_tree *tree, char *drep)
281 offset = dissect_nt_policy_hnd(
282 tvb, offset, pinfo, tree, drep,
283 hf_hnd, NULL, NULL, FALSE, FALSE);
285 offset = dissect_ndr_counted_string(
286 tvb, offset, pinfo, tree, drep, hf_querykey_class, 0);
288 dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
294 RegQueryKey_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
295 proto_tree *tree, char *drep)
299 offset = dissect_ndr_counted_string(
300 tvb, offset, pinfo, tree, drep, hf_querykey_class, 0);
302 offset = dissect_ndr_uint32(
303 tvb, offset, pinfo, tree, drep,
304 hf_querykey_num_subkeys, NULL);
306 offset = dissect_ndr_uint32(
307 tvb, offset, pinfo, tree, drep,
308 hf_querykey_max_subkey_len, NULL);
310 offset = dissect_ndr_uint32(
311 tvb, offset, pinfo, tree, drep,
312 hf_querykey_reserved, NULL);
314 offset = dissect_ndr_uint32(
315 tvb, offset, pinfo, tree, drep,
316 hf_querykey_num_values, NULL);
318 offset = dissect_ndr_uint32(
319 tvb, offset, pinfo, tree, drep,
320 hf_querykey_max_valname_len, NULL);
322 offset = dissect_ndr_uint32(
323 tvb, offset, pinfo, tree, drep,
324 hf_querykey_max_valbuf_size, NULL);
326 offset = dissect_ndr_uint32(
327 tvb, offset, pinfo, tree, drep,
328 hf_querykey_secdesc, NULL);
330 offset = dissect_ndr_nt_NTTIME(
331 tvb, offset, pinfo, tree, drep, hf_querykey_modtime);
333 offset = dissect_ntstatus(
334 tvb, offset, pinfo, tree, drep, hf_rc, NULL);
336 dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
346 RegOpenEntry_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
347 proto_tree *tree, char *drep)
351 offset = dissect_nt_policy_hnd(
352 tvb, offset, pinfo, tree, drep,
353 hf_hnd, NULL, NULL, FALSE, FALSE);
355 offset = dissect_ndr_counted_string(
356 tvb, offset, pinfo, tree, drep, hf_querykey_class, 0);
358 offset = dissect_ndr_uint32(
359 tvb, offset, pinfo, tree, drep,
360 hf_openentry_unknown1, NULL);
362 offset = dissect_ndr_uint32(
363 tvb, offset, pinfo, tree, drep,
364 hf_access_mask, NULL);
366 dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
372 RegOpenEntry_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
373 proto_tree *tree, char *drep)
375 e_ctx_hnd policy_hnd;
376 proto_item *hnd_item;
381 offset = dissect_nt_policy_hnd(
382 tvb, offset, pinfo, tree, drep,
383 hf_hnd, &policy_hnd, &hnd_item, TRUE, FALSE);
385 offset = dissect_ntstatus(
386 tvb, offset, pinfo, tree, drep, hf_rc, &status);
389 dcerpc_smb_store_pol_name(&policy_hnd, pinfo,
391 if (hnd_item != NULL)
392 proto_item_append_text(hnd_item, ": OpenEntry handle");
395 dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
405 RegUnknown1A_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
406 proto_tree *tree, char *drep)
410 offset = dissect_nt_policy_hnd(
411 tvb, offset, pinfo, tree, drep,
412 hf_hnd, NULL, NULL, FALSE, FALSE);
414 dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
420 RegUnknown1A_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
421 proto_tree *tree, char *drep)
425 offset = dissect_ndr_uint32(
426 tvb, offset, pinfo, tree, drep,
427 hf_unknown1A_unknown1, NULL);
429 offset = dissect_ntstatus(
430 tvb, offset, pinfo, tree, drep, hf_rc, NULL);
432 dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
442 RegEnumKey_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
443 proto_tree *tree, char *drep)
447 offset = dissect_nt_policy_hnd(
448 tvb, offset, pinfo, tree, drep,
449 hf_hnd, NULL, NULL, FALSE, FALSE);
451 dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
457 RegEnumKey_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
458 proto_tree *tree, char *drep)
462 offset = dissect_ntstatus(
463 tvb, offset, pinfo, tree, drep, hf_rc, NULL);
465 dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
472 /* Templates for new subdissectors */
479 RegFoo_q(tvbuff_t *tvb, int offset, packet_info *pinfo,
480 proto_tree *tree, char *drep)
482 dcerpc_info *di = (dcerpc_info *)pinfo->private_data;
486 dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
492 RegFoo_r(tvbuff_t *tvb, int offset, packet_info *pinfo,
493 proto_tree *tree, char *drep)
495 dcerpc_info *di = (dcerpc_info *)pinfo->private_data;
499 offset = dissect_ntstatus(
500 tvb, offset, pinfo, tree, drep, hf_rc, NULL);
502 dcerpc_smb_check_long_frame(tvb, offset, pinfo, tree);
509 /* Registry data types */
511 const value_string reg_datatypes[] = {
512 { DCERPC_REG_NONE, "REG_NONE" },
513 { DCERPC_REG_SZ, "REG_SZ" },
514 { DCERPC_REG_EXPAND_SZ, "REG_EXPAND_SZ" },
515 { DCERPC_REG_BINARY, "REG_BINARY" },
516 { DCERPC_REG_DWORD, "REG_DWORD" },
517 { DCERPC_REG_DWORD_LE, "REG_DWORD_LE" },
518 { DCERPC_REG_DWORD_BE, "REG_DWORD_BE" },
519 { DCERPC_REG_LINK, "REG_LINK" },
520 { DCERPC_REG_MULTI_SZ, "REG_MULTI_SZ" },
521 { DCERPC_REG_RESOURCE_LIST, "REG_RESOURCE_LIST" },
522 { DCERPC_REG_FULL_RESOURCE_DESCRIPTOR, "REG_FULL_RESOURCE_DESCRIPTOR" },
523 { DCERPC_REG_RESOURCE_REQUIREMENTS_LIST, "REG_RESOURCE_REQUIREMENTS_LIST" },
527 static int proto_dcerpc_reg = -1;
528 static int hf_reg_opnum = -1;
529 static gint ett_dcerpc_reg = -1;
531 static e_uuid_t uuid_dcerpc_reg = {
532 0x338cd001, 0x2244, 0x31f1,
533 { 0xaa, 0xaa, 0x90, 0x00, 0x38, 0x00, 0x10, 0x03 }
536 static guint16 ver_dcerpc_reg = 1;
538 static dcerpc_sub_dissector dcerpc_reg_dissectors[] = {
539 { REG_OPEN_HKCR, "OpenHKCR", RegOpenHKCR_q, RegOpenHKCR_r },
540 { _REG_UNK_01, "Unknown01", NULL, NULL },
541 { REG_OPEN_HKLM, "OpenHKLM", RegOpenHKLM_q, RegOpenHKLM_r },
542 { _REG_UNK_03, "Unknown03", NULL, NULL },
543 { REG_OPEN_HKU, "OpenHKU", RegOpenHKU_q, RegOpenHKU_r },
544 { REG_CLOSE, "Close", RegClose_q, RegClose_r },
545 { REG_CREATE_KEY, "CreateKey", NULL, NULL },
546 { REG_DELETE_KEY, "DeleteKey", NULL, NULL },
547 { REG_DELETE_VALUE, "DeleteValue", NULL, NULL },
548 { REG_ENUM_KEY, "EnumKey", RegEnumKey_q, RegEnumKey_r },
549 { REG_ENUM_VALUE, "EnumValue", NULL, NULL },
550 { REG_FLUSH_KEY, "FlushKey", NULL, NULL },
551 { REG_GET_KEY_SEC, "GetKeySecurity", NULL, NULL },
552 { _REG_UNK_0D, "Unknown0d", NULL, NULL },
553 { _REG_UNK_0E, "Unknown0e", NULL, NULL },
554 { REG_OPEN_ENTRY, "OpenEntry", RegOpenEntry_q, RegOpenEntry_r },
555 { REG_QUERY_KEY, "QueryKey", RegQueryKey_q, RegQueryKey_r },
556 { REG_INFO, "Info", NULL, NULL },
557 { _REG_UNK_12, "Unknown12", NULL, NULL },
558 { _REG_UNK_13, "Unknown13", NULL, NULL },
559 { _REG_UNK_14, "Unknown14", NULL, NULL },
560 { REG_SET_KEY_SEC, "SetKeySecurity", NULL, NULL },
561 { REG_CREATE_VALUE, "CreateValue", NULL, NULL },
562 { _REG_UNK_17, "Unknown17", NULL, NULL },
563 { REG_SHUTDOWN, "Shutdown", NULL, NULL },
564 { REG_ABORT_SHUTDOWN, "AbortShutdown", NULL, NULL },
565 { _REG_UNK_1A, "Unknown1A", RegUnknown1A_q, RegUnknown1A_r },
567 { 0, NULL, NULL, NULL }
570 static const value_string reg_opnum_vals[] = {
571 { REG_OPEN_HKCR, "OpenHKCR" },
572 { _REG_UNK_01, "Unknown01" },
573 { REG_OPEN_HKLM, "OpenHKLM" },
574 { _REG_UNK_03, "Unknown03" },
575 { REG_OPEN_HKU, "OpenHKU" },
576 { REG_CLOSE, "Close" },
577 { REG_CREATE_KEY, "CreateKey" },
578 { REG_DELETE_KEY, "DeleteKey" },
579 { REG_DELETE_VALUE, "DeleteValue" },
580 { REG_ENUM_KEY, "EnumKey" },
581 { REG_ENUM_VALUE, "EnumValue" },
582 { REG_FLUSH_KEY, "FlushKey" },
583 { REG_GET_KEY_SEC, "GetKeySecurity" },
584 { _REG_UNK_0D, "Unknown0d" },
585 { _REG_UNK_0E, "Unknown0e" },
586 { REG_OPEN_ENTRY, "OpenEntry" },
587 { REG_QUERY_KEY, "QueryKey" },
588 { REG_INFO, "Info" },
589 { _REG_UNK_12, "Unknown12" },
590 { _REG_UNK_13, "Unknown13" },
591 { _REG_UNK_14, "Unknown14" },
592 { REG_SET_KEY_SEC, "SetKeySecurity" },
593 { REG_CREATE_VALUE, "CreateValue" },
594 { _REG_UNK_17, "Unknown17" },
595 { REG_SHUTDOWN, "Shutdown" },
596 { REG_ABORT_SHUTDOWN, "AbortShutdown" },
597 { _REG_UNK_1A, "Unknown1A" },
602 proto_register_dcerpc_reg(void)
604 static hf_register_info hf[] = {
609 { "Context handle", "reg.hnd", FT_BYTES, BASE_NONE,
610 NULL, 0x0, "REG policy handle", HFILL }},
613 { "Return code", "reg.rc", FT_UINT32, BASE_HEX,
614 VALS(NT_errors), 0x0, "REG return code", HFILL }},
617 { "Operation", "reg.opnum", FT_UINT16, BASE_DEC,
618 VALS(reg_opnum_vals), 0x0, "Operation", HFILL }},
621 { "Access mask", "reg.access_mask", FT_UINT32, BASE_HEX,
622 NULL, 0x0, "Access mask", HFILL }},
626 { &hf_openhklm_unknown1,
627 { "Unknown 1", "reg.openhklm.unknown1", FT_UINT16, BASE_HEX,
628 NULL, 0x0, "Unknown 1", HFILL }},
630 { &hf_openhklm_unknown2,
631 { "Unknown 2", "reg.openhklm.unknown2", FT_UINT16, BASE_HEX,
632 NULL, 0x0, "Unknown 2", HFILL }},
636 { &hf_querykey_class,
637 { "Class", "reg.querykey.class", FT_STRING, BASE_NONE,
638 NULL, 0, "Class", HFILL }},
640 { &hf_querykey_num_subkeys,
641 { "Num subkeys", "reg.querykey.num_subkeys", FT_UINT32, BASE_DEC,
642 NULL, 0x0, "Num subkeys", HFILL }},
644 { &hf_querykey_max_subkey_len,
645 { "Max subkey len", "reg.querykey.max_subkey_len", FT_UINT32, BASE_DEC,
646 NULL, 0x0, "Max subkey len", HFILL }},
648 { &hf_querykey_reserved,
649 { "Reserved", "reg.querykey.reserved", FT_UINT32, BASE_DEC,
650 NULL, 0x0, "Reserved", HFILL }},
652 { &hf_querykey_num_values,
653 { "Num values", "reg.querykey.num_values", FT_UINT32, BASE_DEC,
654 NULL, 0x0, "Num values", HFILL }},
656 { &hf_querykey_max_valname_len,
657 { "Max valnum len", "reg.querykey.max_valname_len", FT_UINT32, BASE_DEC,
658 NULL, 0x0, "Max valname len", HFILL }},
660 { &hf_querykey_max_valbuf_size,
661 { "Max valbuf size", "reg.querykey.max_valbuf_size", FT_UINT32, BASE_DEC,
662 NULL, 0x0, "Max valbuf size", HFILL }},
664 { &hf_querykey_secdesc,
665 { "Secdesc", "reg.querykey.secdesc", FT_UINT32, BASE_DEC,
666 NULL, 0x0, "Secdesc", HFILL }},
668 { &hf_querykey_modtime,
669 { "Mod time", "reg.querykey.modtime", FT_ABSOLUTE_TIME, BASE_NONE,
670 NULL, 0x0, "Secdesc", HFILL }},
675 { "Key name", "reg.keyname", FT_STRING, BASE_NONE,
676 NULL, 0x0, "Keyname", HFILL }},
678 { &hf_openentry_unknown1,
679 { "Unknown 1", "reg.openentry.unknown1", FT_UINT32, BASE_HEX,
680 NULL, 0x0, "Unknown 1", HFILL }},
684 { &hf_unknown1A_unknown1,
685 { "Unknown 1", "reg.unknown1A.unknown1", FT_UINT32, BASE_HEX,
686 NULL, 0x0, "Unknown 1", HFILL }},
690 static gint *ett[] = {
694 proto_dcerpc_reg = proto_register_protocol(
695 "Microsoft Registry", "WINREG", "winreg");
697 proto_register_field_array(proto_dcerpc_reg, hf, array_length(hf));
699 proto_register_subtree_array(ett, array_length(ett));
703 proto_reg_handoff_dcerpc_reg(void)
705 /* Register protocol as dcerpc */
707 dcerpc_init_uuid(proto_dcerpc_reg, ett_dcerpc_reg, &uuid_dcerpc_reg,
708 ver_dcerpc_reg, dcerpc_reg_dissectors, hf_reg_opnum);