1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 from rekall import obj
31 from rekall.plugins.overlays import basic
32 from rekall.plugins.windows import common
33 from rekall.plugins.windows import vadinfo
34 from rekall.plugins.overlays.windows import pe_vtypes
35 from rekall_lib import utils
36
37
38 MAX_HISTORY_DEFAULT = 50
39 HISTORY_BUFFERS_DEFAULTS = 4
40
41
42 common_types = {
43 '_LIST_ENTRY' : [0x8, {
44 'Flink' : [0x0, ['pointer', ['_LIST_ENTRY']]],
45 'Blink' : [0x4, ['pointer', ['_LIST_ENTRY']]],
46 }]}
47
48 common_types_64 = {
49 '_LIST_ENTRY' : [0x10, {
50 'Flink' : [0x0, ['pointer', ['_LIST_ENTRY']]],
51 'Blink' : [0x8, ['pointer', ['_LIST_ENTRY']]],
52 }]}
53
54
55 conhost_types_x86 = {
56 '_COMMAND': [None, {
57 'CmdLength': [0x00, ['unsigned short']],
58 'Cmd' : [0x02, ['UnicodeString', dict(
59 encoding='utf16',
60 length=lambda x: x.CmdLength
61 )]],
62 }],
63 '_COMMAND_HISTORY': [None, {
64 'ListEntry': [0x00, ['_LIST_ENTRY']],
65 'Flags' : [0x08, ['Flags', dict(
66 bitmap={
67 'Allocated': 0,
68 'Reset': 1
69 }
70 )]],
71 'Application': [0x0C, ['Pointer', dict(
72 target='UnicodeString',
73 target_args=dict(
74 encoding='utf16',
75 length=256
76 )
77 )]],
78 'CommandCount': [0x10, ['short']],
79 'LastAdded': [0x12, ['short']],
80 'LastDisplayed': [0x14, ['short']],
81 'FirstCommand': [0x16, ['short']],
82 'CommandCountMax': [0x18, ['short']],
83 'ProcessHandle': [0x1C, ['unsigned int']],
84 'PopupList': [0x20, ['_LIST_ENTRY']],
85 'CommandBucket': [0x28, ['Array', dict(
86 count=lambda x: x.CommandCount,
87 target='Pointer',
88 target_args=dict(
89 target='_COMMAND'
90 )
91 )]],
92 }],
93
94 '_ALIAS': [None, {
95 'ListEntry': [0x00, ['_LIST_ENTRY']],
96 'SourceLength': [0x08, ['unsigned short']],
97 'TargetLength': [0x0A, ['unsigned short']],
98 'Source': [0x0C, ['Pointer', dict(
99 target='UnicodeString',
100 target_args=dict(
101 encoding='utf16',
102 length=lambda x: x.SourceLength * 2
103 )
104 )]],
105
106 'Target': [0x10, ['Pointer', dict(
107 target='UnicodeString',
108 target_args=dict(
109 encoding='utf16',
110 length=lambda x: x.TargetLength * 2
111 )
112 )]],
113 }],
114 '_EXE_ALIAS_LIST' : [None, {
115 'ListEntry': [0x00, ['_LIST_ENTRY']],
116 'ExeLength': [0x08, ['unsigned short']],
117 'ExeName': [0x0C, ['Pointer', dict(
118 target='UnicodeString',
119 target_args=dict(
120 encoding='utf16',
121 length=lambda x: x.ExeLength * 2
122 )
123 )]],
124 'AliasList': [0x10, ['_LIST_ENTRY']],
125 }],
126
127 '_POPUP_LIST' : [None, {
128 'ListEntry' : [0x00, ['_LIST_ENTRY']],
129 }],
130
131 '_CONSOLE_INFORMATION': [None, {
132 'CurrentScreenBuffer': [0x98, ['pointer', ['_SCREEN_INFORMATION']]],
133 'ScreenBuffer': [0x9C, ['pointer', ['_SCREEN_INFORMATION']]],
134 'HistoryList': [0xD4, ['_LIST_ENTRY']],
135 'ProcessList': [0x18, ['_LIST_ENTRY']],
136 'ExeAliasList': [0xDC, ['_LIST_ENTRY']],
137
138
139 'HistoryBufferCount': [0xE4, ['unsigned short']],
140
141
142 'HistoryBufferMax': [0xE6, ['unsigned short']],
143
144 'CommandHistorySize': [0xE8, ['unsigned short']],
145 'OriginalTitle': [0xEC, ['Pointer', dict(
146 target='UnicodeString',
147 target_args=dict(
148 encoding='utf16',
149 length=256
150 )
151 )]],
152
153 'Title': [0xF0, ['Pointer', dict(
154 target='UnicodeString',
155 target_args=dict(
156 encoding='utf16',
157 length=256
158 )
159 )]],
160 }],
161
162 '_CONSOLE_PROCESS': [None, {
163 'ListEntry': [0x00, ['_LIST_ENTRY']],
164 'ProcessHandle': [0x8, ['unsigned int']],
165 }],
166 '_SCREEN_INFORMATION': [None, {
167 'ScreenX': [0x08, ['short']],
168 'ScreenY': [0x0A, ['short']],
169 'Rows': [0x3C, ['Pointer', dict(
170 target='Array',
171 target_args=dict(
172 count=lambda x: x.ScreenY,
173 target='_ROW'
174 )
175 )]],
176 'Next': [0xDC, ['Pointer', dict(target='_SCREEN_INFORMATION')]],
177 }],
178 '_ROW': [0x1C, {
179 'Chars': [0x08, ['Pointer', dict(
180 target='UnicodeString',
181 target_args=dict(
182 encoding='utf16',
183 length=lambda x: x.obj_parent.ScreenX * 2,
184 )
185 )]],
186 }],
187 }
188
189
190 conhost_types_x64 = {
191 '_COMMAND': [None, {
192 'CmdLength': [0x00, ['unsigned short']],
193 'Cmd' : [0x02, ['UnicodeString', dict(
194 encoding='utf16',
195 length=lambda x: x.CmdLength)]],
196 }],
197 '_COMMAND_HISTORY': [None, {
198 'ListEntry': [0x00, ['_LIST_ENTRY']],
199
200
201 'Flags' : [0x10, ['Flags', {'bitmap': {'Allocated': 0, 'Reset': 1}}]],
202
203
204 'Application': [0x18, ['Pointer', dict(
205 target='UnicodeString',
206 target_args=dict(
207 encoding='utf16',
208 length=256
209 )
210 )]],
211 'CommandCount': [0x20, ['short']],
212 'LastAdded': [0x22, ['short']],
213 'LastDisplayed': [0x24, ['short']],
214 'FirstCommand': [0x26, ['short']],
215 'CommandCountMax': [0x28, ['short']],
216 'ProcessHandle': [0x30, ['address']],
217 'PopupList': [0x38, ['_LIST_ENTRY']],
218 'CommandBucket': [0x48, ['Array', dict(
219 count=lambda x: x.CommandCount,
220 target='Pointer',
221 target_args=dict(
222 target='_COMMAND')
223 )]],
224 }],
225 '_ALIAS': [None, {
226 'ListEntry': [0x00, ['_LIST_ENTRY']],
227 'SourceLength': [0x10, ['unsigned short']],
228 'TargetLength': [0x12, ['unsigned short']],
229
230
231 'Source': [0x18, ['pointer', ['UnicodeString', dict(
232 encoding='utf16',
233 length=lambda x: x.SourceLength * 2)]]],
234
235 'Target': [0x20, ['pointer', ['UnicodeString', dict(
236 encoding='utf16',
237 length=lambda x: x.TargetLength * 2
238 )]]],
239 }],
240 '_EXE_ALIAS_LIST' : [None, {
241 'ListEntry': [0x00, ['_LIST_ENTRY']],
242 'ExeLength': [0x10, ['unsigned short']],
243
244
245 'ExeName': [0x18, ['pointer', ['UnicodeString', dict(
246 encoding='utf16',
247 length=lambda x: x.ExeLength * 2)]]],
248
249 'AliasList': [0x20, ['_LIST_ENTRY']],
250 }],
251 '_POPUP_LIST' : [None, {
252 'ListEntry' : [0x00, ['_LIST_ENTRY']],
253 }],
254 '_CONSOLE_INFORMATION': [None, {
255
256 'ProcessList': [0x28, ['_LIST_ENTRY']],
257 'CurrentScreenBuffer': [0xE0, ['Pointer', dict(
258 target='_SCREEN_INFORMATION'
259 )]],
260
261 'ScreenBuffer': [0xE8, ['Pointer', dict(
262 target='_SCREEN_INFORMATION'
263 )]],
264
265 'HistoryList': [0x148, ['_LIST_ENTRY']],
266 'ExeAliasList': [0x148, ['_LIST_ENTRY']],
267 'HistoryBufferCount': [0x168, ['unsigned short']],
268 'HistoryBufferMax': [0x16A, ['unsigned short']],
269 'CommandHistorySize': [0x16C, ['unsigned short']],
270
271 'OriginalTitle': [0x170, ['Pointer', dict(
272 target='UnicodeString',
273 target_args=dict(
274 encoding='utf16',
275 length=256
276 )
277 )]],
278
279 'Title': [0x178, ['Pointer', dict(
280 target='UnicodeString',
281 target_args=dict(
282 encoding='utf16',
283 length=256
284 )
285 )]],
286 }],
287 '_CONSOLE_PROCESS': [None, {
288 'ListEntry': [0x00, ['_LIST_ENTRY']],
289 'ProcessHandle': [0x10, ['unsigned int']],
290 }],
291
292 '_SCREEN_INFORMATION': [None, {
293 'ScreenX': [8, ['short']],
294 'ScreenY': [10, ['short']],
295 'Rows': [0x48, ['Pointer', dict(
296 target="Array",
297 target_args=dict(
298 count=lambda x: x.ScreenY,
299 target='_ROW'
300 )
301 )]],
302
303 'Next': [0x128, ['pointer', ['_SCREEN_INFORMATION']]],
304 }],
305 '_ROW': [0x28, {
306 'Chars': [0x08, ['pointer', ['UnicodeString', dict(
307 encoding='utf16',
308 length=lambda x: x.obj_parent.obj_parent.ScreenX * 2,
309 )]]],
310 }],
311 }
312
313
314 winsrv_types_x86 = {
315 '_COMMAND': [None, {
316 'CmdLength': [0x00, ['unsigned short']],
317 'Cmd' : [0x02, ['UnicodeString', dict(
318 encoding='utf16',
319 length=lambda x: x.CmdLength
320 )]],
321 }],
322 '_COMMAND_HISTORY': [None, {
323 'Flags' : [0x00, ['Flags', {
324 'bitmap': {
325 'Allocated': 0,
326 'Reset': 1
327 }
328 }]],
329 'ListEntry': [0x04, ['_LIST_ENTRY']],
330 'Application': [0x0C, ['pointer', ['UnicodeString', dict(
331 encoding='utf16', length=256)]]],
332 'CommandCount': [0x10, ['short']],
333 'LastAdded': [0x12, ['short']],
334 'LastDisplayed': [0x14, ['short']],
335 'FirstCommand': [0x16, ['short']],
336 'CommandCountMax': [0x18, ['short']],
337 'ProcessHandle': [0x1C, ['unsigned int']],
338 'PopupList': [0x20, ['_LIST_ENTRY']],
339 'CommandBucket': [0x28, ['Array', dict(
340 count=lambda x: x.CommandCount,
341 target='Pointer',
342 target_args=dict(
343 target='_COMMAND'
344 )
345 )]],
346 }],
347
348 '_ALIAS': [None, {
349 'ListEntry': [0x00, ['_LIST_ENTRY']],
350 'SourceLength': [0x08, ['unsigned short']],
351 'TargetLength': [0x0A, ['unsigned short']],
352 'Source': [0x0C, ['pointer', ['UnicodeString', dict(
353 encoding='utf16',
354 length=lambda x: x.SourceLength * 2
355 )]]],
356 'Target': [0x10, ['pointer', ['UnicodeString', dict(
357 encoding='utf16',
358 length=lambda x: x.TargetLength * 2)]]],
359 }],
360 '_EXE_ALIAS_LIST' : [None, {
361 'ListEntry': [0x00, ['_LIST_ENTRY']],
362 'ExeLength': [0x08, ['unsigned short']],
363 'ExeName': [0x0C, ['pointer', [
364 'UnicodeString', dict(
365 encoding='utf16',
366 length=lambda x: x.ExeLength * 2)]]],
367 'AliasList': [0x10, ['_LIST_ENTRY']],
368 }],
369 '_POPUP_LIST' : [None, {
370 'ListEntry' : [0x00, ['_LIST_ENTRY']],
371 }],
372 '_CONSOLE_INFORMATION': [None, {
373 'CurrentScreenBuffer': [0xB0, ['pointer', ['_SCREEN_INFORMATION']]],
374 'ScreenBuffer': [0xB4, ['pointer', ['_SCREEN_INFORMATION']]],
375 'HistoryList': [0x108, ['_LIST_ENTRY']],
376 'ProcessList': [0x100, ['_LIST_ENTRY']],
377 'ExeAliasList': [0x110, ['_LIST_ENTRY']],
378 'HistoryBufferCount': [0x118, ['unsigned short']],
379 'HistoryBufferMax': [0x11A, ['unsigned short']],
380 'CommandHistorySize': [0x11C, ['unsigned short']],
381 'OriginalTitle': [0x124, ['pointer', [
382 'UnicodeString', dict(
383 encoding='utf16',
384 length=256)]]],
385 'Title': [0x128, ['pointer', [
386 'UnicodeString', dict(
387 encoding='utf16',
388 length=256
389 )]]],
390 }],
391 '_CONSOLE_PROCESS': [None, {
392 'ListEntry': [0x00, ['_LIST_ENTRY']],
393 'ProcessHandle': [0x08, ['unsigned int']],
394 'Process': [0x0C, ['pointer', ['_CSR_PROCESS']]],
395 }],
396 '_SCREEN_INFORMATION': [None, {
397 'Console': [0x00, ['pointer', ['_CONSOLE_INFORMATION']]],
398 'ScreenX': [0x24, ['short']],
399 'ScreenY': [0x26, ['short']],
400 'Rows': [0x58, ['pointer', [
401 'array', lambda x: x.ScreenY, ['_ROW']]]],
402 'Next': [0xF8, ['pointer', ['_SCREEN_INFORMATION']]],
403 }],
404 '_ROW': [0x1C, {
405 'Chars': [0x08, ['pointer', [
406 'UnicodeString', dict(
407 encoding='utf16', length=256
408 )]]],
409 }],
410
411
412 '_CSR_PROCESS' : [0x60, {
413 'ClientId' : [0x0, ['_CLIENT_ID']],
414 'ListLink' : [0x8, ['_LIST_ENTRY']],
415 'ThreadList' : [0x10, ['_LIST_ENTRY']],
416 'NtSession' : [0x18, ['pointer', ['_CSR_NT_SESSION']]],
417 'ClientPort' : [0x1c, ['pointer', ['void']]],
418 'ClientViewBase' : [0x20, ['pointer', ['unsigned char']]],
419 'ClientViewBounds' : [0x24, ['pointer', ['unsigned char']]],
420 'ProcessHandle' : [0x28, ['pointer', ['void']]],
421 'SequenceNumber' : [0x2c, ['unsigned long']],
422 'Flags' : [0x30, ['unsigned long']],
423 'DebugFlags' : [0x34, ['unsigned long']],
424 'ReferenceCount' : [0x38, ['unsigned long']],
425 'ProcessGroupId' : [0x3c, ['unsigned long']],
426 'ProcessGroupSequence' : [0x40, ['unsigned long']],
427 'LastMessageSequence' : [0x44, ['unsigned long']],
428 'NumOutstandingMessages' : [0x48, ['unsigned long']],
429 'ShutdownLevel' : [0x4c, ['unsigned long']],
430 'ShutdownFlags' : [0x50, ['unsigned long']],
431 'Luid' : [0x54, ['_LUID']],
432 'ServerDllPerProcessData' : [0x5c, [
433 'array', 1, ['pointer', ['void']]]],
434 }],
435 }
436
437 winsrv_types_x64 = {
438 '_COMMAND': [None, {
439 'CmdLength': [0x00, ['unsigned short']],
440 'Cmd' : [0x02, ['UnicodeString', dict(
441 encoding='utf16',
442 length=lambda x: x.CmdLength)]],
443 }],
444 '_COMMAND_HISTORY': [None, {
445 'Flags' : [0x00, ['Flags', {
446 'bitmap': {'Allocated': 0, 'Reset': 1}}]],
447 'ListEntry': [0x08, ['_LIST_ENTRY']],
448 'Application': [0x18, ['pointer', [
449 'UnicodeString', dict(
450 encoding='utf16',
451 length=256)]]],
452 'CommandCount': [0x20, ['short']],
453 'LastAdded': [0x22, ['short']],
454 'LastDisplayed': [0x24, ['short']],
455 'FirstCommand': [0x26, ['short']],
456 'CommandCountMax': [0x28, ['short']],
457 'ProcessHandle': [0x30, ['unsigned int']],
458 'PopupList': [0x38, ['_LIST_ENTRY']],
459 'CommandBucket': [0x48, [
460 'array', lambda x: x.CommandCount, [
461 'pointer', ['_COMMAND']]]],
462 }],
463 '_ALIAS': [None, {
464 'ListEntry': [0x00, ['_LIST_ENTRY']],
465 'SourceLength': [0x10, ['unsigned short']],
466 'TargetLength': [0x12, ['unsigned short']],
467 'Source': [0x14, ['pointer', [
468 'UnicodeString', dict(
469 encoding='utf16',
470 length=lambda x: x.SourceLength * 2)]]],
471 'Target': [0x1C, ['pointer', ['UnicodeString', dict(
472 encoding='utf16',
473 length=lambda x: x.TargetLength * 2)]]],
474 }],
475 '_EXE_ALIAS_LIST' : [None, {
476 'ListEntry': [0x00, ['_LIST_ENTRY']],
477 'ExeLength': [0x10, ['unsigned short']],
478 'ExeName': [0x12, ['pointer', [
479 'UnicodeString', dict(
480 encoding='utf16',
481 length=lambda x: x.ExeLength * 2)]]],
482 'AliasList': [0x1A, ['_LIST_ENTRY']],
483 }],
484 '_POPUP_LIST' : [None, {
485 'ListEntry' : [0x00, ['_LIST_ENTRY']],
486 }],
487 '_CONSOLE_INFORMATION': [None, {
488 'CurrentScreenBuffer': [0xE8, ['pointer', ['_SCREEN_INFORMATION']]],
489 'ScreenBuffer': [0xF0, ['pointer', ['_SCREEN_INFORMATION']]],
490 'HistoryList': [0x188, ['_LIST_ENTRY']],
491 'ProcessList': [0x178, ['_LIST_ENTRY']],
492 'ExeAliasList': [0x198, ['_LIST_ENTRY']],
493 'HistoryBufferCount': [0x1A8, ['unsigned short']],
494 'HistoryBufferMax': [0x1AA, ['unsigned short']],
495 'CommandHistorySize': [0x1AC, ['unsigned short']],
496 'OriginalTitle': [0x1B0, ['pointer', [
497 'UnicodeString', dict(
498 encoding='utf16', length=256)]]],
499 'Title': [0x1B8, ['pointer', [
500 'UnicodeString', dict(
501 encoding='utf16', length=256)]]],
502 }],
503 '_CONSOLE_PROCESS': [None, {
504 'ListEntry': [0x00, ['_LIST_ENTRY']],
505 'ProcessHandle': [0x10, ['unsigned int']],
506 'Process': [0x18, ['pointer', ['_CSR_PROCESS']]],
507 }],
508 '_SCREEN_INFORMATION': [None, {
509 'Console': [0x00, ['pointer', ['_CONSOLE_INFORMATION']]],
510 'ScreenX': [0x28, ['short']],
511 'ScreenY': [0x2A, ['short']],
512 'Rows': [0x68, ['pointer', [
513 'array', lambda x: x.ScreenY, ['_ROW']]]],
514 'Next': [0x128, ['pointer', ['_SCREEN_INFORMATION']]],
515 }],
516 '_ROW': [0x28, {
517 'Chars': [0x08, ['pointer', [
518 'UnicodeString', dict(
519 encoding='utf16',
520 length=256)]]],
521 }],
522
523
524 '_CSR_PROCESS' : [0x60, {
525 'ClientId' : [0x0, ['_CLIENT_ID']],
526 'ListLink' : [0x8, ['_LIST_ENTRY']],
527 'ThreadList' : [0x10, ['_LIST_ENTRY']],
528 'NtSession' : [0x18, ['pointer', ['_CSR_NT_SESSION']]],
529 'ClientPort' : [0x1c, ['pointer', ['void']]],
530 'ClientViewBase' : [0x20, ['pointer', ['unsigned char']]],
531 'ClientViewBounds' : [0x24, ['pointer', ['unsigned char']]],
532 'ProcessHandle' : [0x28, ['pointer', ['void']]],
533 'SequenceNumber' : [0x2c, ['unsigned long']],
534 'Flags' : [0x30, ['unsigned long']],
535 'DebugFlags' : [0x34, ['unsigned long']],
536 'ReferenceCount' : [0x38, ['unsigned long']],
537 'ProcessGroupId' : [0x3c, ['unsigned long']],
538 'ProcessGroupSequence' : [0x40, ['unsigned long']],
539 'LastMessageSequence' : [0x44, ['unsigned long']],
540 'NumOutstandingMessages' : [0x48, ['unsigned long']],
541 'ShutdownLevel' : [0x4c, ['unsigned long']],
542 'ShutdownFlags' : [0x50, ['unsigned long']],
543 'Luid' : [0x54, ['_LUID']],
544 'ServerDllPerProcessData' : [0x5c, [
545 'array', 1, ['pointer', ['void']]]],
546 }],
547 }
573
617
618
619 -class WinSrv86(basic.Profile32Bits, basic.BasicClasses):
620 """A domain specific profile for the xp, 2008."""
621
630
631
632 -class WinSrv64(basic.ProfileLLP64, basic.BasicClasses):
633 """A domain specific profile for the xp, 2008."""
634
643
644
645 -class ConHost86(basic.Profile32Bits, basic.BasicClasses):
646 """A domain specific profile for windows 7."""
647
656
657
658 -class ConHost64(basic.ProfileLLP64, basic.BasicClasses):
659 """A domain specific profile for windows 7."""
660
669
670
671 -class WinHistoryScanner(vadinfo.VadScanner):
672 """A vad scanner for command histories.
673
674 The default pattern we search for, as described by Stevens and Casey, is
675 "\x32\x00". That's because CommandCountMax is a little-endian unsigned short
676 whose default value is 50. However, that value can be changed by right
677 clicking cmd.exe and going to Properties->Options->Cmd History or by calling
678 the API function kernel32!SetConsoleHistoryInfo. Thus you can tweak the
679 search criteria by using the --MAX_HISTORY.
680 """
681 - def __init__(self, max_history=MAX_HISTORY_DEFAULT, **kwargs):
682 super(WinHistoryScanner, self).__init__(**kwargs)
683 self.max_history = max_history
684
685 - def scan(self, **kwargs):
686 for hit in super(WinHistoryScanner, self).scan(**kwargs):
687
688 hist = self.profile.Object(
689 "_COMMAND_HISTORY", vm=self.address_space,
690 offset=hit - self.profile.get_obj_offset(
691 "_COMMAND_HISTORY", "CommandCountMax"))
692
693 if not hist.is_valid():
694 continue
695
696
697 if hist.CommandCount < 0 or hist.CommandCount > self.max_history:
698 continue
699
700
701 if hist.LastAdded < -1 or hist.LastAdded > self.max_history:
702 continue
703
704
705 if hist.LastDisplayed < -1 or hist.LastDisplayed > self.max_history:
706 continue
707
708
709 if hist.FirstCommand < 0 or hist.FirstCommand > self.max_history:
710 continue
711
712
713 if (hist.FirstCommand != 0 and
714 hist.FirstCommand != hist.LastAdded + 1):
715 continue
716
717
718 if hist.ProcessHandle <= 0 or hist.ProcessHandle > 0xFFFF:
719 continue
720
721 Popup = self.profile._POPUP_LIST(
722 offset=hist.PopupList.Flink, vm=self.address_space)
723
724
725 if Popup.ListEntry.Blink != hist.PopupList.obj_offset:
726 continue
727
728 yield hist
729
730
731 -class CmdScan(common.WindowsCommandPlugin):
732 """Extract command history by scanning for _COMMAND_HISTORY"""
733 __name = "cmdscan"
734
735 __args = [
736 dict(name="max_history", default=MAX_HISTORY_DEFAULT,
737 type="IntParser", help="Value of history buffer size. See "
738 "HKEY_CURRENT_USER\\Console\\HistoryBufferSize "
739 "for default.")
740 ]
741
775
777 for task, hist in self.generate_hits():
778 renderer.section()
779 renderer.format(u"CommandProcess: {0} Pid: {1}\n",
780 task.ImageFileName, task.UniqueProcessId)
781 renderer.format(
782 u"CommandHistory: {0:#x} Application: {1} Flags: {2}\n",
783 hist.obj_offset, hist.Application.dereference(), hist.Flags)
784
785 renderer.format(
786 u"CommandCount: {0} LastAdded: {1} LastDisplayed: {2}\n",
787 hist.CommandCount, hist.LastAdded, hist.LastDisplayed)
788
789 renderer.format(u"FirstCommand: {0} CommandCountMax: {1}\n",
790 hist.FirstCommand, hist.CommandCountMax)
791
792 renderer.format(u"ProcessHandle: {0:#x}\n", hist.ProcessHandle)
793
794
795 renderer.table_header([("Cmd", "command", ">3"),
796 ("Address", "address", "[addrpad]"),
797 ("Text", "text", "")])
798
799
800
801
802
803 pointers = hist.obj_profile.Array(
804 target="address", count=hist.CommandCountMax,
805 offset=hist.obj_offset + hist.obj_profile.get_obj_offset(
806 "_COMMAND_HISTORY", "CommandBucket"),
807 vm=hist.obj_vm)
808
809 for i, p in enumerate(pointers):
810 cmd = p.cast("Pointer", target="_COMMAND").deref()
811 if cmd.obj_offset and cmd.Cmd:
812 renderer.table_row(
813 i, cmd.obj_offset,
814 utils.SmartUnicode(cmd.Cmd).encode("unicode_escape"))
815
818 """A scanner for _CONSOLE_INFORMATION."""
819
822 super(ConsoleScanner, self).__init__(**kwargs)
823 self.max_history = max_history
824 self.history_buffers = history_buffers
825
826 - def scan(self, **kwargs):
827 for hit in super(ConsoleScanner, self).scan(**kwargs):
828
829 console = self.profile.Object(
830 "_CONSOLE_INFORMATION", offset=hit -
831 self.profile.get_obj_offset(
832 "_CONSOLE_INFORMATION", "CommandHistorySize"),
833 vm=self.address_space, parent=self.task)
834
835 if (console.HistoryBufferMax != self.history_buffers or
836 console.HistoryBufferCount > self.history_buffers):
837 continue
838
839
840 next_history = console.HistoryList.Flink.dereference(
841 ).dereference_as("_COMMAND_HISTORY", "ListEntry")
842 if next_history.CommandCountMax != self.max_history:
843 continue
844
845 yield console
846
849 """Extract command history by scanning for _CONSOLE_INFORMATION"""
850
851 __name = "consolescan"
852
853 __args = [
854 dict(name="history_buffers", default=HISTORY_BUFFERS_DEFAULTS,
855 type="IntParser",
856 help="Value of history buffer size. See "
857 "HKEY_CURRENT_USER\\Console\\HistoryBufferSize "
858 "for default.")
859 ]
860
898
900 for task, console in self.generate_hits():
901 renderer.section()
902
903 renderer.format(u"ConsoleProcess: {0} Pid: {1}\n",
904 task.ImageFileName, task.UniqueProcessId)
905
906 renderer.format(u"Console: {0:#x} CommandHistorySize: {1}\n",
907 console, console.CommandHistorySize)
908
909 renderer.format(
910 u"HistoryBufferCount: {0} HistoryBufferMax: {1}\n",
911 console.HistoryBufferCount, console.HistoryBufferMax)
912
913 renderer.format(u"OriginalTitle: {0}\n",
914 console.OriginalTitle.dereference())
915
916 renderer.format(u"Title: {0}\n", console.Title.dereference())
917
918 for console_proc in console.ProcessList.list_of_type(
919 "_CONSOLE_PROCESS", "ListEntry"):
920 process = task.ObReferenceObjectByHandle(
921 console_proc.ProcessHandle, type="_EPROCESS")
922
923 if process:
924 renderer.format(
925 u"AttachedProcess: {0} Pid: {1} Handle: {2:#x}\n",
926 process.ImageFileName, process.UniqueProcessId,
927 console_proc.ProcessHandle)
928
929 for hist in console.HistoryList.list_of_type(
930 "_COMMAND_HISTORY", "ListEntry"):
931 renderer.format(u"----\n")
932
933 renderer.format(
934 u"CommandHistory: {0:#x} Application: {1} Flags: {2}\n",
935 hist, hist.Application.dereference(),
936 hist.Flags)
937 renderer.format(
938 u"CommandCount: {0} LastAdded: {1} LastDisplayed: {2}\n",
939 hist.CommandCount, hist.LastAdded, hist.LastDisplayed)
940
941 renderer.format(u"FirstCommand: {0} CommandCountMax: {1}\n",
942 hist.FirstCommand, hist.CommandCountMax)
943
944 renderer.format(u"ProcessHandle: {0:#x}\n", hist.ProcessHandle)
945 for i, cmd in enumerate(hist.CommandBucket):
946 if cmd.Cmd.is_valid():
947 renderer.format(u"Cmd #{0} at {1:#x}: {2}\n",
948 i, cmd, unicode(cmd.Cmd))
949
950 for exe_alias in console.ExeAliasList.list_of_type(
951 "_EXE_ALIAS_LIST", "ListEntry"):
952
953 for alias in exe_alias.AliasList.list_of_type(
954 "_ALIAS", "ListEntry"):
955 renderer.format(u"----\n")
956 renderer.format(
957 u"Alias: {0} Source: {1} Target: {2}\n",
958 exe_alias.ExeName.dereference(),
959 alias.Source.dereference(),
960 alias.Target.dereference())
961
962 for screen in console.get_screens():
963 renderer.format(u"----\n")
964 renderer.format(u"Screen {0:#x} X:{1} Y:{2}\n",
965 screen.dereference(), screen.ScreenX,
966 screen.ScreenY)
967
968 renderer.format(u"Dump:\n{0}\n", '\n'.join(screen.get_buffer()))
969
970
971 -class Conhost(pe_vtypes.BasicPEProfile):
972 """A profile for Conhost.exe."""
973
974 @classmethod
984
985
986 -class Consoles(common.WindowsCommandPlugin):
987 """Enumerate command consoles."""
988
989 name = "consoles"
990
992 self.cc.SwitchProcessContext(task)
993 console = self.session.address_resolver.get_constant_object(
994 "conhost!gConsoleInformation", "_CONSOLE_INFORMATION")
995
996 if console == None:
997 self.session.logging.warning(
998 "Unable to load profile for conhost.exe.")
999 return
1000
1001 renderer.format(u"ConsoleProcess: {0}\n", task)
1002 renderer.format(u"Title: {0}\n", console.Title.deref())
1003 renderer.format(u"OriginalTitle: {0}\n",
1004 console.OriginalTitle.dereference())
1005
1006 for console_proc in console.ProcessList.list_of_type(
1007 "_CONSOLE_PROCESS", "ListEntry"):
1008 process = task.ObReferenceObjectByHandle(
1009 console_proc.ProcessHandle, type="_EPROCESS")
1010
1011 if process:
1012 renderer.format(
1013 u"AttachedProcess: {0} Handle: {1:style=address}\n",
1014 process, console_proc.ProcessHandle)
1015
1016 for hist in console.HistoryList.list_of_type(
1017 "_COMMAND_HISTORY", "ListEntry"):
1018 renderer.format(u"----\n")
1019
1020 renderer.format(
1021 u"CommandHistory: {0:#x} Application: {1} Flags: {2}\n",
1022 hist, hist.Application.dereference(),
1023 hist.Flags)
1024
1025 renderer.format(
1026 u"CommandCount: {0} LastAdded: {1} LastDisplayed: {2}\n",
1027 hist.CommandCount, hist.LastAdded, hist.LastDisplayed)
1028
1029 renderer.format(u"FirstCommand: {0} CommandCountMax: {1}\n",
1030 hist.FirstCommand, hist.CommandCountMax)
1031
1032 renderer.format(u"ProcessHandle: {0:#x}\n", hist.ProcessHandle)
1033 for i, cmd in enumerate(hist.CommandBucket):
1034 if cmd.Cmd.is_valid():
1035 renderer.format(u"Cmd #{0} at {1:#x}: {2}\n",
1036 i, cmd, unicode(cmd.Cmd))
1037
1038 for exe_alias in console.ExeAliasList.list_of_type(
1039 "_EXE_ALIAS_LIST", "ListEntry"):
1040
1041 for alias in exe_alias.AliasList.list_of_type(
1042 "_ALIAS", "ListEntry"):
1043 if alias == None:
1044 continue
1045
1046 renderer.format(u"----\n")
1047 renderer.format(
1048 u"Alias: {0} Source: {1} Target: {2}\n",
1049 exe_alias.ExeName.dereference(),
1050 alias.Source.dereference(),
1051 alias.Target.dereference())
1052
1053 for screen in console.ScreenBuffer.walk_list("Next"):
1054 renderer.format(u"----\n")
1055 renderer.format(u"Screen {0:#x} X:{1} Y:{2}\n",
1056 screen, screen.ScreenX, screen.ScreenY)
1057
1058 screen_data = []
1059 for row in screen.Rows:
1060 row_data = row.Chars.deref()
1061
1062
1063
1064 if len(row_data) == 0:
1065 continue
1066
1067 screen_data.append((row_data, unicode(row_data).rstrip()))
1068
1069
1070 while screen_data and not screen_data[-1][1]:
1071 screen_data.pop(-1)
1072
1073 for row, row_string in screen_data:
1074 renderer.format(
1075 "{0:style=address}: {1}\n", row, row_string)
1076
1084