1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 """Common windows overlays and classes."""
25 import struct
26 from itertools import chain
27
28 from rekall import addrspace
29 from rekall import obj
30
31 from rekall.plugins.overlays.windows import pe_vtypes
32 from rekall.plugins.overlays.windows import undocumented
33
34 from rekall_lib import utils
35
36
37 MM_PROTECTION_ENUM = utils.EnumerationFromDefines("""
38 //
39 00098 // Protection Bits part of the internal memory manager Protection Mask, from:
40 00099 // http://reactos.org/wiki/Techwiki:Memory_management_in_the_Windows_XP_kernel
41 00100 // https://www.reactos.org/wiki/Techwiki:Memory_Protection_constants
42 00101 // and public assertions.
43 00102 //
44 00103 #define MM_ZERO_ACCESS 0
45 00104 #define MM_READONLY 1
46 00105 #define MM_EXECUTE 2
47 00106 #define MM_EXECUTE_READ 3
48 00107 #define MM_READWRITE 4
49 00108 #define MM_WRITECOPY 5
50 00109 #define MM_EXECUTE_READWRITE 6
51 00110 #define MM_EXECUTE_WRITECOPY 7
52 00111 #define MM_PROTECT_ACCESS 7
53 00112
54 00113 //
55 00114 // These are flags on top of the actual protection mask
56 00115 //
57 00116 #define MM_NOCACHE 0x08
58 00117 #define MM_GUARDPAGE 0x10
59 00118 #define MM_WRITECOMBINE 0x18
60 00119 #define MM_PROTECT_SPECIAL 0x18
61 00120
62 00121 //
63 00122 // These are special cases
64 00123 //
65 00124 #define MM_DECOMMIT (MM_ZERO_ACCESS | MM_GUARDPAGE)
66 00125 #define MM_NOACCESS (MM_ZERO_ACCESS | MM_WRITECOMBINE)
67 00126 #define MM_OUTSWAPPED_KSTACK (MM_EXECUTE_WRITECOPY | MM_WRITECOMBINE)
68 00127 #define MM_INVALID_PROTECTION 0xFFFFFFFF
69 """)
70
71
72 windows_overlay = {
73 '_UNICODE_STRING': [None, {
74 'Buffer': [None, ['Pointer', dict(
75 target='UnicodeString',
76 target_args=dict(length=lambda x: x.Length)
77 )]],
78 }],
79
80 '_RTL_BITMAP': [None, {
81 "Buffer": [None, ["Pointer", dict(
82 target="String",
83 target_args=dict(
84 term=None,
85 length=lambda x: x.SizeOfBitMap / 8 + 1
86 )
87 )]],
88 }],
89 '_UNICODE_STRING32': [8, {
90 "Buffer": [4, ['Pointer32', dict(
91 target='UnicodeString',
92 target_args=dict(length=lambda x: x.Length)
93 )]],
94 "Length": [0, ["unsigned short", {}]],
95 "MaximumLength": [2, ["unsigned short", {}]]
96 }],
97 '_EPROCESS' : [None, {
98
99 'name': lambda x: x.ImageFileName,
100 'pid': lambda x: x.UniqueProcessId,
101 'dtb': lambda x: x.Pcb.DirectoryTableBase.v(),
102
103 'CreateTime' : [None, ['WinFileTime', {}]],
104 'ExitTime' : [None, ['WinFileTime', {}]],
105 'InheritedFromUniqueProcessId' : [None, ['unsigned int']],
106 'ImageFileName' : [None, ['String', dict(length=16)]],
107 'UniqueProcessId' : [None, ['unsigned int']],
108 'Session': [None, ["Pointer", dict(target="_MM_SESSION_SPACE")]],
109 'Token': [None, ["_EX_FAST_REF", dict(target="_TOKEN")]],
110 }],
111
112 '_ETHREAD' : [None, {
113 'CreateTime' : [None, ['ThreadCreateTimeStamp', {}]],
114 'ExitTime' : [None, ['WinFileTime', {}]],
115 }],
116
117 '_OBJECT_SYMBOLIC_LINK' : [None, {
118 'CreationTime' : [None, ['WinFileTime', {}]],
119 }],
120
121 '_KUSER_SHARED_DATA' : [None, {
122 'SystemTime' : [None, ['WinFileTime', dict(is_utc=True)]],
123
124
125 'SystemExpirationDate': [None, ['WinFileTime', {}]],
126
127 "NtSystemRoot": [None, ["UnicodeString"]],
128 }],
129
130 '_KPCR': [None, {
131
132
133 'ProcessorBlock': lambda x: x.m("Prcb") or x.m("PrcbData"),
134 'IDT': lambda x: x.m("IDT") or x.m("IdtBase"),
135 'GDT': lambda x: x.m("GDT") or x.m("GdtBase"),
136 'KdVersionBlock': [None, ['Pointer', dict(
137 target='_DBGKD_GET_VERSION64')]],
138 }],
139
140 '_KPRCB': [None, {
141 'CurrentThread': [None, ['Pointer', dict(
142 target='_ETHREAD')]],
143 'IdleThread': [None, ['Pointer', dict(
144 target='_ETHREAD')]],
145 'NextThread': [None, ['Pointer', dict(
146 target='_ETHREAD')]],
147 'VendorString': [None, ['String', dict(length=13)]],
148
149 }],
150
151
152
153
154 '_KPROCESS' : [None, {
155 'DirectoryTableBase' : [None, ['address']],
156 }],
157
158 '_HANDLE_TABLE_ENTRY' : [None, {
159 'Object' : [None, ['_EX_FAST_REF']],
160 }],
161
162 '_OBJECT_HEADER': [None, {
163 'GrantedAccess': lambda x: x.obj_parent.GrantedAccess
164 }],
165
166 '_IMAGE_SECTION_HEADER' : [None, {
167 'Name' : [0x0, ['String', dict(length=8)]],
168 }],
169
170 'PO_MEMORY_IMAGE' : [None, {
171 'Signature': [None, ['String', dict(length=4)]],
172 'SystemTime' : [None, ['WinFileTime', {}]],
173 }],
174
175 '_DBGKD_GET_VERSION64' : [None, {
176 'DebuggerDataList' : [None, ['pointer', ['unsigned long']]],
177 }],
178
179 '_TOKEN' : [None, {
180 'UserAndGroups' : [None, ['Pointer', dict(
181 target='Array',
182 target_args=dict(
183 count=lambda x: x.UserAndGroupCount,
184 target='_SID_AND_ATTRIBUTES'
185 )
186 )]],
187 }],
188
189 '_SID_AND_ATTRIBUTES': [None, {
190 'Sid': [None, ['Pointer', dict(
191 target='_SID'
192 )]],
193 }],
194
195 '_SID' : [None, {
196 'SubAuthority' : [None, ['Array', dict(
197 count=lambda x: x.SubAuthorityCount,
198 target='unsigned long')]],
199 }],
200
201 '_CLIENT_ID': [None, {
202 'UniqueProcess' : [None, ['unsigned int']],
203 'UniqueThread' : [None, ['unsigned int']],
204 }],
205
206 '_MMVAD': [None, {
207 'FirstPrototypePte': [None, ["Pointer", dict(
208 target="Array",
209 target_args=dict(
210 target="_MMPTE"
211 )
212 )]],
213 }],
214
215 '_MMPFN': [None, {
216
217 "IsPrototype": lambda x: x.multi_m(
218 "u4.PrototypePte", "u3.e1.PrototypePte"),
219
220
221 "Priority": lambda x: x.m("u3.e1.Priority"),
222
223 "Type": [0, ["ValueEnumeration", dict(
224 value=lambda x: x.u3.e1.PageLocation,
225 choices={
226 0: 'Zeroed',
227 1: 'Free',
228 2: 'Standby',
229 3: 'Modified',
230 4: 'ModifiedNoWrite',
231 5: 'Bad',
232 6: 'Active',
233 7: 'Transition'
234 }
235 )]],
236 }],
237 "_GUID": [16, {
238 "Data4": [8, ["String", dict(length=8, term=None)]],
239 "AsString": lambda x: ("%08x-%04x-%04x-%s" % (
240 x.Data1, x.Data2, x.Data3, x.Data4.v().encode('hex'))).upper(),
241 }],
242
243 '_MMVAD_LONG': [None, {
244 'FirstPrototypePte': [None, ["Pointer", dict(
245 target="Array",
246 target_args=dict(
247 target="_MMPTE"
248 )
249 )]],
250 }],
251
252 '_MMVAD_FLAGS': [None, {
253
254
255
256 'ProtectionEnum': lambda x: x.cast(
257 "Enumeration",
258 choices={
259 0: 'NOACCESS',
260 1: 'READONLY',
261 2: 'EXECUTE',
262 3: 'EXECUTE_READ',
263 4: 'READWRITE',
264 5: 'WRITECOPY',
265 6: 'EXECUTE_READWRITE',
266 7: 'EXECUTE_WRITECOPY',
267 8: 'NOACCESS',
268 9: 'NOCACHE | READONLY',
269 10:'NOCACHE | EXECUTE',
270 11:'NOCACHE | EXECUTE_READ',
271 12:'NOCACHE | READWRITE',
272 13:'NOCACHE | WRITECOPY',
273 14:'NOCACHE | EXECUTE_READWRITE',
274 15:'NOCACHE | EXECUTE_WRITECOPY',
275 16:'NOACCESS',
276 17:'GUARD | READONLY',
277 18:'GUARD | EXECUTE',
278 19:'GUARD | EXECUTE_READ',
279 20:'GUARD | READWRITE',
280 21:'GUARD | WRITECOPY',
281 22:'GUARD | EXECUTE_READWRITE',
282 23:'GUARD | EXECUTE_WRITECOPY',
283 24:'NOACCESS',
284 25:'WRITECOMBINE | READONLY',
285 26:'WRITECOMBINE | EXECUTE',
286 27:'WRITECOMBINE | EXECUTE_READ',
287 28:'WRITECOMBINE | READWRITE',
288 29:'WRITECOMBINE | WRITECOPY',
289 30:'WRITECOMBINE | EXECUTE_READWRITE',
290 31:'WRITECOMBINE | EXECUTE_WRITECOPY',
291 },
292 value=x.m("Protection")),
293
294
295
296
297
298
299 "VadTypeEnum": lambda x: x.cast(
300 "Enumeration",
301 choices={
302 0: 'VadNone',
303 1: 'VadDevicePhysicalMemory',
304 2: 'VadImageMap',
305 3: 'VadAwe',
306 4: 'VadWriteWatch',
307 5: 'VadLargePages',
308 6: 'VadRotatePhysical',
309 7: 'VadLargePageSection',
310 },
311 value=x.m("VadType")),
312 }],
313
314
315
316 '_RTL_USER_PROCESS_PARAMETERS': [None, {
317 'Environment': [None, ['Pointer', dict(
318 target='SentinelListArray',
319 target_args=dict(
320 target="UnicodeString",
321 )
322 )]],
323 }],
324
325 '_DEVICE_OBJECT': [None, {
326 'DeviceType': [None, ['Enumeration', dict(choices={
327 0x00000027 : 'FILE_DEVICE_8042_PORT',
328 0x00000032 : 'FILE_DEVICE_ACPI',
329 0x00000029 : 'FILE_DEVICE_BATTERY',
330 0x00000001 : 'FILE_DEVICE_BEEP',
331 0x0000002a : 'FILE_DEVICE_BUS_EXTENDER',
332 0x00000002 : 'FILE_DEVICE_CD_ROM',
333 0x00000003 : 'FILE_DEVICE_CD_ROM_FILE_SYSTEM',
334 0x00000030 : 'FILE_DEVICE_CHANGER',
335 0x00000004 : 'FILE_DEVICE_CONTROLLER',
336 0x00000005 : 'FILE_DEVICE_DATALINK',
337 0x00000006 : 'FILE_DEVICE_DFS',
338 0x00000035 : 'FILE_DEVICE_DFS_FILE_SYSTEM',
339 0x00000036 : 'FILE_DEVICE_DFS_VOLUME',
340 0x00000007 : 'FILE_DEVICE_DISK',
341 0x00000008 : 'FILE_DEVICE_DISK_FILE_SYSTEM',
342 0x00000033 : 'FILE_DEVICE_DVD',
343 0x00000009 : 'FILE_DEVICE_FILE_SYSTEM',
344 0x0000003a : 'FILE_DEVICE_FIPS',
345 0x00000034 : 'FILE_DEVICE_FULLSCREEN_VIDEO',
346 0x0000000a : 'FILE_DEVICE_INPORT_PORT',
347 0x0000000b : 'FILE_DEVICE_KEYBOARD',
348 0x0000002f : 'FILE_DEVICE_KS',
349 0x00000039 : 'FILE_DEVICE_KSEC',
350 0x0000000c : 'FILE_DEVICE_MAILSLOT',
351 0x0000002d : 'FILE_DEVICE_MASS_STORAGE',
352 0x0000000d : 'FILE_DEVICE_MIDI_IN',
353 0x0000000e : 'FILE_DEVICE_MIDI_OUT',
354 0x0000002b : 'FILE_DEVICE_MODEM',
355 0x0000000f : 'FILE_DEVICE_MOUSE',
356 0x00000010 : 'FILE_DEVICE_MULTI_UNC_PROVIDER',
357 0x00000011 : 'FILE_DEVICE_NAMED_PIPE',
358 0x00000012 : 'FILE_DEVICE_NETWORK',
359 0x00000013 : 'FILE_DEVICE_NETWORK_BROWSER',
360 0x00000014 : 'FILE_DEVICE_NETWORK_FILE_SYSTEM',
361 0x00000028 : 'FILE_DEVICE_NETWORK_REDIRECTOR',
362 0x00000015 : 'FILE_DEVICE_NULL',
363 0x00000016 : 'FILE_DEVICE_PARALLEL_PORT',
364 0x00000017 : 'FILE_DEVICE_PHYSICAL_NETCARD',
365 0x00000018 : 'FILE_DEVICE_PRINTER',
366 0x00000019 : 'FILE_DEVICE_SCANNER',
367 0x0000001c : 'FILE_DEVICE_SCREEN',
368 0x00000037 : 'FILE_DEVICE_SERENUM',
369 0x0000001a : 'FILE_DEVICE_SERIAL_MOUSE_PORT',
370 0x0000001b : 'FILE_DEVICE_SERIAL_PORT',
371 0x00000031 : 'FILE_DEVICE_SMARTCARD',
372 0x0000002e : 'FILE_DEVICE_SMB',
373 0x0000001d : 'FILE_DEVICE_SOUND',
374 0x0000001e : 'FILE_DEVICE_STREAMS',
375 0x0000001f : 'FILE_DEVICE_TAPE',
376 0x00000020 : 'FILE_DEVICE_TAPE_FILE_SYSTEM',
377 0x00000038 : 'FILE_DEVICE_TERMSRV',
378 0x00000021 : 'FILE_DEVICE_TRANSPORT',
379 0x00000022 : 'FILE_DEVICE_UNKNOWN',
380 0x0000002c : 'FILE_DEVICE_VDM',
381 0x00000023 : 'FILE_DEVICE_VIDEO',
382 0x00000024 : 'FILE_DEVICE_VIRTUAL_DISK',
383 0x00000025 : 'FILE_DEVICE_WAVE_IN',
384 0x00000026 : 'FILE_DEVICE_WAVE_OUT',
385 })]],
386 }],
387 '_DRIVER_OBJECT': [None, {
388 'MajorFunction': [None, ['IndexedArray', dict(
389 index_table={
390 'IRP_MJ_CREATE': 0,
391 'IRP_MJ_CREATE_NAMED_PIPE': 1,
392 'IRP_MJ_CLOSE': 2,
393 'IRP_MJ_READ': 3,
394 'IRP_MJ_WRITE': 4,
395 'IRP_MJ_QUERY_INFORMATION': 5,
396 'IRP_MJ_SET_INFORMATION': 6,
397 'IRP_MJ_QUERY_EA': 7,
398 'IRP_MJ_SET_EA': 8,
399 'IRP_MJ_FLUSH_BUFFERS': 9,
400 'IRP_MJ_QUERY_VOLUME_INFORMATION': 10,
401 'IRP_MJ_SET_VOLUME_INFORMATION': 11,
402 'IRP_MJ_DIRECTORY_CONTROL': 12,
403 'IRP_MJ_FILE_SYSTEM_CONTROL': 13,
404 'IRP_MJ_DEVICE_CONTROL': 14,
405 'IRP_MJ_INTERNAL_DEVICE_CONTROL': 15,
406 'IRP_MJ_SHUTDOWN': 16,
407 'IRP_MJ_LOCK_CONTROL': 17,
408 'IRP_MJ_CLEANUP': 18,
409 'IRP_MJ_CREATE_MAILSLOT': 19,
410 'IRP_MJ_QUERY_SECURITY': 20,
411 'IRP_MJ_SET_SECURITY': 21,
412 'IRP_MJ_POWER': 22,
413 'IRP_MJ_SYSTEM_CONTROL': 23,
414 'IRP_MJ_DEVICE_CHANGE': 24,
415 'IRP_MJ_QUERY_QUOTA': 25,
416 'IRP_MJ_SET_QUOTA': 26,
417 'IRP_MJ_PNP': 27
418 },
419 target="Pointer",
420 target_args=dict(target="Function"),
421 )]],
422 }],
423
424
425 "_PSP_CID_TABLE": "_HANDLE_TABLE",
426
427 "_LDR_DATA_TABLE_ENTRY": [None, {
428 "TimeDateStamp": [None, ["WinFileTime"]],
429 "LoadReason": lambda x: x.multi_m("LoadReason", "LoadCount")
430 }],
431
432 '_PHYSICAL_MEMORY_DESCRIPTOR' : [None, {
433 'Run' : [None, ['Array', dict(
434 count=lambda x: x.NumberOfRuns,
435 max_count=100,
436 target='_PHYSICAL_MEMORY_RUN')]],
437 }],
438
439 '_POOL_HEADER': [None, {
440
441 'PoolType': lambda x: x.cast("Enumeration",
442 enum_name="_POOL_TYPE",
443 value=x.m("PoolType")),
444 'Tag': lambda x: str(x.PoolTag.cast("String", length=4)),
445 }],
446
447 '_DISPATCHER_HEADER': [None, {
448 "Type": [None, ["Enumeration", dict(
449 choices=undocumented.ENUMS["_KOBJECTS"],
450 target="unsigned char",
451 )]],
452 }],
453
454 '_CM_NAME_CONTROL_BLOCK' : [None, {
455 'Name' : [None, ['String', dict(length=lambda x: x.NameLength)]],
456 }],
457
458
459 '_MMPTE': [None, {
460 "Long": lambda x: x.multi_m("u.VolatileLong", "u.Long").v(),
461 }],
462
463 '_MMPTE_SOFTWARE': [None, {
464 "Protection": lambda x: x.cast(
465 "Enumeration",
466 choices=MM_PROTECTION_ENUM,
467 value=x.m("Protection")),
468 }],
469
470 '_MMPTE_PROTOTYPE': [None, {
471 "Protection": lambda x: x.cast(
472 "Enumeration",
473 choices=MM_PROTECTION_ENUM,
474 value=x.m("Protection")),
475
476 "Proto": lambda x: x.cast(
477 "Pointer",
478 target="_MMPTE",
479 value=x.m("ProtoAddress"),
480 vm=x.obj_session.GetParameter("default_address_space"),
481 ),
482 }],
483
484 '_MMPTE_SUBSECTION': [None, {
485 "Protection": lambda x: x.cast(
486 "Enumeration",
487 choices=MM_PROTECTION_ENUM,
488 value=x.m("Protection")),
489
490 "Subsection": lambda x: x.cast(
491 "Pointer",
492 target="_SUBSECTION",
493 value=x.m("SubsectionAddress"),
494 ),
495 }],
496
497 '_MMPTE_TRANSITION': [None, {
498 "Protection": lambda x: x.cast(
499 "Enumeration",
500 choices=MM_PROTECTION_ENUM,
501 value=x.m("Protection")),
502 }],
503
504 '_SECTION_OBJECT_POINTERS': [None, {
505 'DataSectionObject': [None, ['Pointer', dict(
506 target="_CONTROL_AREA"
507 )]],
508
509 'SharedCacheMap': [None, ['Pointer', dict(
510 target="_SHARED_CACHE_MAP"
511 )]],
512
513 'ImageSectionObject': [None, ['Pointer', dict(
514 target="_CONTROL_AREA"
515 )]],
516
517 }],
518
519 '_CONTROL_AREA': [None, {
520 'FilePointer': lambda x: x.m('FilePointer').dereference_as(
521 "_FILE_OBJECT"),
522
523
524 'FirstSubsection': lambda x: x.cast(
525 "_SUBSECTION", offset=x.obj_end),
526 }],
527
528 '_SUBSECTION': [None, {
529 'SubsectionBase': [None, ['Pointer', dict(
530 target='Array',
531 target_args=dict(
532 count=lambda x: x.PtesInSubsection.v(),
533 target='_MMPTE'
534 )
535 )]],
536 }],
537
538 '_SHARED_CACHE_MAP': [None, {
539 'Vacbs': [None, ['Pointer', dict(
540 target="Array",
541 target_args=dict(
542 target="Pointer",
543 target_args=dict(
544 target="_VACB"
545 )
546 )
547 )]],
548 }],
549
550 '_VACB_ARRAY_HEADER': [None, {
551 'VACBs': lambda x: x.cast(
552 "Array",
553 offset=x.obj_end,
554 target="_VACB",
555 count=4095
556 ),
557 }],
558 '_PEB32': [None, {
559 "Ldr": [None, ["Pointer32", {
560 "target": "_PEB_LDR_DATA32"
561 }]]
562 }],
563 '_PEB_LDR_DATA32': [48, {
564 "EntryInProgress": [36, ["Pointer32", {
565 "target": "Void"
566 }]],
567 "InInitializationOrderModuleList": [28, ["LIST_ENTRY32", {}]],
568 "InLoadOrderModuleList": [12, ["LIST_ENTRY32", {}]],
569 "InMemoryOrderModuleList": [20, ["LIST_ENTRY32", {}]],
570 "Initialized": [4, ["unsigned char", {}]],
571 "Length": [0, ["unsigned long", {}]],
572 "ShutdownInProgress": [40, ["unsigned char", {}]],
573 "ShutdownThreadId": [44, ["Pointer32", {
574 "target": "Void"
575 }]],
576 "SsHandle": [8, ["Pointer32", {
577 "target": "Void"
578 }]]
579 }],
580 '_LDR_DATA_TABLE_ENTRY32': [76, {
581 "InLoadOrderLinks": [0, ["LIST_ENTRY32", {}]],
582 "InMemoryOrderLinks": [8, ["LIST_ENTRY32", {}]],
583 "InInitializationOrderLinks": [16, ["LIST_ENTRY32", {}]],
584 "DllBase": [24, ["Pointer32", {
585 "target": "Void"
586 }]],
587 "EntryPoint": [28, ["Pointer32", {
588 "target": "Void"
589 }]],
590 "SizeOfImage": [32, ["unsigned long", {}]],
591 "FullDllName": [36, ["_UNICODE_STRING32", {}]],
592 "BaseDllName": [44, ["_UNICODE_STRING32", {}]],
593 "Flags": [52, ["unsigned long", {}]],
594 "LoadReason": [56, ["unsigned short", {}]],
595 "TlsIndex": [58, ["unsigned short", {}]],
596 "HashLinks": [60, ["LIST_ENTRY32", {}]],
597 "TimeDateStamp": [68, ["unsigned long", {}]],
598 "EntryPointActivationContext": [72, ["Pointer32", {
599 "target": "_ACTIVATION_CONTEXT"
600 }]]
601 }]
602 }
603
604 windows_overlay["_RTL_BITMAP_EX"] = windows_overlay["_RTL_BITMAP"]
605
606
607 -class _LDR_DATA_TABLE_ENTRY(obj.Struct):
608
609 @utils.safe_property
611 return unicode(self.BaseDllName)
612
613 @utils.safe_property
615 return int(self.SizeOfImage)
616
617 @utils.safe_property
619 return int(self.DllBase)
620
621 @utils.safe_property
622 - def filename(self):
623 object_tree_plugin = self.obj_session.plugins.object_tree()
624 return object_tree_plugin.FileNameWithDrive(unicode(self.FullDllName))
625
626 @utils.safe_property
628 """The end address of this module's code in memory."""
629 return int(self.DllBase) + int(self.SizeOfImage)
630
631 @utils.safe_property
633 helper = pe_vtypes.PE(address_space=self.obj_vm,
634 image_base=self.DllBase,
635 session=self.obj_session)
636
637 return helper.RSDS
638
641 """Class representing a _UNICODE_STRING
642
643 Adds the following behavior:
644 * The Buffer attribute is presented as a Python string rather
645 than a pointer to an unsigned short.
646 * The __unicode__ method returns the value of the Buffer.
647 """
648
649 - def v(self, vm=None):
660
662
663 return bool(self.Buffer)
664
666 return unicode(self) == utils.SmartUnicode(other)
667
669 return self.v().strip("\x00") or u""
670
672 value = utils.SmartStr(self)
673 elide = ""
674 if len(value) > 50:
675 elide = "..."
676 value = value[:50]
677
678 return "%s (%s%s)" % (super(_UNICODE_STRING, self).__repr__(),
679 value, elide)
680
681 - def write(self, string):
684
686 """A Locally unique identifier."""
687
689 return (self.HighPart.v() << 32) + self.LowPart.v()
690
691
692 -class _SID(obj.Struct):
693 """SID Structure.
694
695 Ref:
696 http://searchwindowsserver.techtarget.com/feature/The-structure-of-a-SID
697 """
698
700 """
701 Ref: RtlConvertSidToUnicodeString
702 http://doxygen.reactos.org/d9/d9b/lib_2rtl_2sid_8c_source.html
703 """
704 wcs = "S-1-"
705
706 if (self.IdentifierAuthority.Value[0] == 0 and
707 self.IdentifierAuthority.Value[1] == 0):
708 wcs += "%lu" % (
709 self.IdentifierAuthority.Value[2] << 24 |
710 self.IdentifierAuthority.Value[3] << 16 |
711 self.IdentifierAuthority.Value[4] << 8 |
712 self.IdentifierAuthority.Value[5])
713 else:
714 wcs += "0x%02hx%02hx%02hx%02hx%02hx%02hx" % (
715 self.IdentifierAuthority.Value[0],
716 self.IdentifierAuthority.Value[1],
717 self.IdentifierAuthority.Value[2],
718 self.IdentifierAuthority.Value[3],
719 self.IdentifierAuthority.Value[4],
720 self.IdentifierAuthority.Value[5])
721
722 for i in self.SubAuthority:
723 wcs += "-%u" % i
724
725 return wcs
726
729 """ An extensive _EPROCESS with bells and whistles """
730
731 @utils.safe_property
733
734 if self.IsWow64:
735 return "I386"
736
737 return self.obj_session.profile.metadata("arch")
738
740 """Validate the _EPROCESS."""
741 pid = self.pid
742
743
744 if pid < 0 or pid > 0xFFFF:
745 return False
746
747
748
749 if ((pid == 0 or self.CreateTime == 0) and
750 self.ImageFileName not in ("Idle", "System")):
751 return False
752
753
754 if self.Pcb.Header.Type != "ProcessObject":
755 return False
756
757 return True
758
759 @utils.safe_property
761 """ Returns a _PEB object which is using the process address space.
762
763 The PEB structure is referencing back into the process address
764 space so we need to switch address spaces when we look at
765 it. This method ensure this happens automatically.
766 """
767 return self.m("Peb").cast("Pointer", target="_PEB",
768 vm=self.get_process_address_space())
769
770 @utils.safe_property
774
775 @utils.safe_property
777 """Returns True if this is a wow64 process.
778
779 We check for a valid or non zero Wow64Process pointer.
780
781 Possible values:
782
783 32 bit OS: Wow64Process is missing from _EPROCESS and therefore this
784 is not a Wow64 process (but it is 32 bits).
785 64 bit OS but Wow64Process is NULL pointer: Not Wow64 process.
786 64 bit OS and Wow64Process is valid: It is a Wow64 process.
787 """
788 return bool(self.Wow64Process.v())
789
790 @utils.safe_property
801
802 @utils.safe_property
804 """Return the full path of image loaded. Obtained via the VAD root."""
805 for vad in self.RealVadRoot.traverse():
806 if (vad.Start <= self.SectionBaseAddress and
807 vad.End >= self.SectionBaseAddress):
808
809 try:
810 file_obj = vad.ControlArea.FilePointer
811 return file_obj.file_name_with_drive()
812 except AttributeError:
813 continue
814
815 return obj.NoneObject()
816
818 return "%s (pid=%s)" % (super(_EPROCESS, self).__repr__(), self.pid)
819
821 """ Gets a process address space for a task given in _EPROCESS """
822 directory_table_base = self.Pcb.DirectoryTableBase.v()
823
824 try:
825 process_as = self.obj_vm.__class__(
826 base=self.obj_vm.base, session=self.obj_vm.session,
827 dtb=directory_table_base)
828 except addrspace.ASAssertionError as e:
829 return obj.NoneObject("Unable to get process AS: %s" % e)
830
831 process_as.name = "Process {0}".format(self.UniqueProcessId)
832
833 return process_as
834
836 """Generator for DLLs in one of the 3 PEB lists"""
837 if self.UniqueProcessId and the_list:
838 if wow64:
839 for l in the_list.list_of_type(
840 "_LDR_DATA_TABLE_ENTRY32", the_type):
841 yield l
842 else:
843 for l in the_list.list_of_type(
844 "_LDR_DATA_TABLE_ENTRY", the_type):
845 yield l
846
848 return chain(
849 self._get_modules(
850 self.Peb.Ldr.InInitializationOrderModuleList,
851 "InInitializationOrderLinks"),
852 self._get_modules(
853 self.Wow64Process.Ldr.InInitializationOrderModuleList,
854 "InInitializationOrderLinks", wow64=True))
855
857 return chain(
858 self._get_modules(
859 self.Peb.Ldr.InMemoryOrderModuleList, "InMemoryOrderLinks"),
860 self._get_modules(
861 self.Wow64Process.Ldr.InMemoryOrderModuleList,
862 "InMemoryOrderLinks", wow64=True))
863
865 return chain(
866 self._get_modules(self.Peb.Ldr.InLoadOrderModuleList,
867 "InLoadOrderLinks"),
868 self._get_modules(self.Wow64Process.Ldr.InLoadOrderModuleList,
869 "InLoadOrderLinks", wow64=True))
870
872 """Return the process's TOKEN object if its valid"""
873
874
875
876 token = self.Token.dereference_as("_TOKEN")
877
878
879
880 if token.is_valid():
881 return token
882
883 return obj.NoneObject("Cannot get process Token")
884
886 """Search the object table and retrieve the object by handle.
887
888 Args:
889 handle: The handle we search for.
890 type: The object will be cast to this type.
891 """
892 for h in self.ObjectTable.handles():
893 if h.HandleValue == handle:
894 if type is None:
895 return h
896 else:
897 return h.dereference_as(type)
898
899 return obj.NoneObject("Could not find handle in ObjectTable")
900
903 """Windows separates processes into Sessions.
904
905 Sessions are logically similar groups of processes (e.g. all created as part
906 of the same RDP login). The virtual address space is divided into three main
907 parts:
908
909 - The process range - This memory is unique to each process.
910
911 - The kernel space - all regular kernel memory is mapped into all processes.
912
913 - The session space - This part of the address space is different for each
914 session, but is shared by all processes in the same session.
915 """
916
918 """Generator for processes in this session.
919
920 A process is always associated with exactly
921 one session.
922 """
923 for p in self.ProcessList.list_of_type(
924 "_EPROCESS", "SessionProcessLinks"):
925 yield p
926
929 """Extension to support retrieving allocations inside the pool.
930
931 Ref for windows memory management:
932 http://illmatics.com/Windows%208%20Heap%20Internals.pdf
933 """
934
936 """Returns the size of the object accounting for pool alignment."""
937 size_of_obj = self.obj_profile.get_obj_size(object_name)
938 pool_align = self.obj_profile.get_constant("PoolAlignment")
939
940
941 extra = size_of_obj % pool_align
942 if extra:
943 size_of_obj += pool_align - extra
944
945 return size_of_obj
946
947 @utils.safe_property
949 pool_align = self.obj_profile.get_constant("PoolAlignment")
950 return self.BlockSize * pool_align
951
953 return self.obj_offset + self.obj_size
954
956 """Return the first object header found.
957
958 Args:
959 type: If specified we only get the object if it belong to this type.
960 freed: If True we consider also freed objects.
961 """
962 for item in self.IterObject(type=type, freed=freed):
963 return item
964
965 return obj.NoneObject("No object found.")
966
968 """Gets the _OBJECT_HEADER considering optional headers."""
969 pool_align = self.obj_profile.get_constant("PoolAlignment")
970 allocation_size = self.BlockSize * pool_align
971
972
973
974 cached_data = self.obj_vm.read(self.obj_offset + self.obj_size,
975 allocation_size)
976 cached_vm = addrspace.BufferAddressSpace(
977 data=cached_data, session=self.obj_session)
978
979
980
981
982
983
984
985 for i in range(0, allocation_size, pool_align):
986
987
988 test_object = self.obj_profile._OBJECT_HEADER(
989 offset=i, vm=cached_vm)
990
991 optional_preamble = max(test_object.NameInfoOffset,
992 test_object.HandleInfoOffset,
993 test_object.QuotaInfoOffset)
994
995
996 if optional_preamble > i:
997 continue
998
999 if test_object.is_valid():
1000
1001 if (type is None or
1002 test_object.get_object_type() == type or
1003
1004 (freed and test_object.Type.v() == 0xbad0b0b0)):
1005 yield self.obj_profile._OBJECT_HEADER(
1006 offset=i + self.obj_offset + self.obj_size,
1007 vm=self.obj_vm, parent=self)
1008
1009 @utils.safe_property
1011 return self.PoolType.v() == 0
1012
1013 @utils.safe_property
1015 return str(self.PoolType).startswith("NonPagedPool")
1016
1017 @utils.safe_property
1019 return str(self.PoolType).startswith("PagedPool")
1020
1021 - def Body(self, type):
1022 return self.obj_profile.Object(type, offset=self.obj_end,
1023 vm=self.obj_vm)
1024
1025
1026 -class _TOKEN(obj.Struct):
1027 """A class for Tokens"""
1028
1030 """Override BaseObject.is_valid with some additional
1031 checks specific to _TOKEN objects."""
1032 return (super(_TOKEN, self).is_valid() and
1033 self.TokenInUse in (0, 1) and self.SessionId < 10)
1034
1036 """Generator for process SID strings"""
1037 if self.UserAndGroupCount < 0xFFFF:
1038 for sa in self.UserAndGroups.dereference():
1039 sid = sa.Sid.dereference_as('_SID')
1040 for i in sid.IdentifierAuthority.Value:
1041 id_auth = i
1042 yield "S-" + "-".join(str(i) for i in (sid.Revision, id_auth) +
1043 tuple(sid.SubAuthority))
1044
1047 """ A class for threads """
1048
1050 """Return the EPROCESS that owns this thread"""
1051 return self.Tcb.ApcState.Process.dereference_as("_EPROCESS")
1052
1054 """Return the EPROCESS that this thread is currently
1055 attached to."""
1056 return self.Tcb.ApcState.Process.dereference_as("_EPROCESS")
1057
1060 """ A class for _HANDLE_TABLE.
1061
1062 This used to be a member of _EPROCESS but it was isolated per issue
1063 91 so that it could be subclassed and used to service other handle
1064 tables, such as the _KDDEBUGGER_DATA64.PspCidTable.
1065 """
1066
1068 """Returns the OBJECT_HEADER of the associated handle. The parent
1069 is the _HANDLE_TABLE_ENTRY so that an object can be linked to its
1070 GrantedAccess.
1071 """
1072 return entry.Object.dereference_as("_OBJECT_HEADER", parent=entry)
1073
1075 """ Returns an array of _HANDLE_TABLE_ENTRY rooted at offset,
1076 and iterates over them.
1077 """
1078
1079
1080
1081 if level == 0:
1082 table = self.obj_profile.Array(
1083 offset=table_offset,
1084 target="_HANDLE_TABLE_ENTRY",
1085 size=0x1000)
1086
1087 for entry in table:
1088 yield self.get_item(entry)
1089
1090 else:
1091 table = self.obj_profile.PointerArray(
1092 offset=table_offset, size=0x1000)
1093
1094 for entry in table:
1095 if entry:
1096 for item in self._make_handle_array(entry, level-1):
1097 yield item
1098
1100 """ A generator which yields this process's handles
1101
1102 _HANDLE_TABLE tables are multi-level tables at the first level
1103 they are pointers to second level table, which might be
1104 pointers to third level tables etc, until the final table
1105 contains the real _OBJECT_HEADER table.
1106
1107 This generator iterates over all the handles recursively
1108 yielding all handles. We take care of recursing into the
1109 nested tables automatically.
1110
1111 Reference:
1112 http://forum.sysinternals.com/hiding-a-process-pspcidtable_topic15362.html
1113 """
1114
1115 LEVEL_MASK = 7
1116
1117 table = self.TableCode & ~LEVEL_MASK
1118 level = self.TableCode & LEVEL_MASK
1119
1120 for i, handle in enumerate(self._make_handle_array(table, level)):
1121
1122 if handle.m("TypeIndex") > 0x0 or handle.m("Type").Name:
1123 handle.HandleValue = i * 4
1124
1125 yield handle
1126
1129 """Subclass the Windows handle table object for parsing PspCidTable"""
1130
1132 p = self.obj_profile.Object("address", entry.Object.v(), self.obj_vm)
1133
1134 handle = self.obj_profile.Object(
1135 "_OBJECT_HEADER",
1136 offset=(p & ~7) - self.obj_profile.get_obj_offset(
1137 '_OBJECT_HEADER', 'Body'),
1138 vm=self.obj_vm)
1139
1140 return handle
1141
1144 """A mixin to be applied on Object Manager Objects."""
1145
1146 @utils.safe_property
1148 return self.obj_profile._OBJECT_HEADER(
1149 self.obj_offset - self.obj_profile.get_obj_size(
1150 "_OBJECT_HEADER"))
1151
1154 """A Rekall Memory Forensics object to handle Windows object headers.
1155
1156 This object applies only to versions below windows 7. (old version
1157 objects). See:
1158 http://codemachine.com/article_objectheader.html
1159 """
1160
1161
1162 type_lookup = dict(
1163 Device="_DEVICE_OBJECT",
1164 Directory="_OBJECT_DIRECTORY",
1165 Driver="_DRIVER_OBJECT",
1166 File="_FILE_OBJECT",
1167 Key="_CM_KEY_BODY",
1168 Mutant="_KMUTANT",
1169 Process="_EPROCESS",
1170 Section="_SECTION_OBJECT",
1171 SymbolicLink="_OBJECT_SYMBOLIC_LINK",
1172 Thread="_ETHREAD",
1173 Token="_TOKEN",
1174 )
1175
1176 optional_headers = [
1177 ('NameInfo', '_OBJECT_HEADER_NAME_INFO', 'NameInfoOffset'),
1178 ('HandleInfo', '_OBJECT_HEADER_HANDLE_INFO', 'HandleInfoOffset'),
1179 ('QuotaInfo', '_OBJECT_HEADER_QUOTA_INFO', 'QuotaInfoOffset')]
1180
1182 self.HandleValue = handle_value
1183 self._preamble_size = 0
1184 super(_OBJECT_HEADER, self).__init__(**kwargs)
1185
1187 header_offset = self.m(member).v()
1188 if header_offset == 0:
1189 return obj.NoneObject("Header not set")
1190
1191 return self.obj_profile.Object(
1192 struct_name, offset=self.obj_offset - header_offset,
1193 vm=self.obj_vm, parent=self)
1194
1195 @utils.safe_property
1197 """The size of the object header is actually the position of the Body
1198 element."""
1199 return self.obj_profile.get_obj_offset("_OBJECT_HEADER", "Body")
1200
1202 """Instantiate an object from the _OBJECT_HEADER.Body"""
1203 return self.obj_profile.Object(
1204 type_name=type_name, offset=self.Body.obj_offset,
1205 vm=vm or self.obj_vm, parent=self)
1206
1208 """Return the object's type as a string"""
1209 type_obj = self.obj_profile._OBJECT_TYPE(
1210 vm=vm or self.obj_session.kernel_address_space,
1211 offset=self.Type)
1212
1213 return type_obj.Name.v()
1214
1215 @utils.safe_property
1217 """Return the object following this header."""
1218 required_type = self.type_lookup.get(self.get_object_type())
1219 if required_type:
1220 return self.Body.cast(required_type)
1221
1222 return obj.NoneObject("Unknown object type")
1223
1224
1225
1226 for _name, _y, _z in _OBJECT_HEADER.optional_headers:
1227 setattr(_OBJECT_HEADER, _name, property(
1228 lambda x, y=_y, z=_z: x._GetOptionalHeader(y, z)))
1232 """A Device Object."""
1233
1236 """Class for file objects"""
1237
1238 @utils.safe_property
1240 """Make a nicely formatted ACL string."""
1241 return (((self.ReadAccess > 0 and "R") or '-') +
1242 ((self.WriteAccess > 0 and "W") or '-') +
1243 ((self.DeleteAccess > 0 and "D") or '-') +
1244 ((self.SharedRead > 0 and "r") or '-') +
1245 ((self.SharedWrite > 0 and "w") or '-') +
1246 ((self.SharedDelete > 0 and "d") or '-'))
1247
1249 """Return the name of the file, prefixed with the name
1250 of the device object to which the file belongs"""
1251 name = u""
1252 if self.DeviceObject:
1253 device_name = self.DeviceObject.ObjectHeader.NameInfo.Name
1254 if device_name:
1255 name = u"\\Device\\{0}".format(device_name)
1256
1257 if self.FileName:
1258 name += unicode(self.FileName)
1259
1260 return name
1261
1263 """Returns the name of the file prepended with the drive letter.
1264
1265 We resolve the drive letter by matching it with the currently assigned
1266 letter to the mounted device. The result of this function should be
1267 usable by file system APIs to open the file on a live system.
1268 """
1269 name = u""
1270 drive_letter_device_map = self.obj_session.GetParameter(
1271 "drive_letter_device_map")
1272
1273 device_obj = self.DeviceObject.deref(vm=vm)
1274 if device_obj:
1275 device_name = device_obj.ObjectHeader.NameInfo.Name
1276 if device_name:
1277 try:
1278 name = u"\\Device\\{0}".format(device_name)
1279 except UnicodeError:
1280 return obj.NoneObject("Invalid filename")
1281
1282 if name in drive_letter_device_map:
1283 name = drive_letter_device_map.get(name)
1284
1285 filename = self.FileName.v(vm=vm)
1286 if filename:
1287 name += unicode(filename)
1288
1289 return name
1290
1294 """Object directories hold other objects.
1295
1296 http://msdn.microsoft.com/en-us/library/windows/hardware/ff557755(v=vs.85).aspx
1297 """
1298
1300 for bucket in self.HashBuckets:
1301 for entry in bucket.walk_list("ChainLink"):
1302 target_obj_header = self.obj_profile._OBJECT_HEADER(
1303 entry.Object.v() - self.obj_profile.get_obj_size(
1304 "_OBJECT_HEADER"))
1305
1306 yield target_obj_header
1307
1310
1312 for item in self:
1313 if item.NameInfo.Name == name:
1314 return item
1315
1316 raise KeyError
1317
1320 """This type allows instantiating an object from its .Object member."""
1321
1322 - def __init__(self, target=None, **kwargs):
1323 self.target = target
1324 super(_EX_FAST_REF, self).__init__(**kwargs)
1325 end_bit = self.RefCnt.end_bit
1326 self.mask = ~ (2 ** end_bit - 1)
1327 self._object = None
1328
1330 if self.Object.v() == 0:
1331 return False
1332
1333 return True
1334
1336 return self.m("Object").obj_offset & self.mask
1337
1338 @utils.safe_property
1340 if self._object is None:
1341 result = self.m("Object")
1342 self._object = result.cast(value=result.v() & self.mask)
1343
1344 return self._object
1345
1355
1365
1368
1369
1370 -class _CM_KEY_BODY(obj.Struct):
1371 """Registry key"""
1372
1373 - def full_key_name(self):
1374 output = []
1375 kcb = self.KeyControlBlock
1376 while kcb.ParentKcb:
1377 if kcb.NameBlock.Name == None:
1378 break
1379 output.append(str(kcb.NameBlock.Name))
1380 kcb = kcb.ParentKcb
1381 return "\\".join(reversed(output))
1382
1385 """The windows Vad tree is basically the same in all versions of windows,
1386 but the exact name of the structs vary with version. This is the base class
1387 for all Vad traversor.
1388 """
1389
1390 tag_map = {'Vadl': '_MMVAD_LONG',
1391 'VadS': '_MMVAD_SHORT',
1392 'Vad ': '_MMVAD',
1393 'VadF': '_MMVAD_SHORT',
1394 'Vadm': '_MMVAD_LONG',
1395 }
1396
1397 left = "LeftChild"
1398 right = "RightChild"
1399
1401 """Traverse an AVL tree - similar to _LIST_ENTRY.list_as_type()."""
1402 relative_offset = self.obj_profile.get_obj_offset(type, member)
1403
1404 for node in self.traverse(type="_RTL_BALANCED_NODE"):
1405 yield self.obj_profile.Object(
1406 type, node.obj_offset - relative_offset)
1407
1408 - def traverse(self, visited=None, depth=0, type=None):
1409 """Traverse the VAD tree.
1410
1411 Generate all the left items, then the right items.
1412
1413 We try to be tolerant of cycles by storing all offsets visited.
1414
1415 If type is specified we always return that type instead of check the
1416 pool tag from the tag_map.
1417
1418 """
1419 if visited == None:
1420 visited = set()
1421
1422 if depth > 100:
1423 self.obj_session.logging.error(
1424 "Vad tree too deep - something went wrong!")
1425 visited.add(self.obj_offset)
1426 return
1427
1428
1429 if self.obj_offset in visited:
1430 return
1431
1432 self.obj_context['depth'] = depth
1433
1434
1435 if type is not None:
1436 yield self.cast(type)
1437
1438 elif self.Tag in self.tag_map:
1439 yield self.cast(self.tag_map[self.Tag])
1440
1441
1442 elif depth and self.Tag.v() != "\x00":
1443 return
1444
1445 for c in self.m(self.left).traverse(visited=visited, depth=depth+1,
1446 type=type):
1447 visited.add(self.obj_offset)
1448 yield c
1449
1450 for c in self.m(self.right).traverse(visited=visited, depth=depth+1,
1451 type=type):
1452 visited.add(self.obj_offset)
1453 yield c
1454
1457
1459 for node in self.traverse(type=self.obj_type):
1460 if node.obj_offset == self.obj_offset:
1461 continue
1462
1463 yield node
1464
1467
1470 @utils.safe_property
1472
1473 self.KiWaitNever = self.obj_profile.get_constant_object(
1474 "KiWaitNever", "unsigned long long")
1475 if not self.KiWaitNever:
1476 return self.m("Dpc")
1477
1478 self.KiWaitAlways = self.obj_profile.get_constant_object(
1479 "KiWaitAlways", "unsigned long long")
1480
1481 return self._DeobfuscateDpc()
1482
1484 return struct.unpack(">Q", struct.pack("<Q", value))[0]
1485
1486 - def _Rol64(self, value, bits):
1487 return ((value << bits % 64) & (2**64-1) |
1488 ((value & (2**64-1)) >> (64-(bits % 64))))
1489
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506 Obfuscated = self.m("Dpc").cast("unsigned long long")
1507
1508 Deobfuscated = Obfuscated ^ self.KiWaitNever
1509 Deobfuscated = self._Rol64(Deobfuscated, 0xFF & self.KiWaitNever)
1510 Deobfuscated = Deobfuscated ^ (self.obj_offset | 0xffff000000000000)
1511 Deobfuscated = self._byteswap(Deobfuscated)
1512 Deobfuscated = Deobfuscated ^ int(self.KiWaitAlways)
1513
1514 return self.obj_profile._KDPC(Deobfuscated, parent=self,
1515 vm=self.obj_vm)
1516
1519 @utils.safe_property
1521 result = self.m("FileObject")
1522 if result == None:
1523 result = self.m('FileObjectFastRef').dereference_as(
1524 "_FILE_OBJECT")
1525
1526 return result
1527
1530
1532 char = ord(self.Buffer[index / 8])
1533 return bool(char & 2 ** (index % 8))
1534
1536 return int(self.SizeOfBitMap)
1537
1539 for i in xrange(len(self)):
1540 yield self[i]
1541
1544 """Install the basic windows overlays."""
1545 profile.add_classes({
1546 '_RTL_BITMAP': _RTL_BITMAP,
1547 '_RTL_BITMAP_EX': _RTL_BITMAP,
1548 '_UNICODE_STRING': _UNICODE_STRING,
1549 '_UNICODE_STRING32': _UNICODE_STRING,
1550 '_EPROCESS': _EPROCESS,
1551 '_ETHREAD': _ETHREAD,
1552 '_HANDLE_TABLE': _HANDLE_TABLE,
1553 '_POOL_HEADER': _POOL_HEADER,
1554 '_OBJECT_HEADER': _OBJECT_HEADER,
1555 '_PSP_CID_TABLE': _PSP_CID_TABLE,
1556 '_FILE_OBJECT': _FILE_OBJECT,
1557 '_DEVICE_OBJECT': _DEVICE_OBJECT,
1558 '_OBJECT_DIRECTORY': _OBJECT_DIRECTORY,
1559 '_EX_FAST_REF': _EX_FAST_REF,
1560 '_CM_KEY_BODY': _CM_KEY_BODY,
1561 '_LDR_DATA_TABLE_ENTRY': _LDR_DATA_TABLE_ENTRY,
1562 '_LDR_DATA_TABLE_ENTRY32': _LDR_DATA_TABLE_ENTRY,
1563 "_MM_SESSION_SPACE": _MM_SESSION_SPACE,
1564 "_RTL_BALANCED_LINKS": _RTL_BALANCED_LINKS,
1565 "_LUID": _LUID,
1566 "_SID": _SID,
1567 "_KTIMER": _KTIMER,
1568 "_SHARED_CACHE_MAP": _SHARED_CACHE_MAP,
1569 "RVAPointer": pe_vtypes.RVAPointer,
1570 "SentinelArray": pe_vtypes.SentinelArray,
1571 "SentinelListArray": pe_vtypes.SentinelListArray,
1572 })
1573
1574 profile.add_overlay(windows_overlay)
1575 profile.add_constant_type(
1576 "MmPfnDatabase", "Pointer", dict(
1577 target="Array",
1578 target_args=dict(
1579 target="_MMPFN"
1580 )
1581 )
1582 )
1583
1584
1585 profile.add_constants(dict(
1586 DRIVER_POOLTAG="Dri\xf6",
1587 EPROCESS_POOLTAG="Pro\xe3",
1588 FILE_POOLTAG="Fil\xe5",
1589 SYMLINK_POOLTAG="Sym\xe2",
1590 MODULE_POOLTAG="MmLd",
1591 MUTANT_POOLTAG="Mut\xe1",
1592 THREAD_POOLTAG='\x54\x68\x72\xe5',
1593 ))
1594
1595
1596 if profile.metadata("arch") == "AMD64":
1597
1598
1599 ki_shared_data_address = 0xFFFFF78000000000
1600 else:
1601
1602 ki_shared_data_address = 0xffdf0000
1603
1604 ki_shared_data_address = profile.integer_to_address(ki_shared_data_address)
1605
1606 def func(profile=profile):
1607 return (profile.get_constant("KI_USER_SHARED_DATA_RAW") -
1608 profile.GetImageBase())
1609
1610 profile.add_constants(
1611 dict(KI_USER_SHARED_DATA_RAW=ki_shared_data_address,
1612 KI_USER_SHARED_DATA=func
1613 )
1614 )
1615