首页
社区
课程
招聘
未解决 [求助]内核遍历某进程内模块,结果PEB地址访问出错
发表于: 2021-2-6 12:16 7637

未解决 [求助]内核遍历某进程内模块,结果PEB地址访问出错

2021-2-6 12:16
7637

X64下,需要实现内核下遍历某进程内模块,获取模块的地址,代码通过EPROCESS找到PEB,再找LDR,通过LDR的三个链表来遍历。

 

功能是实现了,但是发现有的时候会存在不能访问PEB地址的情况,错误代码是0xC0000005,Access Violation。发生这种情况的进程也不一样,有的时候是这个进程,有的是那个进程。

 

网上找了很久也没找到答案,有篇文章是说是因为系统此时没有将地址翻译为物理地址导致的;也有的是说要用MDL映射内存,但是我理解的是PEB还属于内核空间地址,应该不用映射直接访问吧?初学内核很多不懂,不知道大牛们能解答一下吗,万分感谢!

 

代码大致如下:

1
2
3
4
5
6
7
8
9
10
11
peb = PsGetProcessPeb(eprocess);
if (!peb)
    return FALSE;
KeStackAttachProcess(eprocess, &ks);
__try
{
    PPEB_LDR_DATA peb_LDR_data;
    //irql = WPOFFx64();//关闭保护的话直接蓝屏
 
    //下面这句peb有时候不可读导致错误,错误代码0xC0000005
    peb_LDR_data = (PPEB_LDR_DATA)(*(PULONG64)((ULONG64)peb+PEB_LDR_DATA_OFFSET));

希望有大佬指点一下,或者如何能可靠的在内核下读取任意进程内的模块地址?


[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

收藏
免费 0
支持
分享
最新回复 (11)
雪    币: 19
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
2
有大佬回复一下吗?这个问题真的困扰我好久了。我尝试过不用PEB,用EPROCESS里面的VadRoot去读取,但是发现出现问题的时候,两个方法都会出错。感觉像是EPROCESS整个不是在内存中了,是在虚拟内存中。昨天尝试用MDL映射来读取,但是在虚拟机测试没问题,在真机测试则总是蓝屏,报错 PAGE_FAULT_IN_NONPAGED_AREA 
2021-2-8 17:35
0
雪    币: 275
活跃值: (237)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
大概猜测是 PPEB 32位 64位要分开处理 
2021-2-8 17:57
0
雪    币: 19
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
4
hymeca 大概猜测是 PPEB 32位 64位要分开处理
感谢回复,我的问题应该不是32位和64位导致的,因为同一个程序,可能此次能读取,下一次就不能读取了。我自己感觉大概率是PEB被移到硬盘了,因为昨天用MDL映射,蓝屏后dump文件有一句PEB is paged out (Peb.Ldr = 00000000`7efdf018)。但是您提的确实也是我程序的一个问题,我应该在程序中对32位程序也做个判断,目前确实没有区分32位和64位程序。
2021-2-8 20:31
0
雪    币: 246
活跃值: (4427)
能力值: ( LV4,RANK:45 )
在线值:
发帖
回帖
粉丝
5
发核心转储的dump就好了
2021-2-8 22:10
0
雪    币: 275
活跃值: (237)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
不是32位64位的问题 那就应该是没有KeStackAttachProcess
2021-2-9 08:54
0
雪    币: 1391
活跃值: (1914)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
7
是不是内核隔离的问题?
2021-2-9 09:52
0
雪    币: 2726
活跃值: (1110)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
代码没看出啥问题,指针拆分开,先输出各个指针及里面的数据,都0xC0000005了,你还不拆开你的指针看看输出...
2021-2-9 13:46
0
雪    币: 19
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
9
感谢楼上各位的回答,目前这个问题找到原因了,是因为我外层的函数是一个遍历函数,通过active process link来获取EPROCESS,然后再遍历此EPROCESS下的模块。但是我以为active process link里面都是在运行的进程,实际上是有退出的进程,已经退出的进程读取peb就会失败。虚拟机不会出错应该是开系统后就测试,并没有退出的进程,而真机上有很多已退出的进程。

但是这个问题最早出现是在我读取指定程序PEB失败,那个指定程序我可以肯定是没有退出的。后面为了测试,我才写了这么一个遍历函数来测试的。目前指定程序读取PEB失败那个问题还不容易复现,后续复现了我再来咨询一下。
2021-2-9 16:26
0
雪    币: 362
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
10

你可以试一下MmIsAddressValid 如果MmIsAddressValid还出错 你需要  写一个 
 NoPageFaultRead() 
首先关中断 hook缺页中断 读内存 如果抛缺页异常 直接在你的缺页异常处理函数返回到安全的位置
所有内存读完之后立马恢复原来的缺页中断 在开中断 

或者你自己映射所有物理页到虚拟地址 然后根据虚拟地址从cr3物理页开始依次读取每层页表的方式来读内存

最后于 2021-2-10 02:35 被gdgdgdg编辑 ,原因:
2021-2-10 02:15
0
雪    币: 772
活跃值: (977)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
我记得好像win32和win64是不一样的。
2021-2-17 23:09
0
雪    币: 1416
活跃值: (4398)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
12
挂靠之后判断进程是不是退出,再判断r3地址是否有效,我代码跟你差不多但我还没遇到过这种问题
2023-3-27 10:40
0
游客
登录 | 注册 方可回帖
返回
//