<ReversingEngineering>关于windows32位系统下的dll注入技术经验汇
上个学期把自己闷在图书馆一直在看关于逆向工程技术方面的书,从入门到初级,现在也敢说自己一条腿已经迈进了这片知识的大门里,因为该博客刚开通先将一些经验记录下来,也是留给自己一方面做个参照。 《逆向工程核心原理》((韩)李承远 )《Reversing:逆向工程揭密(电子工业出版社)》《黑客反汇编揭密》((俄)卡巴斯基 )
dll注入技术是一门逆向工程中非常基础非常初步的技术,也是打开大门的钥匙,逆向破解的前提条件。API勾取 ,Rootkit进程隐藏都需要dll注入为先决条件。基本方法如下(每一种方法都经过本人亲自多次试验,有不同意见欢迎评论):
(1)通过windows钩子函数来将dll注入进程之中
首先是钩子函数API的定义:
HOOK SetWindowsHookEx(
int idHook;
HOOKPROC lpfn;
HINSTANCE hMod;
DWORD dwThreadId;
)///////// 在头文件#include〈windows.h〉中的定义
SetWindowsHookEx proto :dword,dword,dword,dword
;;;;;; 在MASM32中的定义
(以全局键盘钩子为例)钩子过程是隶属于操作系统的,而非某个单独的进程或者线程,只要安装好了钩子,无论是哪个进程,就要将WM_CHAR或者WM_SYSCHAR消息就会强制将调用钩子函数的dll加载到相应的进程之中(所以钩子回调函数必须写进一个Dll之中)。这样一来钩子既可以通过dll在OS的消息循环队列之中拦截住键盘消息或者将消息“加工”后转达给下一个钩子回调函数或者应用程序(取决于是否调用了CallNextHookEx函数)。
通过在写有钩子回调函数的dll中加入一些你真正想要使用的function可以完成dll的注入。
///////////////////////////////////////////////////////////////////
(2)通过创建远程线程来将dll注入某一个进程
这种方法的核心思想在于:##不同的应用程序所装载的系统关键dll的虚拟地址一致##
////////////////////////////////////////////////////////////////////////////////////
“在Vista/7中应用了新的ASLR功能,使系统dll加载的地址每次都会改变,但在系统运行期间他都会被映射(Mapping)到每个进程相同的地址”
(《逆向工程核心原理》((韩)李承远)2014年5月第1版 P207)
/////////////////////////////////////////////////////////////////////////////////////
于是我们可以通过在自己的程序之中调用LoadLibraryA或者LoadLibraryW函数来获得函数入口,而这个函数的地址通过传递到创建在另一个进程之中的远程线程之中就可以用来加载自己想要加载的dll (所以前提是dll已经存在于被注入进程所在的主机之中)
具体步骤总结如下://///切换输入法太烦了,这段还是用英语写吧
1) OpenProcess(param...)////To get the handle of process as the parameter of CreateRomoteThread
2) VirtualAllocEx(param...) ///// To alloc a block of memory to store the path/name of DLL (WCHAR or CHAR depends)
WriteProcessMemory(param...) ////// Fill in the block alloced
3) GetModuleHandle("kernel32.dll") ///// Get the virtual address /handle of kernel32.dll which stores the entry of LoadLibraryA/W API
GetProcAddress(hKernelMod,”LoadLibray“) ///////////As stated above to get entry
4) CreateRemoteThread(param...) ////As call this API the DLL will be injected in remote thread's loadlibrary function
5) Memory Cleaning Freeing Deleting,Handles Shutting down
到此 通过创建远程线程来完成dll注入的工作就完成了。
/////////////////////////////////////////////////////////////////////////////
(3)通过静态修改PE格式文件的磁盘映像来完成dll的静态注入
熟悉整个PE格式文件的装载过程之后,我们可以通过使用一些非常简单的十六进制修改器来完成dll的安全注入过程
1)通过DOS头找到PE头,然后在PE头中的Import Directory Table中添加一个新的结构体(windows.h中的命名为IMAGE_IMPORT_DESCRIPTOR)来通过windows应用程序loader来装载dll。
这里有个问题是 原PE头中的IDT(Import Directory Table)的尾部是否有足够的空间来允许我们添加一个结构体(LOADER是通过一个全NULL的结构体来判断IDT是否结束),这里问题产生了分支,如果空间足够的话,我们直接暴力修改IDT是没有任何问题的,但是如果空间不足够我们来加入一个新的结构体单元,我们的选择就只有将整个IDT的位置转移到(一.另一个节区的空闲空间之中 二.静态创建一个新的节区来存放IDT)
方法一:我们在清空原来映像中的IDT之后,把需要添加的结构体添加好,再修改指向IDT的RVA就完成了DLL的注入。
方法二:创建新的节区我们需要扩大整个静态文件的映像大小,并且精确计算新节区的起始RVA再做修改后,重复方法一的过程就完成了dll静态注入。(这一部分内容很多,这里不再赘述。)