1 /* packet-dcerpc-svcctl.c
2 * Routines for SMB \PIPE\svcctl packet disassembly
3 * Copyright 2003, Tim Potter <tpot@samba.org>
4 * Copyright 2003, Ronnie Sahlberg, added function dissectors
5 * Copyright 2010, Brett Kuskie <fullaxx@gmail.com>
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * SPDX-License-Identifier: GPL-2.0-or-later
16 #include <epan/packet.h>
17 #include "packet-dcerpc.h"
18 #include "packet-dcerpc-svcctl.h"
19 #include "packet-dcerpc-nt.h"
20 #include "packet-windows-common.h"
22 void proto_register_dcerpc_svcctl(void);
23 void proto_reg_handoff_dcerpc_svcctl(void);
25 static int proto_dcerpc_svcctl = -1;
26 static int hf_svcctl_opnum = -1;
27 static int hf_svcctl_machinename = -1;
28 static int hf_svcctl_database = -1;
29 static int hf_svcctl_access_mask = -1;
30 static int hf_svcctl_scm_rights_connect = -1;
31 static int hf_svcctl_scm_rights_create_service = -1;
32 static int hf_svcctl_scm_rights_enumerate_service = -1;
33 static int hf_svcctl_scm_rights_lock = -1;
34 static int hf_svcctl_scm_rights_query_lock_status = -1;
35 static int hf_svcctl_scm_rights_modify_boot_config = -1;
36 static int hf_svcctl_hnd = -1;
37 static int hf_svcctl_lock = -1;
38 static int hf_svcctl_rc = -1;
39 static int hf_svcctl_size = -1;
40 static int hf_svcctl_required_size = -1;
41 static int hf_svcctl_is_locked = -1;
42 static int hf_svcctl_lock_duration = -1;
43 static int hf_svcctl_lock_owner = -1;
44 static int hf_svcctl_service_type = -1;
45 static int hf_svcctl_service_type_kernel_driver = -1;
46 static int hf_svcctl_service_type_fs_driver = -1;
47 static int hf_svcctl_service_type_win32_own_process = -1;
48 static int hf_svcctl_service_type_win32_share_process = -1;
49 static int hf_svcctl_service_type_interactive_process = -1;
50 static int hf_svcctl_service_state = -1;
51 static int hf_svcctl_buffer = -1;
52 /* static int hf_svcctl_bytes_needed = -1; */
53 /* static int hf_svcctl_services_returned = -1; */
54 static int hf_svcctl_resume = -1;
55 static int hf_svcctl_service_name = -1;
56 static int hf_svcctl_display_name = -1;
57 static int hf_svcctl_service_start_type = -1;
58 static int hf_svcctl_service_error_control = -1;
59 static int hf_svcctl_binarypathname = -1;
60 static int hf_svcctl_loadordergroup = -1;
61 static int hf_svcctl_tagid = -1;
62 static int hf_svcctl_dependencies = -1;
63 static int hf_svcctl_depend_size = -1;
64 static int hf_svcctl_service_start_name = -1;
65 static int hf_svcctl_password = -1;
66 static int hf_svcctl_password_size = -1;
68 static gint ett_dcerpc_svcctl = -1;
69 static gint ett_dcerpc_svcctl_service_type_bits = -1;
71 static e_guid_t uuid_dcerpc_svcctl = {
72 0x367abb81, 0x9844, 0x35f1,
73 { 0xad, 0x32, 0x98, 0xf0, 0x38, 0x00, 0x10, 0x03 }
76 static guint16 ver_dcerpc_svcctl = 2;
78 #define SVCCTL_SERVICE_TYPE_KERNEL_DRIVER 0x01
79 #define SVCCTL_SERVICE_TYPE_FILE_SYSTEM_DRIVER 0x02
80 #define SVCCTL_SERVICE_TYPE_WIN32_OWN_PROCESS 0x10
81 #define SVCCTL_SERVICE_TYPE_WIN32_SHARE_PROCESS 0x20
82 #define SVCCTL_SERVICE_TYPE_INTERACTIVE_PROCESS 0x100
83 #define SVCCTL_SERVICE_TYPE_NO_CHANGE 0xffffffff
84 static const true_false_string tfs_svcctl_service_type_kernel_driver = {
85 "Is a kernel driver service",
86 "Is not a kernel driver service"
88 static const true_false_string tfs_svcctl_service_type_fs_driver = {
89 "Is a file system driver service",
90 "Is not a file system driver service"
92 static const true_false_string tfs_svcctl_service_type_win32_own_process = {
93 "Service runs its own processes",
94 "Service does not run its own process"
96 static const true_false_string tfs_svcctl_service_type_win32_share_process = {
97 "Service shares its process",
98 "Service does not share its process"
100 static const true_false_string tfs_svcctl_service_type_interactive_process = {
101 "Service can interact with the desktop",
102 "Service cannot interact with the desktop"
106 svcctl_dissect_dwServiceType_flags(tvbuff_t *tvb, int offset,
107 packet_info *pinfo, proto_tree *parent_tree,
108 guint8 *drep, int opnum)
110 guint32 value, len = 4;
111 proto_item *item = NULL;
112 proto_tree *tree = NULL;
114 (void) dissect_dcerpc_uint32 (tvb, offset, pinfo, NULL, drep, 0, &value);
116 item = proto_tree_add_uint(parent_tree, hf_svcctl_service_type, tvb, offset, len, value);
117 tree = proto_item_add_subtree(item, ett_dcerpc_svcctl_service_type_bits);
121 case SVC_CREATE_SERVICE_W:
122 proto_tree_add_boolean(tree, hf_svcctl_service_type_interactive_process,
123 tvb, offset, len, value & SVCCTL_SERVICE_TYPE_INTERACTIVE_PROCESS);
124 proto_tree_add_boolean(tree, hf_svcctl_service_type_win32_share_process,
125 tvb, offset, len, value & SVCCTL_SERVICE_TYPE_WIN32_SHARE_PROCESS);
126 proto_tree_add_boolean(tree, hf_svcctl_service_type_win32_own_process,
127 tvb, offset, len, value & SVCCTL_SERVICE_TYPE_WIN32_OWN_PROCESS);
128 proto_tree_add_boolean(tree, hf_svcctl_service_type_fs_driver,
129 tvb, offset, len, value & SVCCTL_SERVICE_TYPE_FILE_SYSTEM_DRIVER);
130 proto_tree_add_boolean(tree, hf_svcctl_service_type_kernel_driver,
131 tvb, offset, len, value & SVCCTL_SERVICE_TYPE_KERNEL_DRIVER);
133 case SVC_ENUM_SERVICES_STATUS_W:
134 proto_tree_add_boolean(tree, hf_svcctl_service_type_win32_share_process,
135 tvb, offset, len, value & SVCCTL_SERVICE_TYPE_WIN32_SHARE_PROCESS);
136 proto_tree_add_boolean(tree, hf_svcctl_service_type_win32_own_process,
137 tvb, offset, len, value & SVCCTL_SERVICE_TYPE_WIN32_OWN_PROCESS);
138 proto_tree_add_boolean(tree, hf_svcctl_service_type_fs_driver,
139 tvb, offset, len, value & SVCCTL_SERVICE_TYPE_FILE_SYSTEM_DRIVER);
140 proto_tree_add_boolean(tree, hf_svcctl_service_type_kernel_driver,
141 tvb, offset, len, value & SVCCTL_SERVICE_TYPE_KERNEL_DRIVER);
143 case SVC_QUERY_SERVICE_CONFIG_W:
144 proto_tree_add_boolean(tree, hf_svcctl_service_type_win32_share_process,
145 tvb, offset, len, value & SVCCTL_SERVICE_TYPE_WIN32_SHARE_PROCESS);
146 proto_tree_add_boolean(tree, hf_svcctl_service_type_win32_own_process,
147 tvb, offset, len, value & SVCCTL_SERVICE_TYPE_WIN32_OWN_PROCESS);
148 proto_tree_add_boolean(tree, hf_svcctl_service_type_fs_driver,
149 tvb, offset, len, value & SVCCTL_SERVICE_TYPE_FILE_SYSTEM_DRIVER);
150 proto_tree_add_boolean(tree, hf_svcctl_service_type_kernel_driver,
151 tvb, offset, len, value & SVCCTL_SERVICE_TYPE_KERNEL_DRIVER);
159 #define SVCCTL_SERVICE_ACTIVE 0x01
160 #define SVCCTL_SERVICE_INACTIVE 0x02
161 #define SVCCTL_SERVICE_STATE_ALL 0x03
162 static const value_string svcctl_service_status_vals[] = {
163 { SVCCTL_SERVICE_ACTIVE, "SERVICE_ACTIVE" },
164 { SVCCTL_SERVICE_INACTIVE, "SERVICE_INACTIVE" },
165 { SVCCTL_SERVICE_STATE_ALL, "SERVICE_STATE_ALL" },
169 #define SVCCTL_SERVICE_BOOT_START 0x00
170 #define SVCCTL_SERVICE_SYSTEM_START 0x01
171 #define SVCCTL_SERVICE_AUTO_START 0x02
172 #define SVCCTL_SERVICE_DEMAND_START 0x03
173 #define SVCCTL_SERVICE_DISABLED 0x04
174 static const value_string svcctl_service_start_type_vals[] = {
175 { SVCCTL_SERVICE_BOOT_START, "SERVICE_BOOT_START" },
176 { SVCCTL_SERVICE_SYSTEM_START, "SERVICE_SYSTEM_START" },
177 { SVCCTL_SERVICE_AUTO_START, "SERVICE_AUTO_START" },
178 { SVCCTL_SERVICE_DEMAND_START, "SERVICE_DEMAND_START" },
179 { SVCCTL_SERVICE_DISABLED, "SERVICE_DISABLED" },
183 #define SVCCTL_SERVICE_ERROR_IGNORE 0x00
184 #define SVCCTL_SERVICE_ERROR_NORMAL 0x01
185 #define SVCCTL_SERVICE_ERROR_SEVERE 0x02
186 #define SVCCTL_SERVICE_ERROR_CRITICAL 0x03
187 static const value_string svcctl_service_error_control_vals[] = {
188 { SVCCTL_SERVICE_ERROR_IGNORE, "SERVICE_ERROR_IGNORE" },
189 { SVCCTL_SERVICE_ERROR_NORMAL, "SERVICE_ERROR_NORMAL" },
190 { SVCCTL_SERVICE_ERROR_SEVERE, "SERVICE_ERROR_SEVERE" },
191 { SVCCTL_SERVICE_ERROR_CRITICAL, "SERVICE_ERROR_CRITICAL" },
196 svcctl_dissect_pointer_long(tvbuff_t *tvb, int offset,
197 packet_info *pinfo, proto_tree *tree,
198 dcerpc_info *di, guint8 *drep)
200 offset = dissect_ndr_uint32 (tvb, offset, pinfo, tree, di, drep,
206 svcctl_scm_specific_rights(tvbuff_t *tvb, gint offset, proto_tree *tree,
209 proto_tree_add_boolean(tree, hf_svcctl_scm_rights_modify_boot_config, tvb, offset, 4, access);
210 proto_tree_add_boolean(tree, hf_svcctl_scm_rights_query_lock_status, tvb, offset, 4, access);
211 proto_tree_add_boolean(tree, hf_svcctl_scm_rights_lock, tvb, offset, 4, access);
212 proto_tree_add_boolean(tree, hf_svcctl_scm_rights_enumerate_service, tvb, offset, 4, access);
213 proto_tree_add_boolean(tree, hf_svcctl_scm_rights_create_service, tvb, offset, 4, access);
214 proto_tree_add_boolean(tree, hf_svcctl_scm_rights_connect, tvb, offset, 4, access);
217 struct access_mask_info svcctl_scm_access_mask_info = {
219 svcctl_scm_specific_rights,
220 NULL, /* Generic mapping table */
221 NULL /* Standard mapping table */
225 * IDL long OpenSCManager(
226 * IDL [in] [string] [unique] char *MachineName,
227 * IDL [in] [string] [unique] char *DatabaseName,
228 * IDL [in] long access_mask,
229 * IDL [out] SC_HANDLE handle,
233 svcctl_dissect_OpenSCManager_rqst(tvbuff_t *tvb, int offset,
234 packet_info *pinfo, proto_tree *tree,
235 dcerpc_info *di, guint8 *drep)
237 dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
241 dcv->private_data=NULL;
242 offset = dissect_ndr_pointer_cb(
243 tvb, offset, pinfo, tree, di, drep,
244 dissect_ndr_char_cvstring, NDR_POINTER_UNIQUE,
245 "MachineName", hf_svcctl_machinename, cb_str_postprocess,
246 GINT_TO_POINTER(CB_STR_COL_INFO | CB_STR_SAVE | 1));
247 mn=(const char *)dcv->private_data;
252 dcv->private_data=NULL;
253 offset = dissect_ndr_pointer_cb(
254 tvb, offset, pinfo, tree, di, drep,
255 dissect_ndr_char_cvstring, NDR_POINTER_UNIQUE,
256 "Database", hf_svcctl_database, cb_str_postprocess,
257 GINT_TO_POINTER(CB_STR_COL_INFO | 1));
258 dn=(const char *)dcv->private_data;
262 /* OpenSCManager() stores the server\database in se_data */
263 if(!pinfo->fd->visited){
265 dcv->se_data=wmem_strdup_printf(wmem_file_scope(), "%s\\%s",mn,dn);
270 offset = dissect_nt_access_mask(
271 tvb, offset, pinfo, tree, di, drep, hf_svcctl_access_mask,
272 &svcctl_scm_access_mask_info, NULL);
278 svcctl_dissect_OpenSCManager_reply(tvbuff_t *tvb, int offset,
279 packet_info *pinfo, proto_tree *tree,
280 dcerpc_info *di, guint8 *drep)
282 dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
283 e_ctx_hnd policy_hnd;
284 proto_item *hnd_item;
289 offset = dissect_nt_policy_hnd(
290 tvb, offset, pinfo, tree, di, drep, hf_svcctl_hnd, &policy_hnd,
291 &hnd_item, TRUE, FALSE);
293 offset = dissect_doserror(
294 tvb, offset, pinfo, tree, di, drep, hf_svcctl_rc, &status);
297 const char *pol_name;
300 pol_name = wmem_strdup_printf(wmem_packet_scope(),
301 "OpenSCManagerW(%s)", (char *)dcv->se_data);
303 pol_name = "Unknown OpenSCManagerW() handle";
305 if(!pinfo->fd->visited){
306 dcerpc_store_polhnd_name(&policy_hnd, pinfo, pol_name);
310 proto_item_append_text(hnd_item, ": %s", pol_name);
317 svcctl_dissect_OpenSCManagerW_rqst(tvbuff_t *tvb, int offset,
318 packet_info *pinfo, proto_tree *tree,
319 dcerpc_info *di, guint8 *drep)
321 dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
325 dcv->private_data=NULL;
326 offset = dissect_ndr_pointer_cb(
327 tvb, offset, pinfo, tree, di, drep,
328 dissect_ndr_wchar_cvstring, NDR_POINTER_UNIQUE,
329 "MachineName", hf_svcctl_machinename, cb_wstr_postprocess,
330 GINT_TO_POINTER(CB_STR_COL_INFO | CB_STR_SAVE | 1));
331 mn=(const char *)dcv->private_data;
336 dcv->private_data=NULL;
337 offset = dissect_ndr_pointer_cb(
338 tvb, offset, pinfo, tree, di, drep,
339 dissect_ndr_wchar_cvstring, NDR_POINTER_UNIQUE,
340 "Database", hf_svcctl_database, cb_wstr_postprocess,
341 GINT_TO_POINTER(CB_STR_COL_INFO | 1));
342 dn=(const char *)dcv->private_data;
346 /* OpenSCManager() stores the server\database in se_data */
347 if(!pinfo->fd->visited){
349 dcv->se_data=wmem_strdup_printf(wmem_file_scope(), "%s\\%s",mn,dn);
354 offset = dissect_nt_access_mask(
355 tvb, offset, pinfo, tree, di, drep, hf_svcctl_access_mask,
356 &svcctl_scm_access_mask_info, NULL);
362 svcctl_dissect_OpenSCManagerW_reply(tvbuff_t *tvb, int offset,
363 packet_info *pinfo, proto_tree *tree,
364 dcerpc_info *di, guint8 *drep)
366 dcerpc_call_value *dcv = (dcerpc_call_value *)di->call_data;
367 e_ctx_hnd policy_hnd;
368 proto_item *hnd_item;
373 offset = dissect_nt_policy_hnd(
374 tvb, offset, pinfo, tree, di, drep, hf_svcctl_hnd, &policy_hnd,
375 &hnd_item, TRUE, FALSE);
377 offset = dissect_doserror(
378 tvb, offset, pinfo, tree, di, drep, hf_svcctl_rc, &status);
381 const char *pol_name;
384 pol_name = wmem_strdup_printf(wmem_packet_scope(),
385 "OpenSCManagerW(%s)", (char *)dcv->se_data);
387 pol_name = "Unknown OpenSCManagerW() handle";
389 if(!pinfo->fd->visited){
390 dcerpc_store_polhnd_name(&policy_hnd, pinfo, pol_name);
394 proto_item_append_text(hnd_item, ": %s", pol_name);
401 svcctl_dissect_CreateServiceW_rqst(tvbuff_t *tvb, int offset,
402 packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
405 offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, di, drep,
406 hf_svcctl_hnd, NULL, NULL, FALSE, FALSE);
409 offset = dissect_ndr_cvstring(tvb, offset, pinfo, tree, di, drep,
410 sizeof(guint16), hf_svcctl_service_name, TRUE, NULL);
413 offset = dissect_ndr_pointer_cb(
414 tvb, offset, pinfo, tree, di, drep,
415 dissect_ndr_wchar_cvstring, NDR_POINTER_UNIQUE,
416 "Display Name", hf_svcctl_display_name, cb_wstr_postprocess,
420 offset = dissect_nt_access_mask(
421 tvb, offset, pinfo, tree, di, drep, hf_svcctl_access_mask,
422 &svcctl_scm_access_mask_info, NULL);
425 offset = svcctl_dissect_dwServiceType_flags(tvb, offset, pinfo, tree, drep, SVC_CREATE_SERVICE_W);
427 /* service start type */
428 offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
429 hf_svcctl_service_start_type, NULL);
431 /* service error control */
432 offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
433 hf_svcctl_service_error_control, NULL);
435 /* binary path name */
436 offset = dissect_ndr_cvstring(tvb, offset, pinfo, tree, di, drep,
437 sizeof(guint16), hf_svcctl_binarypathname, TRUE, NULL);
439 /* load order group */
440 offset = dissect_ndr_pointer_cb(
441 tvb, offset, pinfo, tree, di, drep,
442 dissect_ndr_wchar_cvstring, NDR_POINTER_UNIQUE,
443 "Load Order Group", hf_svcctl_loadordergroup, cb_wstr_postprocess,
447 offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
448 hf_svcctl_tagid, NULL);
451 offset = dissect_ndr_pointer_cb(
452 tvb, offset, pinfo, tree, di, drep,
453 dissect_ndr_wchar_cvstring, NDR_POINTER_UNIQUE,
454 "Dependencies", hf_svcctl_dependencies, cb_wstr_postprocess,
458 offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
459 hf_svcctl_depend_size, NULL);
461 /* service start name */
462 offset = dissect_ndr_pointer_cb(
463 tvb, offset, pinfo, tree, di, drep,
464 dissect_ndr_wchar_cvstring, NDR_POINTER_UNIQUE,
465 "Service Start Name", hf_svcctl_service_start_name, cb_wstr_postprocess,
469 offset = dissect_ndr_pointer_cb(
470 tvb, offset, pinfo, tree, di, drep,
471 dissect_ndr_wchar_cvstring, NDR_POINTER_UNIQUE,
472 "Password", hf_svcctl_password, cb_wstr_postprocess,
476 offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
477 hf_svcctl_password_size, NULL);
483 svcctl_dissect_CreateServiceW_reply(tvbuff_t *tvb, int offset,
484 packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
487 offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
488 hf_svcctl_tagid, NULL);
491 offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, di, drep,
492 hf_svcctl_hnd, NULL, NULL, FALSE, FALSE);
494 offset = dissect_doserror(
495 tvb, offset, pinfo, tree, di, drep, hf_svcctl_rc, NULL);
502 * IDL BOOL CloseServiceHandle(
503 * IDL [in][out] SC_HANDLE handle
507 svcctl_dissect_CloseServiceHandle_rqst(tvbuff_t *tvb, int offset,
508 packet_info *pinfo, proto_tree *tree,
509 dcerpc_info *di, guint8 *drep)
511 e_ctx_hnd policy_hnd;
516 offset = dissect_nt_policy_hnd(
517 tvb, offset, pinfo, tree, di, drep, hf_svcctl_hnd, &policy_hnd,
520 dcerpc_fetch_polhnd_data(&policy_hnd, &pol_name, NULL, NULL, NULL,
523 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
530 svcctl_dissect_CloseServiceHandle_reply(tvbuff_t *tvb, int offset,
531 packet_info *pinfo, proto_tree *tree,
532 dcerpc_info *di, guint8 *drep)
534 offset = dissect_nt_policy_hnd(
535 tvb, offset, pinfo, tree, di, drep, hf_svcctl_hnd, NULL,
538 offset = dissect_doserror(
539 tvb, offset, pinfo, tree, di, drep, hf_svcctl_rc, NULL);
547 * IDL long LockServiceDatabase(
548 * IDL [in] SC_HANDLE dbhandle,
549 * IDL [out] SC_HANDLE lock,
553 svcctl_dissect_LockServiceDatabase_rqst(tvbuff_t *tvb, int offset,
554 packet_info *pinfo, proto_tree *tree,
555 dcerpc_info *di, guint8 *drep)
557 /* XXX - why is the "is a close" argument TRUE? */
558 offset = dissect_nt_policy_hnd(
559 tvb, offset, pinfo, tree, di, drep, hf_svcctl_hnd, NULL,
565 svcctl_dissect_LockServiceDatabase_reply(tvbuff_t *tvb, int offset,
566 packet_info *pinfo, proto_tree *tree,
567 dcerpc_info *di, guint8 *drep)
569 /* XXX - why is the "is an open" argument TRUE? */
570 offset = dissect_nt_policy_hnd(
571 tvb, offset, pinfo, tree, di, drep, hf_svcctl_lock, NULL,
574 offset = dissect_doserror(
575 tvb, offset, pinfo, tree, di, drep, hf_svcctl_rc, NULL);
583 * IDL long UnlockServiceDatabase(
584 * IDL [in][out] SC_HANDLE lock,
588 svcctl_dissect_UnlockServiceDatabase_rqst(tvbuff_t *tvb, int offset,
589 packet_info *pinfo, proto_tree *tree,
590 dcerpc_info *di, guint8 *drep)
592 /* XXX - why is the "is a close" argument TRUE? */
593 offset = dissect_nt_policy_hnd(
594 tvb, offset, pinfo, tree, di, drep, hf_svcctl_lock, NULL,
600 svcctl_dissect_UnlockServiceDatabase_reply(tvbuff_t *tvb, int offset,
601 packet_info *pinfo, proto_tree *tree,
602 dcerpc_info *di, guint8 *drep)
604 /* XXX - why is the "is an open" argument TRUE? */
605 offset = dissect_nt_policy_hnd(
606 tvb, offset, pinfo, tree, di, drep, hf_svcctl_lock, NULL,
609 offset = dissect_doserror(
610 tvb, offset, pinfo, tree, di, drep, hf_svcctl_rc, NULL);
617 * IDL typedef struct {
618 * IDL long is_locked,
619 * IDL [unique][string] char *lock_owner,
620 * IDL long lock_duration,
624 svcctl_dissect_QUERY_SERVICE_LOCK_STATUS(tvbuff_t *tvb, int offset,
625 packet_info *pinfo, proto_tree *tree,
626 dcerpc_info *di, guint8 *drep)
628 offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
629 hf_svcctl_is_locked, NULL);
631 offset = dissect_ndr_pointer(
632 tvb, offset, pinfo, tree, di, drep,
633 dissect_ndr_char_cvstring, NDR_POINTER_UNIQUE,
634 "Owner", hf_svcctl_lock_owner);
636 offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
637 hf_svcctl_lock_duration, NULL);
643 * IDL long QueryServiceLockStatus(
644 * IDL [in] SC_HANDLE db_handle,
645 * IDL [in] long buf_size,
646 * IDL [out][ref] QUERY_SERVICE_LOCK_STATUS *status,
647 * IDL [out][ref] long *required_buf_size
651 svcctl_dissect_QueryServiceLockStatus_rqst(tvbuff_t *tvb, int offset,
652 packet_info *pinfo, proto_tree *tree,
653 dcerpc_info *di, guint8 *drep)
655 /* XXX - why is the "is a close" argument TRUE? */
656 offset = dissect_nt_policy_hnd(
657 tvb, offset, pinfo, tree, di, drep, hf_svcctl_hnd, NULL,
660 offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
661 hf_svcctl_size, NULL);
666 svcctl_dissect_QueryServiceLockStatus_reply(tvbuff_t *tvb, int offset,
667 packet_info *pinfo, proto_tree *tree,
668 dcerpc_info *di, guint8 *drep)
670 offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
671 svcctl_dissect_QUERY_SERVICE_LOCK_STATUS, NDR_POINTER_REF,
674 offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
675 hf_svcctl_required_size, NULL);
677 offset = dissect_doserror(
678 tvb, offset, pinfo, tree, di, drep, hf_svcctl_rc, NULL);
684 * IDL long EnumServicesStatus(
685 * IDL [in] SC_HANDLE db_handle,
686 * IDL [in] long type,
687 * IDL [in] long status,
688 * IDL [in] long buf_size,
689 * IDL [in][unique] long *resume_handle,
694 svcctl_dissect_EnumServicesStatus_rqst(tvbuff_t *tvb, int offset,
695 packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
698 offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, di, drep,
699 hf_svcctl_hnd, NULL, NULL, FALSE, FALSE);
702 offset = svcctl_dissect_dwServiceType_flags(tvb, offset, pinfo, tree, drep, SVC_ENUM_SERVICES_STATUS_W);
705 offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
706 hf_svcctl_service_state, NULL);
709 offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
710 hf_svcctl_size, NULL);
713 offset = dissect_ndr_pointer(tvb, offset, pinfo, tree, di, drep,
714 svcctl_dissect_pointer_long, NDR_POINTER_UNIQUE,
715 "Resume Handle", hf_svcctl_resume);
721 svcctl_dissect_OpenServiceW_rqst(tvbuff_t *tvb, int offset,
722 packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
725 offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, di, drep,
726 hf_svcctl_hnd, NULL, NULL, FALSE, FALSE);
729 offset = dissect_ndr_cvstring(tvb, offset, pinfo, tree, di, drep,
730 sizeof(guint16), hf_svcctl_service_name, TRUE, NULL);
733 offset = dissect_nt_access_mask(
734 tvb, offset, pinfo, tree, di, drep, hf_svcctl_access_mask,
735 &svcctl_scm_access_mask_info, NULL);
741 svcctl_dissect_OpenServiceW_reply(tvbuff_t *tvb, int offset,
742 packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
745 offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, di, drep,
746 hf_svcctl_hnd, NULL, NULL, FALSE, FALSE);
748 offset = dissect_doserror(
749 tvb, offset, pinfo, tree, di, drep, hf_svcctl_rc, NULL);
755 svcctl_dissect_QueryServiceConfigW_rqst(tvbuff_t *tvb, int offset,
756 packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep)
759 offset = dissect_nt_policy_hnd(tvb, offset, pinfo, tree, di, drep,
760 hf_svcctl_hnd, NULL, NULL, FALSE, FALSE);
763 offset = dissect_ndr_uint32(tvb, offset, pinfo, tree, di, drep,
764 hf_svcctl_buffer, NULL);
769 static dcerpc_sub_dissector dcerpc_svcctl_dissectors[] = {
770 { SVC_CLOSE_SERVICE_HANDLE, "CloseServiceHandle",
771 svcctl_dissect_CloseServiceHandle_rqst,
772 svcctl_dissect_CloseServiceHandle_reply },
773 { SVC_CONTROL_SERVICE, "ControlService", NULL, NULL },
774 { SVC_DELETE_SERVICE, "DeleteService", NULL, NULL },
775 { SVC_LOCK_SERVICE_DATABASE, "LockServiceDatabase",
776 svcctl_dissect_LockServiceDatabase_rqst,
777 svcctl_dissect_LockServiceDatabase_reply },
778 { SVC_QUERY_SERVICE_OBJECT_SECURITY, "QueryServiceObjectSecurity",
780 { SVC_SET_SERVICE_OBJECT_SECURITY, "SetServiceObjectSecurity",
782 { SVC_QUERY_SERVICE_STATUS, "QueryServiceStatus",
784 { SVC_SET_SERVICE_STATUS, "SetServiceStatus",
786 { SVC_UNLOCK_SERVICE_DATABASE, "UnlockServiceDatabase",
787 svcctl_dissect_UnlockServiceDatabase_rqst,
788 svcctl_dissect_UnlockServiceDatabase_reply },
789 { SVC_NOTIFY_BOOT_CONFIG_STATUS, "NotifyBootConfigStatus",
791 { SVC_SC_SET_SERVICE_BITS_W, "ScSetServiceBitsW",
793 { SVC_CHANGE_SERVICE_CONFIG_W, "ChangeServiceConfigW",
795 { SVC_CREATE_SERVICE_W, "CreateServiceW",
796 svcctl_dissect_CreateServiceW_rqst,
797 svcctl_dissect_CreateServiceW_reply },
798 { SVC_ENUM_DEPENDENT_SERVICES_W, "EnumDependentServicesW",
800 { SVC_ENUM_SERVICES_STATUS_W, "EnumServicesStatusW",
801 svcctl_dissect_EnumServicesStatus_rqst, NULL },
802 { SVC_OPEN_SC_MANAGER_W, "OpenSCManagerW",
803 svcctl_dissect_OpenSCManagerW_rqst,
804 svcctl_dissect_OpenSCManagerW_reply },
805 { SVC_OPEN_SERVICE_W, "OpenServiceW",
806 svcctl_dissect_OpenServiceW_rqst,
807 svcctl_dissect_OpenServiceW_reply },
808 { SVC_QUERY_SERVICE_CONFIG_W, "QueryServiceConfigW",
809 svcctl_dissect_QueryServiceConfigW_rqst, NULL },
810 { SVC_QUERY_SERVICE_LOCK_STATUS_W, "QueryServiceLockStatusW",
812 { SVC_START_SERVICE_W, "StartServiceW", NULL, NULL },
813 { SVC_GET_SERVICE_DISPLAY_NAME_W, "GetServiceDisplayNameW",
815 { SVC_GET_SERVICE_KEY_NAME_W, "GetServiceKeyNameW", NULL, NULL },
816 { SVC_SC_SET_SERVICE_BITS_A, "ScSetServiceBitsA", NULL, NULL },
817 { SVC_CHANGE_SERVICE_CONFIG_A, "ChangeServiceConfigA", NULL, NULL },
818 { SVC_CREATE_SERVICE_A, "CreateServiceA", NULL, NULL },
819 { SVC_ENUM_DEPENDENT_SERVICES_A, "EnumDependentServicesA",
821 { SVC_ENUM_SERVICES_STATUS_A, "EnumServicesStatusA",
822 svcctl_dissect_EnumServicesStatus_rqst,
824 { SVC_OPEN_SC_MANAGER_A, "OpenSCManagerA",
825 svcctl_dissect_OpenSCManager_rqst,
826 svcctl_dissect_OpenSCManager_reply },
827 { SVC_OPEN_SERVICE_A, "OpenServiceA", NULL, NULL },
828 { SVC_QUERY_SERVICE_CONFIG_A, "QueryServiceConfigA", NULL, NULL },
829 { SVC_QUERY_SERVICE_LOCK_STATUS_A, "QueryServiceLockStatusA",
830 svcctl_dissect_QueryServiceLockStatus_rqst,
831 svcctl_dissect_QueryServiceLockStatus_reply },
832 { SVC_START_SERVICE_A, "StartServiceA", NULL, NULL },
833 { SVC_GET_SERVICE_DISPLAY_NAME_A, "GetServiceDisplayNameA",
835 { SVC_GET_SERVICE_KEY_NAME_A, "GetServiceKeyNameA", NULL, NULL },
836 { SVC_SC_GET_CURRENT_GROUPE_STATE_W, "ScGetCurrentGroupStateW",
838 { SVC_ENUM_SERVICE_GROUP_W, "EnumServiceGroupW",
840 { SVC_CHANGE_SERVICE_CONFIG2_A, "ChangeServiceConfig2A",
842 { SVC_CHANGE_SERVICE_CONFIG2_W, "ChangeServiceConfig2W",
844 { SVC_QUERY_SERVICE_CONFIG2_A, "QueryServiceConfig2A",
846 { SVC_QUERY_SERVICE_CONFIG2_W, "QueryServiceConfig2W",
848 { SVC_QUERY_SERVICE_STATUS_EX, "QueryServiceStatusEx",
850 { SVC_ENUM_SERVICES_STATUS_EX_A, "EnumServicesStatusExA",
852 { SVC_ENUM_SERVICES_STATUS_EX_W, "EnumServicesStatusExW",
854 { SVC_SC_SEND_TS_MESSAGE, "ScSendTSMessage",
856 {0, NULL, NULL, NULL}
860 proto_register_dcerpc_svcctl(void)
862 static hf_register_info hf[] = {
864 { "Operation", "svcctl.opnum", FT_UINT16, BASE_DEC,
865 NULL, 0x0, NULL, HFILL }},
866 { &hf_svcctl_machinename,
867 { "MachineName", "svcctl.machinename", FT_STRING, BASE_NONE,
868 NULL, 0x0, "Name of the host we want to open the database on", HFILL }},
869 { &hf_svcctl_database,
870 { "Database", "svcctl.database", FT_STRING, BASE_NONE,
871 NULL, 0x0, "Name of the database to open", HFILL }},
872 { &hf_svcctl_access_mask,
873 { "Access Mask", "svcctl.access_mask", FT_UINT32, BASE_HEX,
874 NULL, 0x0, "SVCCTL Access Mask", HFILL }},
875 { &hf_svcctl_scm_rights_connect,
876 { "Connect", "svcctl.scm_rights_connect", FT_BOOLEAN, 32,
877 TFS(&tfs_set_notset), 0x00000001, "SVCCTL Rights to connect to SCM", HFILL }},
878 { &hf_svcctl_scm_rights_create_service,
879 { "Create Service", "svcctl.scm_rights_create_service", FT_BOOLEAN, 32,
880 TFS(&tfs_set_notset), 0x00000002, "SVCCTL Rights to create services", HFILL }},
881 { &hf_svcctl_scm_rights_enumerate_service,
882 { "Enumerate Service", "svcctl.scm_rights_enumerate_service", FT_BOOLEAN, 32,
883 TFS(&tfs_set_notset), 0x00000004, "SVCCTL Rights to enumerate services", HFILL }},
884 { &hf_svcctl_scm_rights_lock,
885 { "Lock", "svcctl.scm_rights_lock", FT_BOOLEAN, 32,
886 TFS(&tfs_set_notset), 0x00000008, "SVCCTL Rights to lock database", HFILL }},
887 { &hf_svcctl_scm_rights_query_lock_status,
888 { "Query Lock Status", "svcctl.scm_rights_query_lock_status", FT_BOOLEAN, 32,
889 TFS(&tfs_set_notset), 0x00000010, "SVCCTL Rights to query database lock status", HFILL }},
890 { &hf_svcctl_scm_rights_modify_boot_config,
891 { "Modify Boot Config", "svcctl.scm_rights_modify_boot_config", FT_BOOLEAN, 32,
892 TFS(&tfs_set_notset), 0x00000020, "SVCCTL Rights to modify boot config", HFILL }},
894 { "Context Handle", "svcctl.hnd", FT_BYTES, BASE_NONE,
895 NULL, 0x0, "SVCCTL Context handle", HFILL }},
897 { "Lock", "svcctl.lock", FT_BYTES, BASE_NONE,
898 NULL, 0x0, "SVCCTL Database Lock", HFILL }},
900 { "Return code", "svcctl.rc", FT_UINT32, BASE_HEX | BASE_EXT_STRING,
901 &DOS_errors_ext, 0x0, "SVCCTL return code", HFILL }},
903 { "Size", "svcctl.size", FT_UINT32, BASE_DEC,
904 NULL, 0x0, "SVCCTL size of buffer", HFILL }},
905 { &hf_svcctl_required_size,
906 { "Required Size", "svcctl.required_size", FT_UINT32, BASE_DEC,
907 NULL, 0x0, "SVCCTL required size of buffer for data to fit", HFILL }},
908 { &hf_svcctl_is_locked,
909 { "IsLocked", "svcctl.is_locked", FT_UINT32, BASE_DEC,
910 NULL, 0x0, "SVCCTL whether the database is locked or not", HFILL }},
911 { &hf_svcctl_lock_duration,
912 { "Duration", "svcctl.lock_duration", FT_UINT32, BASE_DEC,
913 NULL, 0x0, "SVCCTL number of seconds the database has been locked", HFILL }},
914 { &hf_svcctl_lock_owner,
915 { "Owner", "svcctl.lock_owner", FT_STRING, BASE_NONE,
916 NULL, 0x0, "SVCCTL the user that holds the database lock", HFILL }},
917 { &hf_svcctl_service_type,
918 { "Service Type", "svcctl.service_type", FT_UINT32, BASE_HEX,
919 NULL, 0x0, "SVCCTL type of service", HFILL }},
920 { &hf_svcctl_service_type_kernel_driver,
921 { "Kernel Driver Service", "svcctl.service_type.kernel", FT_BOOLEAN, 32,
922 TFS(&tfs_svcctl_service_type_kernel_driver), SVCCTL_SERVICE_TYPE_KERNEL_DRIVER, "Request includes kernel driver services?", HFILL }},
923 { &hf_svcctl_service_type_fs_driver,
924 { "File System Driver Service", "svcctl.service_type.fs", FT_BOOLEAN, 32,
925 TFS(&tfs_svcctl_service_type_fs_driver), SVCCTL_SERVICE_TYPE_FILE_SYSTEM_DRIVER, "Request includes file system driver services?", HFILL }},
926 { &hf_svcctl_service_type_win32_own_process,
927 { "Self Process Service", "svcctl.service_type.win32_own", FT_BOOLEAN, 32,
928 TFS(&tfs_svcctl_service_type_win32_own_process), SVCCTL_SERVICE_TYPE_WIN32_OWN_PROCESS, "Request includes services that run their own process?", HFILL }},
929 { &hf_svcctl_service_type_win32_share_process,
930 { "Shared Process Service", "svcctl.service_type.win32_shared", FT_BOOLEAN, 32,
931 TFS(&tfs_svcctl_service_type_win32_share_process), SVCCTL_SERVICE_TYPE_WIN32_SHARE_PROCESS, "Request includes services that share their process?", HFILL }},
932 { &hf_svcctl_service_type_interactive_process,
933 { "Interactive Process Service", "svcctl.service_type.interactive", FT_BOOLEAN, 32,
934 TFS(&tfs_svcctl_service_type_interactive_process), SVCCTL_SERVICE_TYPE_INTERACTIVE_PROCESS, "Request includes services that can interact with the desktop?", HFILL }},
935 { &hf_svcctl_service_state,
936 { "Service State", "svcctl.service_state", FT_UINT32, BASE_DEC,
937 VALS(svcctl_service_status_vals), 0x0, "SVCCTL service state", HFILL }},
939 { "Buffer", "svcctl.buffer", FT_UINT32, BASE_DEC,
940 NULL, 0x0, "SVCCTL buffer", HFILL }},
942 { &hf_svcctl_bytes_needed,
943 { "Bytes Needed", "svcctl.bytes_needed", FT_UINT32, BASE_DEC,
944 NULL, 0x0, "SVCCTL bytes needed", HFILL }},
945 { &hf_svcctl_services_returned,
946 { "Services Returned", "svcctl.services_returned", FT_UINT32, BASE_DEC,
947 NULL, 0x0, "SVCCTL services returned", HFILL }},
949 { &hf_svcctl_service_name,
950 { "Service Name", "svcctl.servicename", FT_STRING, BASE_NONE,
951 NULL, 0x0, "SVCCTL name of service", HFILL }},
952 { &hf_svcctl_display_name,
953 { "Display Name", "svcctl.displayname", FT_STRING, BASE_NONE,
954 NULL, 0x0, "SVCCTL display name", HFILL }},
955 { &hf_svcctl_service_start_type,
956 { "Service Start Type", "svcctl.service_start_type", FT_UINT32, BASE_DEC,
957 VALS(svcctl_service_start_type_vals), 0x0, "SVCCTL service start type", HFILL }},
958 { &hf_svcctl_service_error_control,
959 { "Service Error Control", "svcctl.service_error_control", FT_UINT32, BASE_DEC,
960 VALS(svcctl_service_error_control_vals), 0x0, "SVCCTL service error control", HFILL }},
961 { &hf_svcctl_binarypathname,
962 { "Binary Path Name", "svcctl.binarypathname", FT_STRING, BASE_NONE,
963 NULL, 0x0, "SVCCTL binary path name", HFILL }},
964 { &hf_svcctl_loadordergroup,
965 { "Load Order Group", "svcctl.loadordergroup", FT_STRING, BASE_NONE,
966 NULL, 0x0, "SVCCTL load order group", HFILL }},
968 { "Tag Id", "svcctl.tagid", FT_UINT32, BASE_DEC,
969 NULL, 0x0, "SVCCTL tag id", HFILL }},
970 { &hf_svcctl_dependencies,
971 { "Dependencies", "svcctl.dependencies", FT_STRING, BASE_NONE,
972 NULL, 0x0, "SVCCTL dependencies", HFILL }},
973 { &hf_svcctl_depend_size,
974 { "Depend Size", "svcctl.depend_size", FT_UINT32, BASE_DEC,
975 NULL, 0x0, "SVCCTL depend size", HFILL }},
976 { &hf_svcctl_service_start_name,
977 { "Service Start Name", "svcctl.service_start_name", FT_STRING, BASE_NONE,
978 NULL, 0x0, "SVCCTL service start name", HFILL }},
979 { &hf_svcctl_password,
980 { "Password", "svcctl.password", FT_STRING, BASE_NONE,
981 NULL, 0x0, "SVCCTL password", HFILL }},
982 { &hf_svcctl_password_size,
983 { "Password Size", "svcctl.password_size", FT_UINT32, BASE_DEC,
984 NULL, 0x0, "SVCCTL password size", HFILL }},
986 { "Resume Handle", "svcctl.resume", FT_UINT32, BASE_DEC,
987 NULL, 0x0, "SVCCTL resume handle", HFILL }},
990 static gint *ett[] = {
992 &ett_dcerpc_svcctl_service_type_bits,
995 proto_dcerpc_svcctl = proto_register_protocol(
996 "Microsoft Service Control", "SVCCTL", "svcctl");
998 proto_register_field_array(proto_dcerpc_svcctl, hf, array_length(hf));
999 proto_register_subtree_array(ett, array_length(ett));
1003 proto_reg_handoff_dcerpc_svcctl(void)
1005 /* Register protocol as dcerpc */
1007 dcerpc_init_uuid(proto_dcerpc_svcctl, ett_dcerpc_svcctl,
1008 &uuid_dcerpc_svcctl, ver_dcerpc_svcctl,
1009 dcerpc_svcctl_dissectors, hf_svcctl_opnum);
1013 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1018 * indent-tabs-mode: t
1021 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
1022 * :indentSize=8:tabSize=8:noTabs=false: