Windows Executive Objects
Kernel Pool Allocations
Pool Tag Scanning
Finding Objects in memory
Windows New Technology (NT) is the family of products from Microsoft
Windows NT 3.1 first OS in 1993
NT still in product version string, but does not refer to anything in product naming.
NT* represents Kernel mode in Windows and is still used for the API
Every resource is an object consisting of data and methods to manipulate them
Microsoft has a naming convention for their API that adds a prefix to the identifier name to indicate its functionality type.
The creator of this scheme, Dr. Charles Simonyi, was from Hungary, hence Hungarian Notation.
Microsoft keeps a list of their coding conventions here and their coding style conventions here.
Understand the basic prefixes for Hungarian notation.
| Prefix | Description |
|----------|----------------|
| b | BOOL |
| c | char |
| cb | count of bytes |
| dw | DWORD |
| h | Handle |
| i | Integer |
| lp | long pointer |
| str | string |
| lpstr | lp to ASCII str|
| lpvoid | void* |
BOOL WINAPI CreateProcess(
_In_opt_ LPCTSTR lpApplicationName,
_Inout_opt_ LPTSTR lpCommandLine,
_In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
_In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
_In_ BOOL bInheritHandles,
_In_ DWORD dwCreationFlags,
_In_opt_ LPVOID lpEnvironment,
_In_opt_ LPCTSTR lpCurrentDirectory,
_In_ LPSTARTUPINFO lpStartupInfo,
_Out_ LPPROCESS_INFORMATION lpProcessInformation
);
Contains Kernel and Windows Executive layers of Windows NT
Object Management
Security and Process Management
Cache Manager
Nt or Zw API routines go through ntdll.dll and run in th kernel.
Kernel drivers can call them directly whereas user-mode applications use normal system calls.
Kernel32.CreateFileA -> NtCreateFile
Zw has no significance and was just added to avoid naming conflicts.
There are Ansi and Unicode versions for most API calls
Upper level of Ntoskrnl.exe
Contains base OS services
Process/Thread management
Security Reference Monitor
I/O System
Exported functions via Ntdll.dll
DeviceIoControl
Kernel mode functions through Windows Driver Development Kit
Memory Manager
Virtual memory management and support for cache management.
Object Management
Create, manage and delete Windows Executive Objects to represent system resources.
Configuration Manager for system registry
Lower level of Ntoskrnl.exe
Thread scheduling
Synchronization
Interrupt and Exception dispatching
Does not make policies... tasked to Executive
Kernel Objects encapsulated by Executive Objects
Structure → Executive Object
25+ Objects
| Object Name | Strucutre | Description |
|--------------|----------------------|----------------------------------------------------------------------------|
| File | _FILE_OBJECT |Instance of an open file |
| Process | _EPROCESS |Container that allows threads to execute in a private virtual address space.|
| SymbolicLink | _OBJECT_SYBOLIC_LINK |Alias to map network share paths and removable media |
| Token | _TOKEN |Security information such as SID and privileges for processes and threads |
| Thread | _ETHREAD |Scheduled execution entry and its CPU context |
| Mutant | _KMUTANT |Mutal exclision and is used for synchronization |
Created by environment subsystem user application
WINAPI functions create a ton CreateMutext creates a Mutant object
Display information on NT Object Manager.
The object management maintains an internal namespace for OS components, drivers and programs.
All addresses and structure layouts differ between versions of Windows
Service Packs are known to change memory layout of key structures
Several structures are undocumented
Microsoft adds and removes information from everything all the time
My slides will differ from your output of a structure and I cannot cover all possibilities
State information used by the Object Manger
Common to all objects
Up to four optional headers
Precedes the the executive object structure
Weirdly enough, also precedes optional headers
Constant offsets between header and optional headers.
Following the header is the object body for the executive object
TName, Quota, Handle, and Creator information headers. executive object = file, proces, symlink, etc. Optional Headers located at a negative offset from start of Object Header
>>> dt("_OBJECT_HEADER")
'_OBJECT_HEADER' (32 bytes)
0x0 : PointerCount ['long']
0x4 : HandleCount ['long']
0x4 : NextToFree ['pointer', ['void']]
0x8 : Lock ['_EX_PUSH_LOCK']
0xc : TypeIndex ['unsigned char']
0xd : TraceFlags ['unsigned char']
0xe : InfoMask ['unsigned char']
0xf : Flags ['unsigned char']
0x10 : ObjectCreateInfo ['pointer', ['_OBJECT_CREATE_INFORMATION']]
0x10 : QuotaBlockCharged ['pointer', ['void']]
0x14 : SecurityDescriptor ['pointer', ['void']]
0x18 : Body ['_QUAD']
Pointer Count
Handle Count
Type Index
Info Mask
Body
_OBJECT_HEADER.InfoMask tells us what optional headers are present above the object header
0x1 – CREATOR_INFO
0x2 - NAME_INFO
0x4 – HANDLE_INFO
0x8 – QUOTA_INFO
0x10 – PROCESS_INFO
0x20 - AUDIT_INFO
Index into nt!ObTypeIndexTable array of Type Objects
Common meta-data for all objects of said type.
'_OBJECT_TYPE' (136 bytes)
0x0 : TypeList ['_LIST_ENTRY']
0x8 : Name ['_UNICODE_STRING']
0x10 : DefaultObject ['pointer', ['void']]
0x14 : Index ['unsigned char']
0x18 : TotalNumberOfObjects ['unsigned long']
0x1c : TotalNumberOfHandles ['unsigned long']
0x20 : HighWaterNumberOfObjects ['unsigned long']
0x24 : HighWaterNumberOfHandles ['unsigned long']
0x28 : TypeInfo ['_OBJECT_TYPE_INITIALIZER']
0x78 : TypeLock ['_EX_PUSH_LOCK']
0x7c : Key ['String', {'length': 4}]
0x80 : CallbackList ['_LIST_ENTRY']
Name: String of object type. Process, File, etc.
TotalNumberOfObjects: Count of objects of this type on system.
TotalNumberOfHandles: Total handles open to this object type on the system
TypeInfo: Type of memory used to allocate object. Paged, Nonpaged. Flags, Type codes, access mask (rwx).
Key: Four-byte tag used to mark memory allocations for this object type.
TypeInfo is the where and Key is the what.
Scan for Windows object type objects by enumerating Nt!ObTypeIndexTable
Scans for _OBJECT_TYPE
[root&windows]#volatility -f sample002.bin --profile=Win7SP0x86 objtypescan
Offset nObjects nHandles Key Name PoolType
---------- ---------- ---------- -------- ------------------------------ --------------------
0x3f2927c8 0x10 0x10 PcwO PcwObject PagedPool
0x3f4ad6b0 0x0 0x0 Filt FilterConnectionPort NonPagedPool
0x3f4b26b0 0x0 0x0 Filt FilterCommunicationPort NonPagedPool
0x3ff070f8 0x75d 0x6b5 EtwR EtwRegistration NonPagedPool
0x3ff07bb0 0x11 0x11 WmiG WmiGuid NonPagedPool
0x3ff08040 0x6 0x6 EtwC EtwConsumer NonPagedPool
0x3ff599d0 0x5 0x1 Powe PowerRequest NonPagedPool
0x3ff66330 0x10c0 0x1125 Even Event NonPagedPool
0x3ff68350 0x35f 0x361 Sema Semaphore NonPagedPool
0x3ff68418 0x10 0x0 Call Callback NonPagedPool
0x3ff69350 0x0 0x0 Prof Profile NonPagedPool
0x3ff69418 0xba 0xba Time Timer NonPagedPool
0x3ff6b3c0 0x120b 0x3ae File File NonPagedPool
0x3ff6b488 0x6b 0x64 IoCo IoCompletion NonPagedPool
0x3ff6b550 0x7c 0x0 Driv Driver NonPagedPool
0x3ff6b618 0x1a4 0x0 Devi Device NonPagedPool
Range of memory divided into small blocks for storing data from kernel components.
_POOL_HEADER sits above any optional headers from _OBJECT_HEADER
'_POOL_HEADER' (8 bytes)
0x0 : PoolIndex #Total size of allocation including all of the object information
0x0 : PreviousSize
0x0 : Ulong1
0x2 : BlockSize
0x2 : PoolType #Type of system memory. A lot of objects are allocated using nonpageable memory
0x4 : AllocatorBackTraceIndex
0x4 : PoolTag #Four-byte value to identify code path taken to produce the allocation
0x6 : PoolTagHash
Any instance of an object must be allocated by the kernel from an OS memory pool.
Ntoskrnl.ExAllocatePoolWithTag
PVOID ExAllocatePoolWithTag(
_In_ POOL_TYPE PoolType,
_In_ SIZE_T NumberOfBytes,
_In_ ULONG Tag
);
Tag comes from _OBJECT_TYPE.Key and needs to match the tag used with ExAllocatePoolWithTag to safeguard memory
ObCreateObject is an undocumented function that creates executive objects.
Size of executive objects + size of _OBJECT_HEADER + size of Optional Headers
When a process no longer needs a handle, it is deallocated with CloseHandle()
BOOL WINAPI CloseHandle(
_In_ HANDLE hObject
);
Block of memory returns to free list
Contents of memory still intact until overwritten.
Object still resident in RAM.
It is worth noting that Kernel mode objects are freed with ExFreePoolWithTag which sometimes leaves a protected bit in the tag.
Ntoskrnl.lib
VOID ExFreePoolWithTag(
_In_ PVOID P,
_In_ ULONG Tag
);
Search memory for four-byte tags from allocation of executive objects.
Finds historical objects
Finds hidden objects from anti-techniques
Can't just look for “Proc”... might not be _EPROCESS.
More or less brute forcing all of memory!
Find unlinked, linked and unreachable objects!
For example, a terminated process is no longer in the PsActiveProcessList, but an EPROCESS strucutre is still in memory somewhere!
Robust signatures to determine if an object actually exists. . .
Pooltag.txt from Drive Development Kit lists them... there are A LOT.
PoolMon.exe
c:\bin\poolmon.exe
Memory: 260620K Avail: 96364K PageFlts: 0 InRam Krnl: 1916K P:17856K
Commit: 203500K Limit: 640916K Peak: 260632K Pool N: 8332K P:27220K
System pool information
Tag Type Allocs Frees Diff Bytes Per Alloc
Wait Nonp 3971107 ( 0) 3971077 ( 0) 30 8456 ( 0) 281
ObSt Nonp 2791258 ( 0) 2791258 ( 0) 0 0 ( 0) 0
Gxlt Paged 1161638 ( 0) 1161630 ( 0) 8 864 ( 0) 108
Ustm Paged 1088342 ( 0) 1088298 ( 0) 44 2464 ( 0) 56
Io Nonp 1021112 ( 1) 1020985 ( 1) 127 91912 ( 0) 723
Pool tag information still in memory (What poolmon uses)
_KDDEBUGGER_DATA64._POOL_TRACKER_TABLE
'_POOL_TRACKER_TABLE' (28 bytes)
0x0 : Key ['String', {'length': 4}]
0x4 : NonPagedAllocs ['long']
0x8 : NonPagedFrees ['long']
0xc : NonPagedBytes ['unsigned long']
0x10 : PagedAllocs ['unsigned long']
0x14 : PagedFrees ['unsigned long']
0x18 : PagedBytes ['unsigned long']
PoolMon in memory implemented in Volatility
Show a summary of pool tag usage
Size per allocation:
Gives size of each allocation for a robust pool scanner.
[root&windows]#volatility -f sample002.bin --profile=Win7SP0x86 pooltracker
Tag NpAllocs NpFrees NpBytes PgAllocs PgFrees PgBytes Driver
------ -------- -------- -------- -------- -------- -------- --------------------
Io 67539 66947 55576 27308 27303 224
Even 62482 58194 275952 0 0 0
File 61964 57345 822824 0 0 0
SeTl 27610 26517 69952 0 0 0
Vad 14588 10225 314136 0 0 0
FOCX 12505 12411 4512 0 0 0
usbp 11537 11422 90208 51 49 96
Wait 11179 11124 21704 0 0 0
#Note: I used pooltracker and performed sed and sort on the data to get
#the number of NpAllocs in sorted order.
NP = nonpaged P = paged
Robust signature by ensuring adjacent memory near a pool is valid.
OBJECT_HEADER + POOL_HEADER + Executive Object = Size
Similar to total size per allocation from previous slide.
| Object Name | Plugin |
|----------------|-------------|
| Process | psscan |
| Threads | thrdscan |
| Desktops | deskscan |
| Window Station | wndscan |
| Mutants | mutantscan |
| File | filescan |
| Drivers | driverscan |
| Symbolic Links | symlinkscan |
Untagged memory
False positives
Large Allocations
Decoy Tags
Arbitrary Tags (“Ddk” for drivers)
Manipulated tag
[root&windows]#volatility -f Win7.bin --profile=Win7SP0x86 filescan
Volatility Foundation Volatility Framework 2.4
Offset(P) #Ptr #Hnd Access Name
------------------ ------ ------ ------ ----
0x000000003da00038 1 1 R--rw- \Device\HarddiskVolume1\Windows\winsxs\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.7601.17514_none_41e6975e2bd6f2b2
0x000000003da00730 8 0 R--rw- \Device\HarddiskVolume1\Users\Daniel\AppData\Local\Microsoft\Windows\Temporary Internet Files\Low\Content.IE5\LW3MMD1X\widgets[1].js
0x000000003da00b88 7 0 R--r-d \Device\HarddiskVolume1\Windows\System32\srchadmin.dll
0x000000003da00c40 4 0 R--r-d \Device\HarddiskVolume1\Windows\System32\dssenh.dll
0x000000003da00ec8 8 0 R--rw- \Device\HarddiskVolume1\Users\Daniel\AppData\Local\Microsoft\Windows\Temporary Internet Files\Low\Content.IE5\UWEOZDSW\client[1].js
0x000000003da012b0 8 0 R--r-d \Device\HarddiskVolume1\Users\Daniel\AppData\Local\Microsoft\Windows\Temporary Internet Files\Low\Content.IE5\47XIWBRS\hub[1].htm
0x000000003da01be0 6 0 R--r-d \Device\HarddiskVolume1\Windows\System32\QAGENTRT.DLL
0x000000003da02188 4 0 RW-rwd \Device\HarddiskVolume1\$Directory
0x000000003da03748 8 0 R--r-d \Device\HarddiskVolume1\Users\Daniel\AppData\Local\Microsoft\Windows\Temporary Internet Files\Low\Content.IE5\7SYX623H\xd_arbiter[1].htm
[root&windows]#volatility -f Win7.bin --profile=Win7SP0x86 dumpfiles -Q 0x000000003da03748 -D html/
Volatility Foundation Volatility Framework 2.4
DataSectionObject 0x3da03748 None \Device\HarddiskVolume1\Users\Daniel\AppData\Local\Microsoft\Windows\Temporary Internet Files\Low\Content.IE5\7SYX623H\xd_arbiter[1].htm
We can now open that file
<!DOCTYPE html><html><head><title>Facebook Cross-Domain Messaging helper</title></head><body><script> document.domain = 'facebook.com'; var ES5 = function(){
__d("ES5ArrayPrototype",[],function(a,b,c,d,e,f){var g={};g.map=function(h,i){if(typeof h!='function')throw new TypeError();var j,k=this.length,l=new Array(k);for(j=0;j<k;++j)if(j in this)l[j]=h.call(i,this[j],j,this);return l;};g.forEach=function(h,i){g.map.call
-- CUT --
Cached files appear in memory dumps and can be recovered using Dumpfiles.
Dumpfiles iterates through the VAD and extracts all files that are mapped as DataSectionObject, ImageSectionObject or SharedChacheMap.
-r REGEX, --regex=REGEX
Dump files matching REGEX
-i, --ignore-case Ignore case in pattern match
-o OFFSET, --offset=OFFSET
Dump files for Process with physical address OFFSET
-Q PHYSOFFSET, --physoffset=PHYSOFFSET
Dump File Object at physical address PHYSOFFSET
-D DUMP_DIR, --dump-dir=DUMP_DIR
Directory in which to dump extracted files
-S SUMMARY_FILE, --summary-file=SUMMARY_FILE
File where to store summary information
-p PID, --pid=PID Operate on these Process IDs (comma-separated)
-n, --name Include extracted filename in output file path
-u, --unsafe Relax safety constraints for more data
-F FILTER, --filter=FILTER
Filters to apply (comma-separated)
Dumped files are shown as file.[PID].[OFFSET].[EXT] OR named if -n is used.
Scan for symbolic link objects
-V, --virtual Scan virtual space instead of physical
-W, --show-unallocated
Skip unallocated objects (e.g. 0xbad0b0b0)
-A START, --start=START
The starting address to begin scanning
-G LENGTH, --length=LENGTH
Length (in bytes) to scan from the starting address
[root&windows]#volatility -f Win7.bin --profile=Win7SP0x86 symlinkscan
Volatility Foundation Volatility Framework 2.4
Offset(P) #Ptr #Hnd Creation time From To
------------------ ------ ------ ------------------------------ -------------------- ------------------------------------------------------------
0x0000000002de3278 1 0 2013-10-15 18:45:58 UTC+0000 Global \Global??
0x00000000030b40a8 1 0 2013-10-15 18:45:46 UTC+0000 DosDevices \??
0x00000000030b8470 1 0 2013-10-15 18:45:46 UTC+0000 Global \GLOBAL??
0x000000000f3c77d8 1 0 2013-10-15 18:45:59 UTC+0000 Z: \Device\hgfs\;Z:0000000000027f8d\vmware-host\Shared Folders
0x00000000122c0ce8 1 0 2013-10-15 18:45:53 UTC+0000 Local \BaseNamedObjects
0x0000000012474030 1 0 2013-10-15 18:46:00 UTC+0000 UMB#UMB#1...e1ba19f} \Device\00000069
0x0000000012dca868 1 0 2013-10-15 18:45:56 UTC+0000 $VDMLPT1 \Device\ParallelVdm0
Photos snipped from Windows Internals 6th Edition Volume 1 & 2, David Solomon and Mark Russinovich.
Table of Contents | t |
---|---|
Exposé | ESC |
Full screen slides | e |
Presenter View | p |
Source Files | s |
Slide Numbers | n |
Toggle screen blanking | b |
Show/hide slide context | c |
Notes | 2 |
Help | h |