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
kd> db 8283c054 L8
8283c054 72 6f 67 72 61 6d 20 63 rogram c
The binary representation of this address yields:
10000010100000111100000001010100
By splitting this binary representation into groups, we obtain the indices for the PT:
10 000010100 000111100 000001010100
Index into page directory pointer table (PDPT): 10 (0x2)
Index into page directory (PD): 000010100 (0x14)
Index into page table (PT):000111100 (0x3C)
Page offset: 000001010100 (0x54)
kd> r @cr3
cr3=00185000
The CR3 register contains the base address of the page directory pointer table (PDPT).
We continue to calculate the PDPT entry:
kd> !dq @cr3+2*8 L1
# 185010 00000000`00188001
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.
kd> .formats 00000000`00188001
Evaluate expression:
Hex: 00188001
Decimal: 1605633
Octal: 00006100001
Binary: 00000000 00011000 10000000 00000001
Chars: ....
Time: Mon Jan 19 15:00:33 1970
Float: low 2.24997e-039 high 0
Double: 7.93288e-318
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:
kd> !dq 188000+0x14*8 L1
# 1880a0 00000000`001d0063
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:
kd> !dq 1D0000+0x3C*8 L1
# 1d01e0 00000000`0283c963
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:
kd> !db 0x283C000+0x54 L8
# 283c054 72 6f 67 72 61 6d 20 63 rogram c .L.....
We can confirm the contents of physical address 0x283c054 and virtual address 0x8283c054 are identical:
kd> db 0x8283c054 L8
8283c054 72 6f 67 72 61 6d 20 63 rogram c
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)
kd> !vtop 00185000 8283c054
X86VtoP: Virt 8283c054, pagedir 185000
X86VtoP: PAE PDPE 185010 - 0000000000188001
X86VtoP: PAE PDE 1880a0 - 00000000001d0063
X86VtoP: PAE PTE 1d01e0 - 000000000283c963
X86VtoP: PAE Mapped phys 283c054
Virtual address 8283c054 translates to physical address 283c054.
Nevertheless, we perform another translation from virtual to physical address manually:
2) Virtual address: 0x83e31738
kd> db 83e31738 L8
83e31738 41 db e8 59 e9 0c 00 00
Binary representation of virtual address:
10 000011111 000110001 011100111000
PDPT Index: 0x2
PD Index: 0x1F
PT Index: 0x31
Page Offset: 0738
kd> r @cr3
cr3=00185000
PDPT base:
kd> !dq @cr3+0x2*8 L1
# 185010 00000000`00188001
Binary: 110001000000000000001
Truncated: 110001000000000000000 (0x188000)
kd> !dq 188000+0x1F*8 L1
# 1880f8 00000000`1ff80863
Binary: 11111111110000000100001100011
Truncated: 11111111110000000000000000000 (0x1FF80000)
PT Base:
kd> !dq 0x1FF80000+0x31*8 L1
#1ff80188 00000000`1fc31963
Binary: 11111110000110001100101100011
Truncated: 11111110000110001000000000000 (0x1FC31000)
Physical address and contents:
kd> !db 1FC31000+0x738 L8
#1fc31738 41 db e8 59 e9 0c 00
How does DEP work?
No comments:
Post a comment