In this part we divide memory analysis patterns discerned so far as mostly abnormal software behavior memory dump[58] and software trace[59] patterns into behavioral and structural catalogues. The goal is to account for normal system-independent structural entities and relationships visible in memory like modules, threads, processes and so on.
The first pattern (and also a super-pattern) we discuss here is called Memory Snapshot. It is further subdivided into Structured Memory Snapshot and BLOB Memory Snapshot. Structured sub-pattern includes:
Contiguous memory dump files with artificially generated headers (for example, physical or process virtual space memory dump)
Software trace messages with imposed internal structure
BLOB sub-pattern variety includes address range snapshots without any externally imposed structure, for example, saved by. writemem WinDbg command or ReadProcessMemory API and contiguous buffer and raw memory dumps saved by various memory acquisition tools.
Behavioral patterns that relate to Memory Snapshot pattern are:
False Positive Dump (Volume 1, page 259)
Lateral Damage (Volume 1, page 264)
Inconsistent Dump (Volume 1, page 269)
Truncated Dump (Volume 1, page 340)
Early Crash Dump (Volume 1, page 466)
Manual Dump (kernel) (Volume 1, page 480)
Manual Dump (process) (Volume 1, page 487)
Corrupt Dump (Volume 2, page 151)
No Process Dumps (Volume 2, page 157)
No System Dumps (Volume 2, page 158)
Self-Dump (Volume 2, page 181)
Abridged Dump (page 88)
This pattern is any memory dump or software trace file that is combined from Memory Snapshots (page 343). Typical examples include:
A minidump file where only specific memory ranges are included
A software trace file combined from structured memory snapshots
This pattern is a collection of files combined from either linear memory snapshots or aggregate snapshots saved as separate files at different times. Typical examples include:
Several process memory dump files saved sequentially from a growing heap leaking process
Several software traces from working and non-working scenarios for comparative analysis
Now we propose the next group of general patterns related to memory regions (the terminology was partially influenced from topology[60]). The first one we call Memory Region, for example:
1: kd> dp fffff88005875000 fffff88005875010 fffff880`05875000 039b5000`6e696268 00000000`00002000 fffff880`05875010 00000000`00000000
There are Open and Closed memory regions. We can extend the former ones in one or both directions:
1: kd> dp fffff88005875000-10 fffff88005875010+10 fffff880`05874ff06ab90c4f`039ba1b8 039b8050`fffffff8
fffff880`05875000 039b5000`6e696268 00000000`00002000 fffff880`05875010 00000000`0000000000000000`00000000
fffff880`0587502000000294`ffffffd0
The closed regions cannot be read past their boundary, like this kernel stack region [fffff880`05874000 fffff8800587d000):
msieftp!InternetCloseHandleWrap :1 kd> dp fffff88005874000-30fffff880`05873fd0 ????????`???????? ????????`???????? fffff880`05873fe0 ????????`???????? ????????`???????? fffff880`05873ff0 ????????`???????? ????????`????????
fffff880`05874000 039ba000`6e696268 00000000`00001000 fffff880`05874010 00000000`00000000 00000000`00000000 fffff880`05874020 00206b6e`ffffffa8 01cae7bd`b8aca323 fffff880`05874030 039b6698`00000000 00000000`00000001 fffff880`05874040 ffffffff`039bafe8 039b6710`00000004 1: kd> dp fffff8800587d000-30 fffff880`0587cfd0 00000000`00000000 00000000`00000000 fffff880`0587cfe0 00000000`00000000 00000000`00000000 fffff880`0587cff0 00000000`00000000 00000000`00000000fffff880`0587d000 ????????`???????? ????????`???????? fffff880`0587d010 ????????`???????? ????????`???????? fffff880`0587d020 ????????`???????? ????????`???????? fffff880`0587d030 ????????`???????? ????????`???????? fffff880`0587d040 ????????`???????? ????????`????????
The next pattern is called Region Boundary. It is an inaccessible range of memory that surrounds Closed Memory Region (page 347). For example, the closed region of a kernel stack for the following thread has a one page boundary region next to its Base:
1: kd> !thread THREAD fffffa8004544b60 Cid 0a6c.0acc Teb: 000007fffffde000 Win32Thread: fffff900c1eb4010 RUNNING on processor 1 IRP List: fffffa8004d7e010: (0006,0118) Flags: 00060000 Mdl: 00000000 Not impersonating DeviceMap fffff8a001e84c00 Owning Process fffffa8004f68370 Image: NotMyfault.exe Attached Process N/A Image: N/A Wait Start TickCount 40290 Ticks: 0 Context Switch Count 408 LargeStack UserTime 00:00:00.015 KernelTime 00:00:00.015 Win32 Start Address NotMyfault (0x0000000140002708) Stack Init fffff8800587cdb0 Current fffff8800587c6f0Base fffff8800587d000
Limit fffff88005874000 Call 0 [...] 1: kd> !pte fffff880`0587d000 VA fffff8800587d000 PXE at FFFFF6FB7DBEDF88 PPE at FFFFF6FB7DBF1000 PDE at FFFFF6FB7E200160 PTE at FFFFF6FC4002C3E8 contains 0000000133D84863 contains 0000000133D83863 contains 00000000AA9AE863 contains 0000000000000000 pfn 133d84 ---DA--KWEV pfn 133d83 ---DA--KWEV pfn aa9ae ---DA--KWEV1: kd> !pte fffff880`0587d000+
not valid
-1 VA fffff8800587dfff PXE at FFFFF6FB7DBEDF88 PPE at FFFFF6FB7DBF1000 PDE at FFFFF6FB7E200160 PTE at FFFFF6FC4002C3E8 contains 0000000133D84863 contains 0000000133D83863 contains 00000000AA9AE863 contains 0000000000000000 pfn 133d84 - DA- KWEV pfn 133d83 - DA- KWEV pfn aa9ae - DA- KWEV
0n4096
1: kd> !pte fffff880`0587d000+
not valid
0n4096
VA fffff8800587e000
PXE at FFFFF6FB7DBEDF88 PPE at FFFFF6FB7DBF1000 PDE at FFFFF6FB7E200160 PTE at FFFFF6FC4002C3F0 contains 0000000133D84863 contains 0000000133D83863 contains 00000000AA9AE863 contains 8000000028230963 pfn 133d84 - DA- KWEV pfn 133d83 - DA- KWEV pfn aa9ae - DA- KWEVpfn 28230 -G-DA- KW-V
The region after boundary belongs to another process thread kernel stack (I use CodeMachine WinDbg extension[61] here):
1: kd> !cmkd.kvas fffff8800587e000
kvas : Show region containing fffff8800587e000
### Start End Length Type
006 fffff88000000000 fffff89fffffffff 2000000000 ( 128 GB) SystemPTEs
Thread FFFFFA80053D0B60 [0798.0a5c] Stack fffff88005884000 - fffff8800587e000
1: kd> !thread FFFFFA80053D0B60
THREAD fffffa80053d0b60 Cid 0798.0a5c Teb: 000007fffffdd000 Win32Thread:
0000000000000000 WAIT: (DelayExecution) UserMode Non-Alertable
fffffa80053d0f20 Semaphore Limit 0x1
Not impersonating
DeviceMap fffff8a001e84c00
Owning Process fffffa80053ce630 Image: ApplicationB.exe
Attached Process N/A Image: N/A
Wait Start TickCount 34911 Ticks: 5379 (0:00:01:23.912)
Context Switch Count 22
UserTime 00:00:00.000
KernelTime 00:00:00.000
Win32 Start Address 0x000000013fe01538
Stack Init fffff88005883db0 Current fffff88005883970
Base fffff88005884000 Limit fffff8800587e000
Call 0
[...]
Typical examples of this pattern include a complete memory dump with a physical to virtual mapping and paged out memory. Please note that page files are optional and paging can be implemented without a page file. There can be several layers of hierarchy, for example:
physical memory
virtualized physical memory
virtual memory
Another example is from the protected mode x86 architecture:
physical memory
linear memory (paging, virtual)
logical memory (segments)
In order to start the analysis of a structured memory snapshot (page 343) a debugger engine needs Anchor Region that describes memory layout and where to start unfolding of analysis. For example, it can be a list of modules (another forthcoming structural pattern). We can observe the importance of such regions when we try to open corrupt or severely truncated memory dumps (Volume 2, page 151):
[...] KdDebuggerDataBlock is not present or unreadable. [...] Unable to read PsLoadedModuleList [...]
For certain types of memory snapshots (like software traces) an anchor region coinsides with its structure description (message trace format for structured snap-shots) and a trace file header (if any) for aggregate snapshots (page 345).
3.129.45.150