64位寻址,前16位是符号扩展,后48位才是要寻找的地址
一、四级页表
二、根据地址找物理页
以fffff8003846efc0为例</p> <p>1、舍弃前16位 11111000 00000000 00111000 01000110 11101111 11000000</p> <p>2、拆分</p> <p>1 1111 0000 0x1f0</p> <p>0 0000 0000 0x0</p> <p>1 1100 0010 0x1c2</p> <p>0 0110 1110 0x6e</p> <p>1 1111 1000 000 0xfc0</p> <p>3、找物理地址</p> <p>三、x64位下PTE的位置</p> <p>ge根据不同机型有所不同</p> <p>0地址对应的pte地址是这一个,从此时起,每多1000//代码效果参考:http://www.lyjsj.net.cn/wz/art_23761.html<p></p> 字节的地址,pte的地址就会增加8</p> <p>假如我们要求的地址为0xffffxxxx
xxxxxxxx,那么其pte地址为
(0xffffxxxxxxxxxxxx & 0x0000ffff
ffffffff ] 12) [3 + FFFF878000000000
同理,x64下的PDT,PPE,PXE也可以这样得到
注意这三句话,pte也需要指向它自己的地址,指向他的地址就是pdt,以此类推
我们把pte当作普通地址经过上面那个公式演算就可以得到pte
用代码的话,就像这样
也就是说,只要我们知道pte的基地址,就可以求出所有页表的值
四、pte的基地址每次打开都是随机的
我们需要获取pte的基址
这里,周哥提供了一种方法,找调用pte基址的系统api
再根据内核文件的位置,找到这个偏移,每次读取这个偏移的数据即可!
五、实验
微软虚拟地址映射也是通过PTE的方式进行的
根据cr3的值,根据cr3找到pte的值,强搜调用这个值的API,再找到相对内核文件的偏移即可
lm
(IDA修改基址)
找到!!
算相对内核偏移
FFFFF80333403D6a - fffff80333400000 = 3D6A
下面求nt模块的基址,可以通过遍历内核模块的方法,或驱动driver结构体直接获取
这里我们写死地址
成功!!!
代码如下:
#include
ULONG64 g_NT_BASE = 0xfffff8064de00000;
ULONG64 g_PTE_BASE;
ULONG64 g_PDE_BASE;
ULONG64 g_PPE_BASE;
ULONG64 g_PXE_BASE;
void DriverUnload(PDRIVER_OBJECT driver)
{
DbgPrint("Unload Driver Success!!\r\n");
}
PULONG64 GetPteAddress(PVOID addr)
{
return (PULONG64)(((((ULONG64)addr & 0xffffffffffff) ] 12) [ 3) + g_PTE_BASE);
}
PULONG64 GetPdeAddress(PVOID addr)
{
return (PULONG64)(((((ULONG64)addr & 0xffffffffffff) ] 21) [ 3) + g_PDE_BASE);
}
PULONG64 GetPpeAddress(PVOID addr)
{
return (PULONG64)(((((ULONG64)addr & 0xffffffffffff) ] 30) [ 3) + g_PPE_BASE);
}
PULONG64 GetPxeAddress(PVOID addr)
{
return (PULONG64)(((((ULONG64)addr & 0xffffffffffff) ] 39) [ 3) + g_PXE_BASE);
}
NTSTATUS DriverEntry(PDRIVER_OBJECT driver, PUNICODE_STRING reg_path)
{
g_PTE_BASE = *(PULONG64)(g_NT_BASE + 0x3D6A);
g_PDE_BASE = (ULONG64)GetPteAddress((PVOID)g_PTE_BASE);
g_PPE_BASE //代码效果参考:http://www.lyjsj.net.cn/wz/art_23759.html
= (ULONG64)GetPteAddress((PVOID)g_PDE_BASE);g_PXE_BASE = (ULONG64)GetPteAddress((PVOID)g_PPE_BASE);
DbgPrint("PXE: %p\n", GetPxeAddress((PVOID)0xfffff8065246efd0));
DbgPrint("PPE: %p\n", GetPpeAddress((PVOID)0xfffff8065246efd0));
DbgPrint("PDE: %p\n", GetPdeAddress((PVOID)0xfffff8065246efd0));
DbgPrint("PTE: %p\n", GetPteAddress((PVOID)0xfffff8065246efd0));
driver->DriverUnload = DriverUnload;
return STATUS_SUCCESS;
}
EOF
本文链接:
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!