驱动挂载物理页代码示例

驱动挂载物理页代码示例

使用的实验环境为32位xp系统在101012分页模式下

此实验用于测试对分页模式的掌握程度

代码思路如下:

  1. 获取目标进程的cr3
  2. 在目标进程中申请新的物理页
  3. 拆分新申请的物理页的线性地址
  4. 通过差分出的内容获取pte
  5. 将pte写入到要挂载的线性地址的pte中(这个线性地址也可以为不同cr3中的线性地址,这种情况下就可以两个进程共享同一物理页但是要把pte和pde都挂载好)
  6. 此时目标线性地址和新申请的线性地址映射为同一物理页

样例代码:

#include 
#define NTSTRSAFE_LIB
#include 
#include 

VOID Unload(PDRIVER_OBJECT pDriver) {
	KdPrint(("unload"));
	
}

NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pRegPath) {
	NTSTATUS status = STATUS_SUCCESS;
	pDriver->DriverUnload = Unload;
	KdPrint(("begin"));
	//417   01 00 17
	DWORD32 new_va = 0x417000;
	DWORD32 new_cr3 = 0x02e96000;
	DWORD32 old_cr3 = 0x0;
	DWORD32* pdt_va = (DWORD32*)0xc0300000;
	UCHAR* ptt_va = (UCHAR*)0xc0000000;

	//拆分new_va
	KdPrint(("开始拆分线性地址"));
	DWORD32 new_va_10_1 = new_va >> 0x16;
	DWORD32 new_va_10_2 = new_va << 0xa;
	new_va_10_2 >>= 0x16;
	DWORD32 new_va_12 = new_va && 0x00000fff;
	KdPrint(("10:0x%x, 10:0x%x, 12:0x%x \r\n", new_va_10_1, new_va_10_2, new_va_12));
	//挂载物理页
	KdPrint(("开始挂载物理页"));
	KIRQL irql = KeRaiseIrqlToDpcLevel();
	old_cr3 = __readcr3();
	__writecr3(new_cr3);
	KeLowerIrql(irql);

	DWORD32* pte = (ptt_va + ((new_va_10_1 << 12) + (new_va_10_2 << 2)));
	KdPrint(("0x%p\r\n",pte));
	DWORD32* new_pte = (DWORD32*)(ptt_va + 4);
	KdPrint(("0x%p\r\n", new_pte));
	*new_pte = *pte;

	irql = KeRaiseIrqlToDpcLevel();
	__writecr3(old_cr3);
	KeLowerIrql(irql);
	/*DWORD32* cr3_va = (DWORD32*)0xc0300000;
	for (size_t i = 0; i < 1024; i++)
	{
		KdPrint(("%d: 0x%x", i, cr3_va[i]));
	}*/
	return status;
}

你可能感兴趣的:(windows内核,逆向,windows,x86)