手把手教你R0下通过EPROCESS获取进程加载模块

在R3下获取一个进程加载的相关模块儿还是比较简单的,直接通过ToolHelp32库API就能够获取到进程关联的模块儿了,但是既然已经在R0下混了再去使用R3层的东西就没什么意义了,所以这里小悠在这里将会一部一部的介绍如何在R0下通过EPROCESS结构获取到进程加载的模块.

首先这里我们先介绍一下我们通过EPROCESS查询的大概思路

①  通过EPROCESS 获取到对应的PEB 结构

②  通过PEB找到 _PEB_LDR_DATA这货

③  在_PEB_LDR_DATA内部有3个LIST_ENTRY,这也就是进程加载的模块儿信息的链表头,_PEB_LDR_DATA内部的3个链表其实只是模块儿的排列顺序不一样而已,里面的内容是一致的,本文中采用的是LoadOrder这个按照加载顺序排列的链表.

④  知道了链表头,只需要知道链表的结点的就够就行了,这里我们遍历的链表结点是_LDR_DATA_TABLE_ENTRY结构,在这个结构内部有一个FullDllName,也就是模块儿的路径,就是我们要找的东西,只要遍历链表我们就能枚举出所有的加载模块儿.

我用一幅图来描述我们的过程

               

从图中可以看出,只需要找到最终的那个链表遍历一下就OK了。

知道了上面的基本思路,现在我们开始动手操作了,首先准备好你的Windbg调试工具,先通过Windbg正确查找一个进程的模块儿链表,后面我在介绍使用代码的方式。

      我的虚拟机是Win7 x86的,这里以进程dwm.exe为例.

①  命令 !process 0 0 dwm.exe 先获取到dwm.exe的EPROCESS的地址,如图我们可以看到EPROCESS的地址为:0x87ede940  ,PEB的地址为:0x7ffdf000 


②  注意PEB的地址小于0x80000000,属于用户地址空间,是不能够直接访问的,要是直接访问的话就只能看到???????,所以我们需要切换到这个应用程序后才能够访问用户地址空间,使用下面的命令 .process /p /r 87ede940 切换到dwm.exe这个进程,如图所示:

③  已经切换到dwm.exe,我们开始按照步骤来操作吧,命令dt _EPROCESS 87ede940 查看EPROCESS,如图所示在偏移0x1a8的位置找到了_PEB,地址为0x7ffdf000

④  跟进_PEB,使用命令 dt _PEB 0x7ffdf000 查看PEB的信息,如图所示在偏移0x0c的位置找到了_PEB_LDR_DATA,地址为: 0x77307880

⑤  继续跟进_PEB_LDR_DATA,使用命令dt _PEB_LDR_DATA 0x77307880  查看_PEB_LDR_DATA的信息,如图所示,一共有3个_LIST_ENTRY,前面我已经说过这三个链表只是结点的顺序不一样,我采用的是第一个InLoadOrderModuleList按照加载顺序的这个链表.

⑥  我们已经找到了链表的头部,但是我们现在可不知道_LDR_DATA_TABLE_ENTRY这货的结构是神马,所以我们使用命令dt _LDR_DATA_TABLE_ENTRY 来看一下_LDR_DATA_TABLE_ENTRY的结构,如图所示:

从结构中可以看到InLoadOrderModuleList位于结构体的首部,所以我们获取到的_LIST_ENTRY地址就直接指向了_LDR_DATA_TABLE_ENTRY,无需再次转换了

⑦   回到⑤看一下了链表的第一个结点的地址(FLink方向遍历),第一个地址为0x3017b8,OK我们使用命令dt _LDR_DATA_TABLE_ENTRY 0x3017b8 跟进看一下,如图所示

                              

是不是看到dwm.exe这个进程本身的路径了? 那就对了,我们是按照模块儿加载的顺序遍历的,第一个模块儿就是本身嘛,不信的话那我们再往后看一个,命令dt _LDR_DATA_TABLE_ENTRY 0x301838 自己看下面的图吧,我就不多说了~~

原文地址:https://www.cnblogs.com/mayingkun/p/5551676.html