-
-
[原创]模块遍历与模块隐藏
-
发表于:
2021-10-5 17:09
13248
-
要进行模块隐藏,首先要获得要查询的模块的进程的PID。那么就需要遍历进程找到要查询的进程的PID。在用户层查询进程往往都是使用Win API来实现的。首先看下需要使用的相应的API。
当参数dwFlags传入的是TH32CS_SNAPPROCESS,这个值是宏定义其实就是数字0x2,而th32ProcessId传入0的时候会得到一个进程快照的句柄供后面遍历进程使用。如果调用失败返回的就是INVALID_HANDLE_VALUE。
使用上面的两个API就可以完成进程的遍历,我们需要首先调用Process32First来获取第一个进程,接着在循环调用Process32Next来获取下一个进程,当查询到进程时候,函数返回值就是TRUE;
其中参数hSnapshot就是上面进程快照的句柄,而lppe是一个指向PROCESSENTRY32的指针,这个结构体的定义如下
其中的szExeFile就是进程的名称而th32ProcessId就是进程的PID。在调用Process32First之前,我们需要将dwSize初始化为结构体的大小。据此可以写出如下代码来获取进程PID。
对于这个API,当参数dwFlags传入TH32CS_SNAPMODULE,参数th32ProcessID传入进程PID的时候,就可以得到模块快照的句柄,供后面遍历模块使用。如果失败依然返回的是INVALID_HANDLE_VALUE。
和进程遍历类型,模块遍历的两个API如下
使用方法和hSnapshot和上面相同,只是这里的输出值也就是参数MODULEENTRY32的结构体指针。定义如下
其中的szModule就是模块的名称。在调用Module32First之前依然要先初始化dwSize为结构体大小。最终得出的模块遍历的代码如下
要实现模块隐藏,首先需要得到进程的TEB结构体,这个结构体在fs寄存器中保存着。而TEB结构体偏移0x30处可以得到PEB结构体。从PEB结构体0x0c的地方保存的就是PEB_LDR_DATA结构体的指针。这个结构体中保存了三个LIST_ENTRY的双向链表,从这三个链表中的任何一个都连着下一个LDR_DATA_TABLE_ENTRY结构中的LIST_ENTRY结构,这个结构保存了模块的信息,每个模块都有一个。具体的过程如下图
由于PEB_LDR_DATA和LDR_MODULE结构体是未导出的,所以需要我们在程序中自己定义。
其中的LIST_ENTRY在文档中的定义如下
由于我们的FullDllName和BaseDllName都是UNICODE_STRING类型,而这个类型在文档中没导出所有需要我们自己定义。
我们根据DllBase来找到我们需要隐藏的模块,而隐藏过程就是将三个链表断链。最终的隐藏代码如下
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
最后于 2022-1-11 15:59
被1900编辑
,原因: