技术心得记录:周壑x64位内核学习(四)、x64分页机制

简介: 技术心得记录:周壑x64位内核学习(四)、x64分页机制

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>假如我们要求的地址为0xffffxxxxxxxxxxxx,那么其pte地址为


(0xffffxxxxxxxxxxxx & 0x0000ffffffffffff ] 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 许可协议。转载请注明出处!


声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!

相关文章
|
1月前
|
机器学习/深度学习 人工智能 负载均衡
深度解析:Linux内核调度策略的演变与优化
【5月更文挑战第30天】 随着计算技术的不断进步,操作系统的性能调优成为了提升计算机系统效率的关键。在众多操作系统中,Linux因其开源和高度可定制性而备受青睐。本文将深入剖析Linux操作系统的内核调度策略,追溯其历史演变过程,并重点探讨近年来为适应多核处理器和实时性要求而产生的调度策略优化。通过分析比较不同的调度算法,如CFS(完全公平调度器)、实时调度类和批处理作业的调度需求,本文旨在为系统管理员和开发者提供对Linux调度机制深层次理解,同时指出未来可能的发展趋势。
|
1月前
|
算法 Ubuntu Linux
【操作系统】探究进程奥秘:显示进程列表的解密与实战
【操作系统】探究进程奥秘:显示进程列表的解密与实战
41 0
|
NoSQL Linux 编译器
操作系统课程设计:新增Linux驱动程序(重制版)(一)
操作系统课程设计:新增Linux驱动程序(重制版)
174 1
操作系统课程设计:新增Linux驱动程序(重制版)(一)
|
Linux C语言 Windows
操作系统课程设计:新增Linux驱动程序(重制版)(三)
操作系统课程设计:新增Linux驱动程序(重制版)
172 0
操作系统课程设计:新增Linux驱动程序(重制版)(三)
|
Linux Shell
操作系统课程设计:新增Linux驱动程序(重制版)(二)
操作系统课程设计:新增Linux驱动程序(重制版)
120 0
操作系统课程设计:新增Linux驱动程序(重制版)(二)
|
弹性计算 运维 监控
如何解决 Linux 内核调测两大难题:内存被改与内存泄露
一直以来,内核内存调测领域一直持续存在着两大行业难题: "内存被改" 和 "内存泄漏"。内存问题行踪诡异、飘忽不定,在 Linux 内核的调测问题中,是最让开发者头疼的 bug 之一,因为内存问题往往发生故障的现场已经是第 N 现场了,尤其是在生产环境上出现,截止目前并没有一个很有效的方案能够进行精准的线上 debug,导致难以排查、耗时耗力。
474 0
如何解决 Linux 内核调测两大难题:内存被改与内存泄露
|
弹性计算 运维 前端开发
|
网络协议 Shell Linux
使用 bpftrace 分析内核
> 本文翻译自 Brendan Gregg 的 [Kernel analysis with bpftrace](https://lwn.net/Articles/793749/) 在 [2019 Linux Storage, Filesystem, and Memory-Management Summit](https://lwn.net/Articles/lsfmm2019/)(LSFMM
3856 0
从硬件出发,浅谈操作系统的段机制与页机制【转】
转自:https://www.jianshu.com/p/f4a909f3fd2e 我们写一个程序,经过编译之后会变成一堆的指令。操作系统在执行这个程序的时候,也正是执行这堆指令。 指令可以是 取数据的指令 或 取下一条被执行指令 的指令。
1140 0