之前曾经用了三篇文章的篇幅论述了如何利用DLL来实现进程的隐藏(详见《反病毒攻防研究第009篇:DLL注入(上)——DLL文件的编写》、《反病毒攻防研究第010篇:DLL注入(中)——DLL注入与卸载器的编写》和《反病毒攻防研究第011篇:DLL注入(下)——无DLL的注入》),其原理其实就是将恶意程序编写为DLL程序,然后采用DLL注入的方式将其注入到目标进程中,这样恶意程序就不会主动创建进程,也就达到了隐藏的目的。但即便如此,我们依旧可以使用查看进程中的DLL程序的软件查出这些DLL,比如我之前编写的进程管理器(详见《安全类工具制作第004篇:进程管理器(上)》与《安全类工具制作第005篇:进程管理器(下)》)。所以说采用这种方式依旧不够隐秘,因此,这次我所讨论的内容是将DLL文件也进行隐藏。
在我们的Windows操作系统中维护着一个叫做TEB(ThreadEnvironment Block)的结构体,它描述了线程的状态(在不同的Windows版本中,它的定义可能会有些不同,所以具体问题要具体分析)。系统在此TEB中保存频繁使用的线程相关的数据,位于用户地址空间。进程中的每个线程都有自己的一个TEB。一个进程的所有TEB都以堆栈的方式,存放在从0x7FFDE000(Windows XP)开始的线性内存中,每4KB为一个完整的TEB。在用户模式下,当前线程的TEB位于独立的4KB段,可通过CPU的FS寄存器来访问该段,一般存储在[FS:0]。在用户态下WinDbg中可用命令$thread取得TEB地址。通过对TEB的解析,我们可以找到PEB(Process Environment Block)结构体,它位于TEB结构体偏移0x30的位置。PEB包含了进程的信息。每个进程都有自己的PEB信息,位于用户地址空间,所以程序能够直接访问。这个结构体中有一个名为Ldr的项,它指向一个PEB_LDR_DATA结构体。该结构体保存了进程所读取的模块的信息,位于PEB偏移的0x0C处。它在MSDN中的定义如下:
[cpp] view plaincopy
这里出现了名为LIST_ENTRY的结构体,该结构体其实是一个链表。其定义如下:
[cpp] view plaincopy
需要说明的是,在MSDN对于_PEB_LDR_DATA的说明中,仅仅显示出了InMemoryOrderModuleList这一项,而事实上,完整的结构如下:
[cpp] view plaincopy
[1] [2] [3] 下一页