//1获取虚拟内存的PXE PDPTE pde,pte的索引
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, §ionObj, 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;