彩蛋解密之物理内存读写到****的转变
首先放上一段在DriverEntry中让人看了挠头的操作:
ContextVirtualToPhysical(&g_PhysicalOpCR3);
ULONG64 Read1 = *(PULONG64)0x0;
MyPrint(_TitleAndFunc "ReadTest1:%16IX\n", Read1);
ContextPhysicalToVirtual(&g_PhysicalOpCR3);
啊,读空指针啊,这不明摆着蓝屏吗?
唉,咋没蓝屏,还读到东西了呢?
下面我们来windbg看一下:
唉,有点东西是吧。
咋实现的啊,我先去看看代码吧:
咋看不懂呢?
这有个cr3,看看是啥东西?
我相信看到这里,对分页机制比较熟悉的大手子们就应该大概懂实现原理了。
调用CreatePhysicalOpCR3BySystemCR3进行初始化。
在其中分别依次调用pAllocPhysicalOpPageTableMemory、pMapSystemPML4T、pFillGeneratedPML4TandPDPT进行初始化,并填充结构。
需要读取物理内存时调用ContextVirtualToPhysical、ContextPhysicalToVirtual进行环境切换。
卸载时调用FreePhysicalOpCR3。
在其中依次调用pUnmapSystemPML4T、pFreePhysicalOpPageTableMemory并清理结构。
首先使用:CreatePhysicalOpCR3BySystemCR3。
进行初始化工作,下面是这个函数的代码。
NTSTATUS CreatePhysicalOpCR3BySystemCR3(ULONG64 SystemCR3, PPHYSICAL_OP_CR3 pPhysicalOpCR3)
{
//check the init state
if (g_IsPhysicalOpInit)
return STATUS_UNSUCCESSFUL;
//allocate page table memory and fill the structure
if (!NT_SUCCESS(pAllocPhysicalOpPageTableMemory(pPhysicalOpCR3)))
return STATUS_UNSUCCESSFUL;
//map pSystemPML4T to virtual address and fill the structure
if (!NT_SUCCESS(pMapSystemPML4T(SystemCR3, pPhysicalOpCR3)))
return STATUS_UNSUCCESSFUL;
//fill PML4T and PDPT page table
if (!NT_SUCCESS(pFillGeneratedPML4TandPDPT(pPhysicalOpCR3)))
return STATUS_UNSUCCESSFUL;
//generate new cr3 for reading the physical memory and add cr3 flag
ULONG64 SystemCR3Flag = GetCR3Flag(SystemCR3);
pPhysicalOpCR3->CR3Generated = (ULONG64)pPhysicalOpCR3->pAllocPA_PML4T | SystemCR3Flag;
//fill the structure part:CR3System
pPhysicalOpCR3->CR3System = SystemCR3;
//print structure
pPrintPhysicalOpStructure(pPhysicalOpCR3);
g_IsPhysicalOpInit = TRUE;
return STATUS_SUCCESS;
}
NTSTATUS pAllocPhysicalOpPageTableMemory(PPHYSICAL_OP_CR3 pPhysicalOpCR3)
{
//PML4T
pPhysicalOpCR3->pAllocVA_PML4T = MmAllocateNonCachedMemory(PAGE_TABLE_SIZE);
//check allocate state
if (pPhysicalOpCR3->pAllocVA_PML4T == NULL)
goto Lable_Error;
pPhysicalOpCR3->pAllocPA_PML4T = (PVOID)MmGetPhysicalAddress(pPhysicalOpCR3->pAllocVA_PML4T).QuadPart;
//PDPT
pPhysicalOpCR3->pAllocVA_PDPT = MmAllocateNonCachedMemory(PAGE_TABLE_SIZE);
//check allocate state
if (pPhysicalOpCR3->pAllocVA_PDPT == NULL)
goto Lable_Error;
pPhysicalOpCR3->pAllocPA_PDPT = (PVOID)MmGetPhysicalAddress(pPhysicalOpCR3->pAllocVA_PDPT).QuadPart;
return STATUS_SUCCESS;
Lable_Error:
//free allocated memory
pFreePhysicalOpPageTableMemory(pPhysicalOpCR3);
return STATUS_UNSUCCESSFUL;
}
NTSTATUS pMapSystemPML4T(ULONG64 SystemCR3, PPHYSICAL_OP_CR3 pPhysicalOpCR3)
{
ULONG64 SystemCR3NonFlag = ClearCR3Flag(SystemCR3);
PVOID pSystemPML4T = (PVOID)SystemCR3NonFlag;
if (g_SectionHandle == NULL)
g_SectionHandle = OpenPhysicalMemory();
pPhysicalOpCR3->pSystemPML4TMap = MapPhysicalMemory(pSystemPML4T, PAGE_TABLE_SIZE);
return pPhysicalOpCR3->pSystemPML4TMap == NULL ? STATUS_UNSUCCESSFUL : STATUS_SUCCESS;
}
{
//copy the system space map
PVOID pSystemStart = (PVOID)VA_SYSTEM_START;
ULONG64 SystemPML4TStart = ((PMMVA)&pSystemStart)->PML4T;
MyPrint(_TitleAndFunc"SystemPML4TStart:%16X\n", SystemPML4TStart);
RtlCopyMemory((PVOID)((ULONG64)pPhysicalOpCR3->pAllocVA_PML4T + SystemPML4TStart*ENTRY_SIZE),
(PVOID)((ULONG64)pPhysicalOpCR3->pSystemPML4TMap + SystemPML4TStart*ENTRY_SIZE),
(MAX_ENTRY_COUNT - SystemPML4TStart)*ENTRY_SIZE
);
//make the first address point to my PDPT table
*(PULONG64)pPhysicalOpCR3->pAllocVA_PML4T = (ULONG64)pPhysicalOpCR3->pAllocPA_PDPT | PAGE_TABLE_PML4T_FLAG;
//fill the PDPT page table
//add flag
ULONG64 CurrentPDPTEntry = PAGE_TABLE_PDPT_FLAG;
for (int i = 0; i < MAX_ENTRY_COUNT; i++)
{
//change pfn
((PMMPDPTE)&CurrentPDPTEntry)->PageFrameNumber = i;
//
*(PULONG64)((ULONG64)pPhysicalOpCR3->pAllocVA_PDPT + i*ENTRY_SIZE) = CurrentPDPTEntry;
}
return STATUS_SUCCESS;
}
直接给出方程式:
后记:希望大家不要沉迷编程,多拿出一些时间陪陪家人恋人朋友,不要给自己留下遗憾。
- End -
看雪ID:鬼才zxy
https://bbs.pediy.com/user-680946.htm
*本文由看雪论坛 鬼才zxy 原创,转载请注明来自看雪社区
推荐文章++++
进阶安全圈,不得不读的一本书
﹀
﹀
﹀