Windows内核实验:零地址读写

Windows内核实验:零地址读写

以后都是pae模式下的实验

零地址就是我们的空指针指向的位置嘛,0这块地址(准确的说应该是这一个页)本身就会被标记为不可访问,以便为空指针检测提供些支持,肯定是不能读或写的

kd> !pte 0
VA 00000000
PDE at C0600000 PTE at C0000000
contains 0000000008381067 contains 0000000000000000
pfn 8381 ---DA--UWEV not valid

但是他毕竟也是进程虚拟内存的一块嘛,虚拟内存都是靠页目录表项和页表项描述的,去把他映射到物理内存,所有理论上把他的页表项的改掉就可以搞事情

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#define PDE(x) (DWORD64 *) (((x >> 21) << 3) + 0xc0600000)
#define PTE(x) (DWORD64 *) (((x >> 12) << 3) + 0xc0000000)
//004197B0
DWORD g_var = 0x12345678;
void __declspec(naked) IdtEntry() {//裸函数不会帮我们生成栈帧,单纯一个call
*PTE(0) = *PTE(0x04197B0);
__asm {
iretd
}
}
void interrupt() {
__asm {
int 0x20
}
}
int main() {
if (0x401040 != IdtEntry) {
printf("IdtRntry address wrong");
system("pause");
exit(-1);
}
//eq 8003f500 0040ee00`00081040
interrupt();
printf("&g_var:%p\n",&g_var);
printf("g_var:%x\n",g_var);
printf("0:%x\n",*(DWORD*)0);
printf("0x7b0:%x\n",*(DWORD *)0x7b0);
*(DWORD*)0x7b0 = 0xffffff;
printf("g_var:%x\n",g_var);
system("pause");
}
&g_var:004197B0
g_var:12345678
0:462aabc5
0x7b0:12345678
g_var:ffffff
请按任意键继续. . .

由于页表项描述的是4k大小页面,所以相当于00419000-0041a000和0-1000处映射到同一块物理页面