-
-
[原创]保护模式-新手上路:逆向分析MmIsAddressValid函数
-
发表于:
2022-8-31 16:36
5061
-
[原创]保护模式-新手上路:逆向分析MmIsAddressValid函数
最近在学习内核方面的知识,遇到了许多坑,特来发篇帖子总结一下
本文完全面向新手,如有讲错了或者不严谨的地方请各位大佬在评论区指出
在编写驱动的过程中,我们或多或少都用过一个叫MmIsAddressValid的函数,我们今天主要干的就是逆向分析一下它是如何实现的
环境:Win7 x86
工具:IDA
分析文件:ntoskrnl.exe 10-10-12分页
来自MSDN官方文档:MmIsAddressValid 例程检查给定虚拟地址处的读取或写入操作是否会发生页面错误
具体用法可以参考以下代码片段
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | BOOLEAN KReadMemoryA(IN PEPROCESS Proc,IN PVOID Base, IN UINT32 Size,IN OUT PVOID Buffer )
{
KAPC_STATE Apc;
RtlZeroMemory(&Apc, sizeof(KAPC_STATE));
KeStackAttachProcess(Proc, &Apc);
KdPrint(( "xxx:ReadA>>已经附加到目标进程\n" ));
BOOLEAN bRet = MmIsAddressValid(Base); / / 判断目标地址是否有效
if (bRet)
{
RtlCopyMemory( Buffer , Base, Size);
}
else
{
KdPrint(( "xxx:目标地址不可访问" ));
}
KeUnstackDetachProcess(&Apc);
KdPrint(( "xxx:已脱离目标进程!\n" ));
return bRet;
/ / 目标进程的地址空间
}
|
好,废话不多说,我们开始操作,首先打开IDA,将ntoskrnl.exe拖入,加载符号链接
接着来到函数窗口,搜索函数名称
接着双击,然后来到 IDA 的 View 窗口
此时你会看到一段这样的代码
可以看到有一行 mov ecx
VirtualAddress的值是8,对应的是第一个参数,即ebp+8
此时的堆栈环境>>
双击_MiIsAddressVaild@8进入内部查看
我们一步步看上图,可以发现这个函数的核心实现原理
1.判断PDE的P位是否置1,置1则下一步
2.判断PS位是否置1,置1则是大页,则直接返回True
3.继续检查PTE的P位是否置1
4.检查PAT位
正如MSDN中所说,这个函数并不可靠,如果这个地址指向的物理页没有被锁定或者不是非分页池分配的内存,那么这个函数返回的结果就不一定正确。
至此,分析结束,感谢大家的阅读
补充:关于页属性,在Intel白皮书中是这样描述的
P位:
该标志表明,该表项所指向的页或者页表当前是否在内存中。当置位该标志时,这个页在物理内存中,将执行地址转换。当该标志清零时,表示这个页不在内存中,如果处理器试图访问该页,将产生一个缺页异常(PF)。
PS位:
确定页的尺寸。该标志仅被用于页目录项。当该标志被清零时,页尺寸为4KB,页目录项指向一个页表。当该标志被置位时,页的尺寸为32位寻址的4MB(当扩展物理寻址启用时,页的尺寸位2MB),页目录项指向一个页。如果页目录项指向一个页表,所有与那个页表相关的页都是4KB。
PAT位:
这个标志用来选择PAT项。对于支持页属性表(PAT)的处理器来说,这个标志与PCD和PWT标志一起,被用来选取PAT项,PAT反过来选择该页的内存类型(见10.12节“页属性表(PAT)”)。对于不支持PAT的处理器,这个位被保留,应该被置为0。
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2022-8-31 20:53
被AlexLoNe编辑
,原因: