Practical Reverse Engineering Exercise Solutions: Page 35 / Exercise 11
Read the Virtual Memory chapter in Intel Software Developer Manual, Volume 3 and AMD64 Architecture Programmer’s Manual, Volume 2: System Programming. Perform a few virtual address to physical address translations yourself and verify the result with a kernel debugger. Explain how data execution prevention (DEP) works.
For this exercise, we first have to set up a remote kernel debugging session. (see https://codemetrix.net/windows-kernel-debugging-setup/, https://securityblog.gr/3253/debug-user-mode-processes-using-a-kernel-debugger/ and http://securityblog.gr/3023/windows-kernel-debugging/ for excellent explanations)
Local kernel debugging is not an option in this case since examining register contents requires remote kernel debugging. As a reminder, WinDbg has two different commands for inspecting memory contents:
- d* commands (e.g., db): Display memory data at a specified virtual address
- !d* commands (e.g., !db): Display data at a specified physical address
We perform a couple of translations from virtual addresses to physical addresses:
1. Virtual address: 0x8283c054
|
|
The binary representation of this address yields:
10000010100000111100000001010100
By splitting this binary representation into groups, we obtain the indices for the PT:
|
|
The CR3 register contains the base address of the page directory pointer
table (PDPT).
We continue to calculate the PDPT entry:
|
|
Of course, we could employ another program for converting, such as hexadecimal to binary representations. But WinDbg has already implemented a command for this very purpose, namely .formats
.
|
|
The bottom 12 bits of the PDPT entry have to be cleared, which yields:
00000000 00011000 10000000 00000000
Converted to hex: 0x188000
The page directory entry is in turn calculated by adding the index into PD to the PDPT base:
|
|
Converted to binary: 00000000 00011101 00000000 01100011
Similarly to the previous step, we have to clear the lowest 12 bits to calculate the base of the page table (PT):
00000000 00011101 00000000 00000000
Converted to hex: 0x1D0000
The page table entry is calculated as follows:
|
|
Converted to binary: 00000010 10000011 11001001 01100011
Similarly to the previous step, we clear the lowest 12 bits and obtain:
00000010 10000011 11000000 00000000
Converted to hex: 0x283C000
Finally, we can add the page offset to the page entry base to calculate the page’s physical address:
|
|
We can confirm the contents of physical address 0x283c054
and virtual address 0x8283c054
are identical:
|
|
As the manual calculation is a rather cumbersome process, WinDbg has already implemented a function to calculate the physical address of a virtual address. In addition to the virtual address, it requires the base address of the page directory pointer table as an input (https://zerosum0x0.blogspot.de/2015/01/practical-reverse-engineering-p-36-11.html)
|
|
2. Virtual address: 0x83e31738
Nevertheless, we perform another translation from virtual to physical address manually:
|
|
3. How does DEP work?
Processors supporting the PAE
(Physical Address Extension) can set a flag in the page directory entry, which specifies whether or not the contents of the page can be executed. More precisely, bit 63 of the page directory entry sets the NX
flag, which control whether or not instruction fetches from the memory region controlled by this entry are allowed.