The last post discussed finding object roots in Vista using the self referential semantics of the Kernel Processor Control Region (KPCR). Object roots are the starting points that structural interpretation approaches use to begin to interpret kernel structures, in much the same way that one might use the MBR of a hard disk to find partitions on a drive, or the NTFS boot sector to find the MFT area in a filesystem.
The KPCR scanning approach is general purpose in nature. Assuming an appropriate value for the Directory Table Base of the kernel address space, it will yield potential KPCR structures. It is, however, time consuming. Windbg is able to almost instantly find the KPCR in images stored as dump files, so it obviously isn’t employing scanning as a method of identification.
Looking further into the Microsoft dump file format, the dump file has a header which contains a field called KdDebuggerDataBlock, which is a pointer to the kernel virtual address of a KDDEBUGGER_DATA64 structure. This is the same structure which is the end goal of the KPCR trick.
Accordingly, when run against a dump file, the experimental version of volatility currently uses the KdDebuggerDataBlock as the object root, rather than KPCR.
This is the third of a series of posts describing how the volatility memory forensics application was ported to a new Windows operating system version.
Apart from the inevitable changes in kernel data structures which typically come with a new kernel version, Vista brought with it a change which broke one of volatility’s key techniques for identifying kernel objects. The change was Address Space Layout Randomisation (ALSR). Thanks to Gil Peterson for sharing this detail.
Structural interpretation approaches to volatile memory analysis rely on finding an initial kernel object from which one may traverse to other objects, in order to find objects of interest to the investigator. With XP, volatility employed “the KPCR trick”. XP reliably stored the “Kernel Processor Control Region” at a fixed kernel virtual address (0xffdff000). From the KPCR structure, one then traverses intermediate structures (KdVersionBlock, then DebuggerDataList) to access interesting structures such as the active process list.
In Vista, KPCR is not stored at a fixed address, so the first problem in porting volatility to Vista and above, to reliably get an initial reference to a valid KPCR structure.
Damien Aumaitre points out in his 2009 paper "A little journey inside Windows memory" that KPCR is self referencing. Based on this observation I undertook the following investigations:
1. I loaded up windbg to look at the KPCR of a XP dump file.
4. Note that the first line indicates that KPCR is at VA 0xffdff000, which is to be expected. Note also that the SelfPcr attribute (at offset 0x1c from the start of the structure) has the same value at the address of the KPCR. This is what Aumaitre means by self referencing. There exists an additional self referencing property here related to the Prcb field which I will not go into.
5. Repeating the above on a Vista image gives the following. Note that the KPCR structure is not at 0xffdff000, and again, that the SelfPcr field points to the KPCR address.
kd> !pcr KPCR for Processor 0 at 818f4700: Major 1 Minor 1 NtTib.ExceptionList: 9a7bfcf0 NtTib.StackBase: 00000000 NtTib.StackLimit: 00000000 NtTib.SubSystemTib: 80148000 NtTib.Version: 000c3fac NtTib.UserPointer: 00000001 NtTib.SelfTib: 7ffdf000
With the former in mind, I set about writing a volatility scanner that scans the kernel address space for potential KPCR structures. I note here that in my development I have relied on dump files generated by Matthieu Suiche’s win32dd. Dump files store the physical address of the kernel page directory base, which is enough to reconstruct the kernel address space, however, other means will be necessary if operating on raw (DD) style memory images.
The scanner runs through each kernel address space memory region, looking for memory patterns that match the following constraints:
The VA of the start of candidate bytes >= 0×80000000 (i.e. it is in the kernel address space)
The SelfPcr field at offset 0x1c from the start of the candidate bytes contains a pointer to the virtual address of the start of the KPCR structure
The Prcb field at offset 0×20 within the structure contains a pointer to the start of the _KPRCB structure, which is embedded within the KPCR structure at offset 0×120.
I have observed the above scanning technique to identify one KPCR value per processor, which is consistent with the described function of the KPCR – it is a per processor structure.
The above scanner is usable as the volatility command kpcrscan, and the output of it used via the parameter --kpcr=
An example of usage is presented in the screen capture below:
This post follows on from the last post. In the last post I described how I extended Volatility to work with the symbols for Window XP SP3. In this one, I describe how I applied the approach to Vista SP0.
class VistaSP0x86(xp_sp2.WinXPSP2): """ A Profile for Windows Vista SP0 x86 """ native_types = vtypes.x86_native_types_32bit abstract_types = vista_sp0_x86_vtypes.ntkrnlmp_types overlay = vistasp0x86overlays
The next post will cover the modifications to volatility needed to find KdDebuggerDataBlock – the root of kernel objects required to find active modules and processes amongst other things.