如何通过线性地址找到对应的pte,pde指针

本文详细解析了从虚拟地址vaddr到物理地址phy_vaddr的映射过程,通过构造特殊的虚拟地址newvaddr,使其能直接定位到页表项(pte指针)。文章深入探讨了处理器处理32位地址的三个关键步骤,并展示了如何利用这些步骤精确找到所需pte指针。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我们首先明确一下这个问题
也就是说你需要通过线性地址(因为开启了分页,这里也可以叫虚拟地址,我们下文都将这样称呼,假设需要找到虚拟地址vaddr)vaddr来找到对应它的pte指针。

我们知道通过虚拟地址vaddr,我们经过页变化可以找到一个确定的物理地址phy_vaddr。现在我们想要找到的是指向这个phy_vaddr的pte指针,由于页表,页表项这些都是存在于内存中的,所以其对应的是实在的物理地址。于是我们现在的目的就是:通过一个虚拟地址得到物理地址。

嗯,听起来就让人很激动呀?

让我们先来回顾一下处理器处理 32 位地址的三个步骤:
(1)首先处理高 10位 的 pde索引,从而处理器得到页表物理地址。
(2)其次处理中间 10 位 的 pte 索引,进而处理器得到普通物理页的物理地址
(3)最后是把低 12 位 作为普通物理页的页内偏移地址,此偏移地址加上物理页的物理地址,得到的地址之和便是最终的物理地址,处理器到此物理地址上进行读写操作。

也就是说,我们要创造的一个新的虚拟地址 new vaddr,它经过处理器以上三个步骤的拆分处理,最终会落到 vaddr 自身所在的 pte 的物理地址上。

第一步:高10位的构成

那么分析到这里,我们就需要知道一个知识点:在页目录表中,最后一个目录表项填的是页目录表自己的地址。

所以我们在构建新的虚拟地址的时候,在高10位,我们可以直接让其指向页目录表的最后一位,然后本该得到页表物理地址的我们得到的还是页目录表的物理地址。

即图中Dir我们让其指向Page Directory的最后一项,然后我们得到的还是一个指向Page Directory的指针,而并不是指向Page Table的指针。

由于页目录表也是4KB,所以为4*2^10 = 2^12 = 1024,由于其实下标为0,所以最后一个表项为1023,对应的16进制为0x3ff,将其左移到高10位后,变为0xffc00000

第二步:中间10位的构成

现在我们的指针是指向页目录表的,如果按照之前的规则的话,我们此时看图,应该是Table与上一个结果相加,得到Physical Address Space的地址,而我们最终想得到的是指向物理地址Phy.Addr的那个指针,也就是我们想知道的pte指针,那么这一步我们就应该找到Page Table的地址。

所以,我们构造中间10位的时候,将原本的Dir作为偏移地址,这样,通过其与第一步我们得到的页目录表的地址相加,就可以得到指向Page Table的指针,也就是我们要得到的页表的地址。

于是中间10位的构成为图中Dir的值

第三步:低12位的构成

我们现在已经有了指向Page Table的指针了,那我们如何找到指向物理地址Phy.Addr的那个指针呢?我们可以想一下,初始的时候我们是通过加上Table的值得到指向物理地址Phy.Addr的指针的,所以我们此时也是将其作为低12位。

但是这里又有一个问题了,其为10位,而我们需要的是12位,怎么办呢?

我们通过将其左移2位,即可得到新的地址,即将其值乘以4即可。

同样pde指针也是同理,大家自己可以思考一下哦?
(answer : 当32位的地址中高20位位0xffff时,就表示访问到的是最后一个页目录项。即其高10位位0x3ff,中间10位也为0x3ff)

[讨论][转帖][讨论][原创]windows Hook内核api,能过win10 22H2的pg 发表于: 2023-12-6 17:35 12260 举报 最近一直在思考如何hook内核函数而不触发pg,于是我在看雪找到一篇文章讲解如何hook内核函数不触发pg,链接:https://bbs.kanxue.com/thread-266781.htm。 文章并没有讲解思路,直接贴上代码,在看完他的代码后,我理解了其思路,发现代码有点冗长,存在一些多余的操作,不过这也给了我过pg的思路。 windows64位系统内核中内核函数线性地址对应的物理地址pte里面的物理地址,是不是可以修改pte里面物理地址从而改变线性地址对应的物理地址,但是内核中的函数的pte里面的物理地址是全局的,只要一修改,其他进程也会受到影响。好在我们通过进程的Cr3找到进程的内核函数地址对应的PXE,这个PXE不是全局的,如果修改了PXE里面的值,该进程内核函数对应的物理地址也就变了,但是不会影响的其他进程。于是我们可以重构页表,通过修改PXE,PDPTEPDEPTE来修改该进程内核函数对应的物理地址,从而可以对该内核函数进行hook而不触发pg。大致做法如下图: 图片描述 图片描述 图片描述 我们可以通过映射物理内存到虚拟内存的方法来修改PXE,PDPTEPDEPTE。 这里一共两份源码,一份win7,一份win10,win10的源码针对2Mb大页的。 下面是源码: 支持win7 #include<ntifs.h> ULONG_PTR pPhyAddr[5] = { 0 }; typedef struct _HARDWARE_PTE { ULONG64 Valid : 1; ULONG64 Write : 1; ULONG64 Owner : 1; ULONG64 WriteThrough : 1; ULONG64 CacheDisable : 1; ULONG64 Accessed : 1; ULONG64 Dirty : 1; ULONG64 LargePage : 1; ULONG64 Global : 1; ULONG64 CopyOnWrite : 1; ULONG64 Prototype : 1; ULONG64 reserved0 : 1; ULONG64 PageFrameNumber : 36; ULONG64 reserved1 : 4; ULONG64 SoftwareWsIndex : 11; ULONG64 NoExecute : 1; } HARDWARE_PTE, *PHARDWARE_PTE; BOOLEAN InitHook(ULONG_PTR VirtualAddress_s, ULONG Pid, ULONG_PTR offset) { //1获取虚拟内存的PXE PDPTE pdepte的索引 ULONG PxeIndex = (VirtualAddress_s >> 0x27) & 0x1FF; UINT32 PPEIndex = (VirtualAddress_s >> 0x1E) & 0x1FF; //PPEIndex UINT32 PDEIndex = (VirtualAddress_s >> 0x15) & 0x1FF; //PDEIndex UINT32 PTEIndex = (VirtualAddress_s >> 0xC) & 0x1FF; 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 //DbgBreakPoint(); //2 获取要hook进程的CR3 PEPROCESS pEprocess = NULL; NTSTATUS status = PsLookupProcessByProcessId(Pid, &pEprocess); if (!NT_SUCCESS(status)) { return 0; } ULONG_PTR Cr3PhyAddr = *(PULONG64)((ULONG64)pEprocess + KERNEL_CR3_OFFSET); PHYSICAL_ADDRESS Cr3 = { 0 }; Cr3.QuadPart = Cr3PhyAddr; ULONG_PTR VirtualAddresss = MmMapIoSpace(Cr3, PAGE_SIZE, MmNonCached);//由于Cr3是物理地址我们需要映射到虚拟内存中去 if (!VirtualAddresss) { return 0; } //3 构建页表 //*(PULONG64)(VirtualAddresss + PxeIndex * 8) |= 70; PHYSICAL_ADDRESS Low = { 0 }; PHYSICAL_ADDRESS High = { MAXULONG64 }; //ppe pPhyAddr[0] = (ULONG_PTR)MmAllocateContiguousMemorySpecifyCache(PAGE_SIZE, Low, High, Low, MmCached); ULONG_PTR newPPEphy = MmGetPhysicalAddress(pPhyAddr[0]).QuadPart; ULONG_PTR PPEPhyAddr = (ULONG_PTR)(((PHARDWARE_PTE)(VirtualAddresss + PxeIndex * 8))->PageFrameNumber) * 0x1000; PHYSICAL_ADDRESS temp = { 0 }; temp.QuadPart = PPEPhyAddr; ULONG_PTR VirtualAddress_PPE= MmMapIoSpace(temp, PAGE_SIZE, MmNonCached); memcpy(pPhyAddr[0], VirtualAddress_PPE, PAGE_SIZE); //pde pPhyAddr[1] = (ULONG_PTR)MmAllocateContiguousMemorySpecifyCache(PAGE_SIZE, Low, High, Low, MmCached); ULONG_PTR newPDEphy= MmGetPhysicalAddress(pPhyAddr[1]).QuadPart; ULONG_PTR pdePhy= (ULONG_PTR)(((PHARDWARE_PTE)(VirtualAddress_PPE + PPEIndex * 8))->PageFrameNumber) * 0x1000; temp.QuadPart = pdePhy; ULONG_PTR VirtualAddress_PDE = MmMapIoSpace(temp,PAGE_SIZE, MmNonCached); memcpy(pPhyAddr[1], VirtualAddress_PDE, PAGE_SIZE); //pte pPhyAddr[2] = (ULONG_PTR)MmAllocateContiguousMemorySpecifyCache(PAGE_SIZE, Low, High, Low, MmCached); ULONG_PTR newPTEphy = MmGetPhysicalAddress(pPhyAddr[2]).QuadPart; ULONG_PTR ptePhy = (ULONG_PTR)(((PHARDWARE_PTE)(VirtualAddress_PDE + PDEIndex * 8))->PageFrameNumber) * 0x1000; temp.QuadPart = ptePhy; ULONG_PTR VirtualAddress_PTE = MmMapIoSpace(temp, PAGE_SIZE, MmNonCached); memcpy(pPhyAddr[2], VirtualAddress_PTE, PAGE_SIZE); //物理内存 pPhyAddr[3] = (ULONG_PTR)MmAllocateContiguousMemorySpecifyCache(PAGE_SIZE, Low, High, Low, MmCached); ULONG_PTR newphy = MmGetPhysicalAddress(pPhyAddr[3]).QuadPart; ULONG_PTR Phy = (ULONG_PTR)(((PHARDWARE_PTE)(VirtualAddress_PTE + PTEIndex * 8))->PageFrameNumber) * 0x1000; temp.QuadPart = Phy; ULONG_PTR VirtualAddress_PHY = MmMapIoSpace(temp, PAGE_SIZE, MmNonCached); memcpy(pPhyAddr[3], VirtualAddress_PHY, PAGE_SIZE); //ULONG_PTR ss3 = pPhyAddr[3]; //ULONG_PTR ss1 = pPhyAddr[1]; //ULONG_PTR ss2 = pPhyAddr[2]; //DbgBreakPoint(); //4 修改PXE PPE PDE PTE从而改变 ((PHARDWARE_PTE)(VirtualAddresss + PxeIndex * 8))->PageFrameNumber = newPPEphy >> 12; ((PHARDWARE_PTE)(pPhyAddr[0] + PPEIndex * 8))->PageFrameNumber = newPDEphy >> 12; ((PHARDWARE_PTE)(pPhyAddr[1] + PDEIndex * 8))->PageFrameNumber = newPTEphy >> 12; ((PHARDWARE_PTE)(pPhyAddr[2] + PTEIndex * 8))->PageFrameNumber = newphy >> 12; ((PHARDWARE_PTE)(pPhyAddr[2] + PTEIndex * 8))->Write = 1; *(PUCHAR)(pPhyAddr[3] + offset + 0x27) = 0x90; *(PUCHAR)(pPhyAddr[3] + offset + 0x28) = 0x90; *(PUCHAR)(pPhyAddr[3] + offset + 0x29) = 0xc3; return TRUE; } VOID unstallHook() { 1 2 3 4 MmFreeContiguousMemory(pPhyAddr[0]); MmFreeContiguousMemory(pPhyAddr[1]); MmFreeContiguousMemory(pPhyAddr[2]); MmFreeContiguousMemory(pPhyAddr[3]); } VOID DriverUnload(PDRIVER_OBJECT pDriver) { unstallHook(); } NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pRes) { pDriver->DriverUnload = DriverUnload; UNICODE_STRING ss = { 0 }; RtlInitUnicodeString(&ss, L"NtOpenProcess"); ULONG_PTR NtOpenAddr = MmGetSystemRoutineAddress(&ss); ULONG_PTR funcVir = NtOpenAddr & ~(0xfff); ULONG_PTR funcOffset = NtOpenAddr & 0xfff; InitHook(funcVir, 2280, funcOffset); //SetPTEHook(ssz); return STATUS_SUCCESS; } 当我附加到被我下钩子的进程,NtOpenProcess的结果在内存中是这样的: 图片描述 附加到我们没有HOOK的其他进程: 图片描述 在win7 64位系统中存在了5小时未发生pg。 我的这份源码纯粹是为了实验,封装的不太好,请谅解。 由于我刚学习64位系统内核没多久,可能文章会有一些错误,希望各位大佬能够指正。 对于win10,由于不能像win7用同样的方法映射页表的物理内存,我换了一种方式,且这次是2Mb的大页,细节有很多发生了变化,但思路还是一样的,我没有完善卸载函数,卸载的时候会蓝屏。 下面是源码: ULONG_PTR pPhyAddr[5] = { 0 }; ULONG IsPdeLager = 0; ULONG_PTR newPPEphy = 0; //ULONG_PTR pPhyAddr[5] = { 0 }; ULONG_PTR newPDEphy = 0; ULONG_PTR newPTEphy = 0; ULONG_PTR newphy = 0; typedef struct _HARDWARE_PTE { ULONG64 Valid : 1; ULONG64 Write : 1; ULONG64 Owner : 1; ULONG64 WriteThrough : 1; ULONG64 CacheDisable : 1; ULONG64 Accessed : 1; ULONG64 Dirty : 1; ULONG64 LargePage : 1; ULONG64 Global : 1; ULONG64 CopyOnWrite : 1; ULONG64 Prototype : 1; ULONG64 reserved0 : 1; ULONG64 PageFrameNumber : 36; ULONG64 reserved1 : 4; ULONG64 SoftwareWsIndex : 11; ULONG64 NoExecute : 1; } HARDWARE_PTE, *PHARDWARE_PTE; BOOLEAN InitHook(ULONG_PTR VirtualAddress_s, ULONG Pid, ULONG_PTR offset) { 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 //1获取虚拟内存的PXE PDPTE pdepte的索引 ULONG PxeIndex = (VirtualAddress_s >> 0x27) & 0x1FF; UINT32 PPEIndex = (VirtualAddress_s >> 0x1E) & 0x1FF; //PPEIndex UINT32 PDEIndex = (VirtualAddress_s >> 0x15) & 0x1FF; //PDEIndex UINT32 PTEIndex = (VirtualAddress_s >> 0xC) & 0x1FF; //DbgBreakPoint(); //2 获取要hook进程的CR3 PEPROCESS pEprocess = NULL; NTSTATUS status = PsLookupProcessByProcessId(Pid, &pEprocess); if (!NT_SUCCESS(status)) { return 0; } HANDLE hMemory = NULL; UNICODE_STRING unName = { 0 }; RtlInitUnicodeString(&unName, L"\\Device\\PhysicalMemory"); OBJECT_ATTRIBUTES obj; InitializeObjectAttributes(&obj, &unName, OBJ_CASE_INSENSITIVE, NULL, NULL); status = ZwOpenSection(&hMemory, SECTION_ALL_ACCESS, &obj); if (!NT_SUCCESS(status)) { return 0; } SIZE_T sizeView = PAGE_SIZE; PVOID sectionObj = NULL; status = ObReferenceObjectByHandle(hMemory, SECTION_ALL_ACCESS, NULL, KernelMode, &sectionObj, NULL); if (!NT_SUCCESS(status)) { return status; } ULONG_PTR Cr3PhyAddr = *(PULONG64)((ULONG64)pEprocess + KERNEL_CR3_OFFSET)&~(0xf); PHYSICAL_ADDRESS Cr3 = { 0 }; Cr3.QuadPart = Cr3PhyAddr; ULONG_PTR VirtualAddresss = NULL; status = ZwMapViewOfSection(hMemory, NtCurrentProcess(), &VirtualAddresss, 0, PAGE_SIZE, &Cr3, &sizeView, ViewUnmap, MEM_TOP_DOWN, PAGE_READWRITE); //ULONG_PTR VirtualAddresss = MmMapIoSpace(Cr3, PAGE_SIZE, MmNonCached);//由于Cr3是物理地址我们需要映射到虚拟内存中去 if (!NT_SUCCESS(status)) { return 0; } //3 构建页表 //*(PULONG64)(VirtualAddresss + PxeIndex * 8) |= 70; PHYSICAL_ADDRESS Low = { 0 }; PHYSICAL_ADDRESS High = { MAXULONG64 }; //ppe do { pPhyAddr[0] = (ULONG_PTR)MmAllocateContiguousMemorySpecifyCache(PAGE_SIZE, Low, High, Low, MmCached); newPPEphy = MmGetPhysicalAddress(pPhyAddr[0]).QuadPart; ULONG_PTR PPEPhyAddr = (ULONG_PTR)(((PHARDWARE_PTE)(VirtualAddresss + PxeIndex * 8))->PageFrameNumber) * 0x1000; PHYSICAL_ADDRESS temp = { 0 }; temp.QuadPart = PPEPhyAddr; ULONG_PTR VirtualAddress_PPE = NULL; ZwMapViewOfSection(hMemory, NtCurrentProcess(), &VirtualAddress_PPE, 0, PAGE_SIZE, &temp, &sizeView, ViewUnmap, MEM_TOP_DOWN, PAGE_READWRITE); memcpy(pPhyAddr[0], VirtualAddress_PPE, PAGE_SIZE); //pde pPhyAddr[1] = (ULONG_PTR)MmAllocateContiguousMemorySpecifyCache(PAGE_SIZE, Low, High, Low, MmCached); newPDEphy = MmGetPhysicalAddress(pPhyAddr[1]).QuadPart; ULONG_PTR pdePhy = (ULONG_PTR)(((PHARDWARE_PTE)(VirtualAddress_PPE + PPEIndex * 8))->PageFrameNumber) * 0x1000; temp.QuadPart = pdePhy; ULONG_PTR VirtualAddress_PDE = NULL; ZwMapViewOfSection(hMemory, NtCurrentProcess(), &VirtualAddress_PDE, 0, PAGE_SIZE, &temp, &sizeView, ViewUnmap, MEM_TOP_DOWN, PAGE_READWRITE); memcpy(pPhyAddr[1], VirtualAddress_PDE, PAGE_SIZE); //pte ULONG_PTR ptePhy = (ULONG_PTR)(((PHARDWARE_PTE)(VirtualAddress_PDE + PDEIndex * 8))->PageFrameNumber) * 0x1000; temp.QuadPart = ptePhy; if (((PHARDWARE_PTE)(VirtualAddress_PDE + PDEIndex * 8))->LargePage == 1) { pPhyAddr[2] = (ULONG_PTR)MmAllocateContiguousMemorySpecifyCache(PAGE_SIZE* 1024, Low, High, Low, MmCached); memset(pPhyAddr[2], 0, PAGE_SIZE * 1024); ULONG_PTR Real = MmGetPhysicalAddress(pPhyAddr[2]).QuadPart; ULONG_PTR Real1 = Real; ULONG_PTR Realtemp = 0; if (Real == 0) { MmFreeContiguousMemory(pPhyAddr[0]); MmFreeContiguousMemory(pPhyAddr[1]); MmFreeContiguousMemory(pPhyAddr[2]); return FALSE; } ULONG i = 0; for (i = 0; i < 1024; i++) { Real += PAGE_SIZE; //Real &= 0x1fffff; Realtemp = Real & 0x1fffff; if (!Realtemp) break; } DbgBreakPoint(); pPhyAddr[2] += PAGE_SIZE * (i+1); newPTEphy = MmGetPhysicalAddress(pPhyAddr[2]).QuadPart; ULONG_PTR VirtualAddress_PTE = NULL; sizeView = PAGE_SIZE * 0x200; ZwMapViewOfSection(hMemory, NtCurrentProcess(), &VirtualAddress_PTE, 0, PAGE_SIZE, &temp, &sizeView, ViewUnmap, MEM_TOP_DOWN, PAGE_READWRITE); memcpy(pPhyAddr[2], VirtualAddress_s &~(0x1fffff), PAGE_SIZE*0x200); ((PHARDWARE_PTE)(pPhyAddr[0] + PPEIndex * 8))->PageFrameNumber = newPDEphy >> 12; ((PHARDWARE_PTE)(pPhyAddr[1] + PDEIndex * 8))->PageFrameNumber = newPTEphy >> 12; //((PHARDWARE_PTE)(pPhyAddr[2] + PTEIndex * 8))->Write = 1; ULONG_PTR newOffset = (VirtualAddress_s & 0x1ff000) + offset; //((PHARDWARE_PTE)(pPhyAddr[1] + PTEIndex * 8))->Write = 1; *(PUCHAR)(pPhyAddr[2] + newOffset + 0x27) = 0x90; *(PUCHAR)(pPhyAddr[2] + newOffset + 0x28) = 0x90; *(PUCHAR)(pPhyAddr[2] + newOffset + 0x29) = 0xc3; ULONG_PTR ss = pPhyAddr[2]; ULONG_PTR ss2 = VirtualAddress_s & ~(0x1fffff); IsPdeLager = 1; break; } pPhyAddr[2] = (ULONG_PTR)MmAllocateContiguousMemorySpecifyCache(PAGE_SIZE, Low, High, Low, MmCached); newPTEphy = MmGetPhysicalAddress(pPhyAddr[2]).QuadPart; ULONG_PTR VirtualAddress_PTE = NULL; ZwMapViewOfSection(hMemory, NtCurrentProcess(), &VirtualAddress_PTE, 0, PAGE_SIZE, &temp, &sizeView, ViewUnmap, MEM_TOP_DOWN, PAGE_READWRITE); memcpy(pPhyAddr[2], VirtualAddress_PTE, PAGE_SIZE); //物理内存 pPhyAddr[3] = (ULONG_PTR)MmAllocateContiguousMemorySpecifyCache(PAGE_SIZE, Low, High, Low, MmCached); newphy = MmGetPhysicalAddress(pPhyAddr[3]).QuadPart; ULONG_PTR Phy = (ULONG_PTR)(((PHARDWARE_PTE)(VirtualAddress_PTE + PTEIndex * 8))->PageFrameNumber) * 0x1000; temp.QuadPart = Phy; ULONG_PTR VirtualAddress_PHY = NULL; ZwMapViewOfSection(hMemory, NtCurrentProcess(), &VirtualAddress_PHY, 0, PAGE_SIZE, &temp, &sizeView, ViewUnmap, MEM_TOP_DOWN, PAGE_READWRITE); memcpy(pPhyAddr[3], VirtualAddress_PHY, PAGE_SIZE); } while (0); //ULONG_PTR ss3 = pPhyAddr[3]; //ULONG_PTR ss1 = pPhyAddr[1]; //ULONG_PTR ss2 = pPhyAddr[2]; //DbgBreakPoint(); //4 修改PXE PPE PDE PTE从而改变 if (IsPdeLager) { ((PHARDWARE_PTE)(VirtualAddresss + PxeIndex * 8))->PageFrameNumber = newPPEphy >> 12; return TRUE; } ((PHARDWARE_PTE)(VirtualAddresss + PxeIndex * 8))->PageFrameNumber = newPPEphy >> 12; ((PHARDWARE_PTE)(pPhyAddr[0] + PPEIndex * 8))->PageFrameNumber = newPDEphy >> 12; ((PHARDWARE_PTE)(pPhyAddr[1] + PDEIndex * 8))->PageFrameNumber = newPTEphy >> 12; ((PHARDWARE_PTE)(pPhyAddr[2] + PTEIndex * 8))->PageFrameNumber = newphy >> 12; return TRUE; }; VOID unstallHook() { if (IsPdeLager) { MmFreeContiguousMemory(pPhyAddr[0]); MmFreeContiguousMemory(pPhyAddr[1]); MmFreeContiguousMemory(pPhyAddr[2]); return; } 1 2 3 4 //MmFreeContiguousMemory(pPhyAddr[0]); //MmFreeContiguousMemory(pPhyAddr[1]); //MmFreeContiguousMemory(pPhyAddr[2]); //MmFreeContiguousMemory(pPhyAddr[3]); } VOID DriverUnload(PDRIVER_OBJECT pDriver) { unstallHook(); } NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pRes) { pDriver->DriverUnload = DriverUnload; PKLDR_DATA_TABLE_ENTRY pKldr = (PKLDR_DATA_TABLE_ENTRY)pDriver->DriverSection; pKldr->Flags |= 0x20; //NTSTATUS status = PsSetCreateProcessNotifyRoutine(ProcessNotifyRoutine, FALSE); UNICODE_STRING ss = { 0 }; RtlInitUnicodeString(&ss, L"NtOpenProcess"); ULONG_PTR NtOpenAddr = MmGetSystemRoutineAddress(&ss); ULONG_PTR funcVir = NtOpenAddr & ~(0xfff); ULONG_PTR funcOffset = NtOpenAddr & 0xfff; InitHook(funcVir, 8568, funcOffset); //SetPTEHook(ssz); return STATUS_SUCCESS; }根据这个帖子,把上面的win10代码完整的抄下来
最新发布
07-16
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

五月的天气

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值