首页
社区
课程
招聘
[原创]调用ZwQueryVirtualMemory遍历进程模块示例(再次更新)
发表于: 2009-4-5 03:09 24928

[原创]调用ZwQueryVirtualMemory遍历进程模块示例(再次更新)

2009-4-5 03:09
24928

菜鸟学习帖,高手请飘过

一直只知道IceSword(以及看雪论坛上开源的山寨版IceSword)是用ZwQueryVirtualMemory来遍历进程的虚拟内存,从而得到加载的模块的,不过从来没有自己试过。
看了山寨版IceSword相关代码,原来是在Ring3中实现的,就想自己动手整一整,结果发现原来不是那么难。于是用汇编写了个Win32控制台程序来做演示。
基本原理不复杂,倒是细枝末节耗去很多时间。
首先我是以区段内存对齐的单位0x1000字节进行遍历,这样会出现多个区段属于同一个文件。这样我使用两次调用ZwQueryVirtualMemory:
第一次使用参数MemoryBasicInformation,判断传回的MEMORY_BASIC_INFORMATION结构中的AllocationBase字段值与传入的Base是否相等,相等则说明这是文件的第一个区段,这时才进行第二次调用;
第二次使用参数MemorySectionName,获得区段文件名。
山寨版IceSword使用的是0x10000字节为间隔,似乎就避免了这个麻烦,而且也不会漏掉模块。

第一次写Win32控制台程序,也是第一次用msvcrt.dll中的函数(由masm32rt.inc中封装)做字符串处理,发现自己这一块居然超不熟,耗费了不少时间。

其实说原创也不是太合适了,因为参考了一些网上的代码,比如山寨版IceSword,还有提SeDebugPrivilege的那部分也是直接copy的网上的代码(其实只要不是访问系统进程,提权不是必须的)。

代码写得比较挫,又一次证实了自己在Win32汇编这块还很菜

调用方法:把进程ID作为命令行参数传入,如Query.exe 1000

update:看了大家的回帖之后又修改了一下,主要是在盘符转换方面不再偷懒,现在应该可以支持非本地磁盘了。
对这个功能,发现KsBinSword好像没有做?
网上搜索发现QueryDosDevice,但据说没有功能反过来的,这样只能先对A-Z的盘符调用QueryDosDevice,把结果保存起来,然后需要转换的时候再跟全文件名比对。

另外调试了一下ZwQueryVirtualMemory的调用,因为我很在意那几个nls文件,记得好像说是内核创建进程过程中将其映射的。想看看怎么把它们跟后面的Module区分开来。
发现这几个nls映像头部的AllocationProtect都有PAGE_EXECUTE属性,而其他各个exe和dll的映像头部的AllocationProtect属性没有PAGE_EXECUTE,但两者当前的Protect属性都有PAGE_EXECUTE。
因此加了几行代码来做检测,在原文中被注释掉了,如果把注释掉的还原,则显示出来的模块中不包括nls文件。

update2:
之前的版本只能取A-Z盘符,现在是遍历所有DOS符号设备,对所有设备取其映射的设备名,与ZwQueryVirtualMemory得到的结果一一做比对,找到相应的DOS符号设备名。
由于同一个设备可能映射到多个DOS设备,比如\Device\HarddiskVolume1,除了C:之外还有其他的DOS设备与之对应,为了取到C:,这里我取长度最短的一个DOS设备名来显示。
实现还是用QueryDosDevice,代码写得一团乱 不禁想Ring0真好啊,有Rtl(Io)VolumeDeviceToDosName可以用……


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 8
支持
分享
最新回复 (19)
雪    币: 581
活跃值: (149)
能力值: ( LV12,RANK:600 )
在线值:
发帖
回帖
粉丝
2
ZwQueryVirtualMemory在ring3很容易被XXX..比如简单的HOOK就失效...不过目前这种办法还是不错的...绕过办法可以参考小伟的文章...不过yas anti rootkit不存在这个问题,至少能得到一个加载地址.. .
2009-4-5 07:20
0
雪    币: 7651
活跃值: (523)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
3
Hook内存管理可以绕过yaskit吗?另外,Yaskit的ObjectHook好像只检测文件和注册表部分的?
2009-4-5 07:29
0
雪    币: 581
活跃值: (149)
能力值: ( LV12,RANK:600 )
在线值:
发帖
回帖
粉丝
4
Hook内存管理可以绕过yaskit吗?? 你是说隐藏内存???
如果隐藏内存是可以的..因为yaskit枚举DLL就是在内存找相关结构的...
2009-4-5 07:38
0
雪    币: 7651
活跃值: (523)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
5
恩,我说的就是隐藏内存。不过应该也可以DKOM让进程中dll占用的内存看起来不像是一个可执行的映像
2009-4-5 10:04
0
雪    币: 7651
活跃值: (523)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
6
还可以加上暴力枚举PE部分,我以前写的那个程序拿gmer实验时,把gmer自己加载的ntoskrnl都给找出来了~~不过对抗暴力也很容易啊~
2009-4-5 13:31
0
雪    币: 8835
活跃值: (2404)
能力值: ( LV12,RANK:760 )
在线值:
发帖
回帖
粉丝
7
用notify+overshadow就行了~~
没有一点hook,VMM技术保护内核某些内存不可写,notify记录加载的DLL~~
2009-4-5 14:30
0
雪    币: 8201
活跃值: (2701)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
牛太多了,只能潜
2009-4-5 20:49
0
雪    币: 148
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
to nObele:

我在你的冰刃源代码上单击了鼠标.
但那似乎不是源代码的链接.
期待你上传这个东西.
注:如果不是masm的就算了.
2009-4-5 21:22
0
雪    币: 7309
活跃值: (3788)
能力值: (RANK:1130 )
在线值:
发帖
回帖
粉丝
10
不支持动态卷,不支持映射驱动器
2009-4-5 21:36
0
雪    币: 722
活跃值: (123)
能力值: ( LV12,RANK:300 )
在线值:
发帖
回帖
粉丝
11
这个W3是加上去想使使有没有效果,试后忘了删掉
那几行include和.mode的确应该删,因为masm32rt.inc已经有包含了,如果不删会报warning
开始的时候我是删掉的,不过后来想写进去也没啥,如果为了不报warning,就应该删掉。

至于那英文,当时都凌晨了,头脑昏昏的,没注意语法语义,反正就那意思
2009-4-5 21:43
0
雪    币: 722
活跃值: (123)
能力值: ( LV12,RANK:300 )
在线值:
发帖
回帖
粉丝
12
这个是在识别盘符的时候偷懒了。因为主要是演示ZwQueryVirtualMemory,怎么正确识别盘符我还要自己再想想
2009-4-5 22:45
0
雪    币: 722
活跃值: (123)
能力值: ( LV12,RANK:300 )
在线值:
发帖
回帖
粉丝
13
更新了一下,解决这个问题
貌似KsBinSword里没解决?
2009-4-6 02:41
0
雪    币: 1705
活跃值: (1665)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
楼主也没解决,你试试运行个网络路径的程序,或者是VMWARE共享目录下的文件,又或者在LOCAL下挂载个盘符,你看你还能解析得出来么?呵呵!
2009-4-6 06:01
0
雪    币: 1705
活跃值: (1665)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
另外,判断是否镜像模块应判顿其是否是SEC_IMAGE,具体参考冰刃源代码
2009-4-6 06:03
0
雪    币: 722
活跃值: (123)
能力值: ( LV12,RANK:300 )
在线值:
发帖
回帖
粉丝
16
呃,没有测试过这种情况,只做了有映射到A-Z盘符的
SEC_IMAGE这个知道,但是如果不是SEC_IMAGE的,ZwQueryVirtualMemory(MemorySectionName)会返回文件名吗?我不太确定,如果不会,那实际上就等于自动排除了不是SEC_IMAGE的情况。

另外,冰刃有源代码?
2009-4-6 19:50
0
雪    币: 722
活跃值: (123)
能力值: ( LV12,RANK:300 )
在线值:
发帖
回帖
粉丝
17
这次不偷懒了,取系统所有的DOS符号设备去做对比,应该不止A-Z盘,其他的也可以出来了,不过没有测试过,不知道效果怎么样啊。
Ring0有Rtl(Io)VolumeDeviceToDosName可以用,Ring3下只能倒过来使,比较累
另外SEC_IMAGE也试了,如果加上这个判断,nls文件就不会出来了(发的程序中这个判断注释掉了)。
2009-4-11 21:57
0
雪    币: 635
活跃值: (101)
能力值: ( LV12,RANK:420 )
在线值:
发帖
回帖
粉丝
18
VolumeDeviceToDosName并不好用

另外你这个网络路径和VMWARE的共享目录也不行
2009-4-11 22:36
0
雪    币: 722
活跃值: (123)
能力值: ( LV12,RANK:300 )
在线值:
发帖
回帖
粉丝
19
看了wrk,IoVolumeDeviceToDosName的原理好像是向Device发IRP的,我不太了解这个,不太清楚适用范围有多大。
网络路径和VMWARE共享目录我还是不明白怎么做的
2009-4-11 22:40
0
雪    币: 148
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
给楼主推荐个VC++源码.有空翻译成masm32.呵呵
上传的附件:
2009-4-11 23:06
0
游客
登录 | 注册 方可回帖
返回
//