1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 from rekall import plugin
23 from rekall import obj
24 from rekall.plugins.windows import common
25 from rekall.plugins.windows import vadinfo
26 from rekall_lib import utils
27
28
29 SERVICE_TYPE_FLAGS = {
30 'SERVICE_KERNEL_DRIVER': 0,
31 'SERVICE_FILE_SYSTEM_DRIVER': 1,
32 'SERVICE_WIN32_OWN_PROCESS': 4,
33 'SERVICE_WIN32_SHARE_PROCESS': 5,
34 'SERVICE_INTERACTIVE_PROCESS': 8
35 }
36
37 SERVICE_STATE_ENUM = {
38 1: 'SERVICE_STOPPED',
39 2: 'SERVICE_START_PENDING',
40 3: 'SERVICE_STOP_PENDING',
41 4: 'SERVICE_RUNNING',
42 5: 'SERVICE_CONTINUE_PENDING',
43 6: 'SERVICE_PAUSE_PENDING',
44 7: 'SERVICE_PAUSED'
45 }
46
47 svcscan_base_x86 = {
48 '_SERVICE_HEADER': [None, {
49 'Tag': [0x0, ['array', 4, ['unsigned char']]],
50 'ServiceRecord': [0xC, ['pointer', ['_SERVICE_RECORD']]],
51 }],
52
53 '_SERVICE_RECORD': [None, {
54 'NextService': [0x0, ['_SERVICE_HEADER']],
55 'ServiceName': [0x8, ['pointer', ['UnicodeString', dict(length=512)]]],
56 'DisplayName': [0xc, ['pointer', ['UnicodeString', dict(length=512)]]],
57 'Order': [0x10, ['unsigned int']],
58 'Tag': [0x18, ['array', 4, ['unsigned char']]],
59 'DriverName': [0x24, ['pointer', ['UnicodeString', dict(
60 length=256)]]],
61 'ServiceProcess': [0x24, ['pointer', ['_SERVICE_PROCESS']]],
62 'Type': [0x28, ['Flags', {'bitmap': SERVICE_TYPE_FLAGS}]],
63 'State': [0x2c, ['Enumeration', dict(target='long',
64 choices=SERVICE_STATE_ENUM)]],
65 }],
66
67 '_SERVICE_PROCESS': [None, {
68 'BinaryPath': [0x8, ['pointer', ['UnicodeString', dict(
69 encoding='utf16', length=256)]]],
70 'ProcessId': [0xc, ['unsigned int']],
71 }],
72 }
73
74 svcscan_base_x64 = {
75 '_SERVICE_HEADER': [None, {
76 'Tag': [0x0, ['Array', dict(
77 count=4,
78 target='unsigned char'
79 )]],
80 'ServiceRecord': [0x10, ['Pointer', dict(
81 target='_SERVICE_RECORD'
82 )]],
83 }],
84
85 '_SERVICE_RECORD': [None, {
86 'NextService': [0x0, ['Pointer', dict(
87 target="_SERVICE_RECORD"
88 )]],
89 'ServiceName': [0x8, ['pointer', ['UnicodeString', dict(
90 encoding='utf16', length=512)]]],
91
92 'DisplayName': [0x10, ['Pointer', dict(
93 target='UnicodeString',
94 target_args=dict(length=512)
95 )]],
96 'Order': [0x18, ['unsigned int']],
97 'Tag' : [0x20, ['Array', dict(
98 count=4,
99 target='unsigned char'
100 )]],
101 'DriverName': [0x30, ['Pointer', dict(
102 target='UnicodeString',
103 target_args=dict(
104 length=256
105 )
106 )]],
107 'ServiceProcess': [0x30, ['Pointer', dict(
108 target='_SERVICE_PROCESS'
109 )]],
110 'Type': [0x38, ['Flags', {'bitmap': SERVICE_TYPE_FLAGS}]],
111 'State': [0x3C, ['Enumeration', dict(
112 target='long', choices=SERVICE_STATE_ENUM)]],
113 }],
114
115 '_SERVICE_PROCESS': [None, {
116 'BinaryPath': [0x10, ['Pointer', dict(
117 target='UnicodeString',
118 target_args=dict(
119 length=256
120 )
121 )]],
122 'ProcessId': [0x18, ['unsigned int']],
123 }],
124 }
128 "Service records for XP/2003 x86 and x64"
129
130 @utils.safe_property
132 "Return the binary path for a service"
133
134
135
136 if str(self.State) != 'SERVICE_RUNNING':
137 return obj.NoneObject("No path, service isn't running")
138
139
140
141 if 'PROCESS' in str(self.Type):
142 return self.ServiceProcess.BinaryPath.dereference()
143 else:
144 return self.DriverName.dereference()
145
146 @utils.safe_property
148 "Return the process ID for a service"
149
150 if str(self.State) == 'SERVICE_RUNNING':
151 if 'PROCESS' in str(self.Type):
152 return self.ServiceProcess.ProcessId
153
154 return obj.NoneObject("Cannot get process ID")
155
157 "Check some fields for validity"
158 return (super(_SERVICE_RECORD_LEGACY, self).is_valid() and
159 self.Order > 0 and self.Order < 0xFFFF)
160
163 "Service records for 2008, Vista, 7 x86 and x64"
164
167 "Service headers for 2008, Vista, 7 x86 and x64"
168
170 "Check some fields for validity"
171 return (super(_SERVICE_HEADER, self).is_valid() and
172 self.ServiceRecord.is_valid())
173
174
175 _SERVICE_RECORD_VISTA_X86 = {
176 '_SERVICE_RECORD': [None, {
177 'NextService': [0x0, ['pointer', ['_SERVICE_RECORD']]],
178 'ServiceName': [0x4, ['pointer', ['UnicodeString', dict(length=512)]]],
179 'DisplayName': [0x8, ['pointer', ['UnicodeString', dict(length=512)]]],
180 'Order': [0xC, ['unsigned int']],
181 'ServiceProcess': [0x1C, ['pointer', ['_SERVICE_PROCESS']]],
182 'DriverName': [0x1C, ['pointer', ['UnicodeString', dict(
183 length=256)]]],
184 'Type' : [0x20, ['Flags', {'bitmap': SERVICE_TYPE_FLAGS}]],
185 'State': [0x24, ['Enumeration', dict(
186 target='unsigned int', choices=SERVICE_STATE_ENUM)]],
187 }],
188 }
189
190
191 _SERVICE_RECORD_VISTA_X64 = {
192 '_SERVICE_RECORD': [None, {
193 'NextService': [0x00, ['Pointer', dict(
194 target='_SERVICE_RECORD'
195 )]],
196
197 'ServiceName': [0x08, ['pointer', ['UnicodeString', dict(
198 length=512
199 )]]],
200 'DisplayName': [0x10, ['pointer', ['UnicodeString', dict(
201 length=512
202 )]]],
203 'Order': [0x18, ['unsigned int']],
204 'ServiceProcess': [0x28, ['pointer', ['_SERVICE_PROCESS']]],
205 'DriverName': [0x28, ['Pointer', dict(
206 target='UnicodeString',
207 target_args=dict(
208 length=256,
209 )
210 )]],
211
212 'Type' : [0x30, ['Flags', {'bitmap': SERVICE_TYPE_FLAGS}]],
213 'State': [0x34, ['Enumeration', dict(
214 target='unsigned int',
215 choices=SERVICE_STATE_ENUM
216 )]],
217 }],
218 }
219
220
221 _SERVICE_RECORD_WIN81_X64 = {
222 "_SERVICE_RECORD": [None, {
223 "Tag": [0, ["String", dict(length=4)]],
224 'NextService': [0x8, ['Pointer', dict(
225 target='_SERVICE_RECORD'
226 )]],
227
228 'ServiceName': [0x10, ['pointer', ['UnicodeString', dict(
229 length=512
230 )]]],
231 'DisplayName': [0x18, ['pointer', ['UnicodeString', dict(
232 length=512
233 )]]],
234 'Order': [0x20, ['unsigned int']],
235 'ServiceProcess': [0x38, ['pointer', ['_SERVICE_PROCESS']]],
236 'DriverName': [0x38, ['Pointer', dict(
237 target='UnicodeString',
238 target_args=dict(
239 length=256,
240 )
241 )]],
242
243 'Type' : [0x40, ['Flags', {'bitmap': SERVICE_TYPE_FLAGS}]],
244 'State': [0x44, ['Enumeration', dict(
245 target='unsigned int',
246 choices=SERVICE_STATE_ENUM
247 )]],
248 }],
249
250 '_SERVICE_PROCESS': [None, {
251 'Tag': [0, ["String", dict(length=4)]],
252 'BinaryPath': [0x18, ['Pointer', dict(
253 target='UnicodeString',
254 target_args=dict(
255 length=256
256 )
257 )]],
258 'ProcessId': [0x20, ['unsigned int']],
259 }],
260 }
264 """A modification for the service control manager."""
265
266 @classmethod
312
316 """A scanner for the service tags."""
317
325
326 - def scan(self, **kwargs):
333
336 """A scanner for the service tags."""
337
350
362
363
364 -class SvcScan(plugin.KernelASMixin, common.AbstractWindowsCommandPlugin):
365 "Scan for Windows services"
366
367 __name = "svcscan"
368
369 - def __init__(self, scan_in_kernel_address_space=False, **kwargs):
370 """Scan for callbacks.
371
372 Args:
373 scan_in_kernel_address_space: If False we will use the physical
374 address space for scanning, while if true we scan in the kernel
375 address space.
376 """
377 super(SvcScan, self).__init__(**kwargs)
378 self.scan_in_kernel_address_space = scan_in_kernel_address_space
379
380
381 self.profile = ServiceModification(self.profile)
382
408
410 renderer.table_header([
411 ("Offset", "offset", "[addrpad]"),
412 ("Order", "order", "5"),
413 ("PID", "pid", "4"),
414 ("Service Name", "service", "30"),
415 ("Display Name", "display_name", "40"),
416 ("Service Type", "type", "30"),
417 ("Service State", "state", "15"),
418 ("Binary Path", "binary_path", "")])
419
420 for rec in self.calculate():
421 renderer.table_row(
422 rec,
423 rec.Order,
424 rec.Pid,
425 rec.ServiceName.deref(),
426 rec.DisplayName.deref(),
427 rec.Type,
428 rec.State,
429 rec.Binary)
430