DLL注入
消息钩取
常规的Windows消息流
1.发生键盘输入事件时,WM_KEYDOWN消息被添加到[OS message queue]。
2.OS判断哪个应用程序中发生了事件,然后从[OS message queue]取出消息,添加到相应应用程序的[application message queue]中。
3.应用程序(如记事本)监视自身的[application message queue],发现新添加的WM_KEYDOWN消息后,调用相应的事件处理程序处理。
SetWindowsHookEx()
使用SetWindowsHookEx()API可以很简单的实现消息钩子,定义如下
1 | HHOOK SetWindowsHookEx( |
Tips:若dwThreaId设置为0,则安装的钩子为“全局钩子”(Global Hook)它会影响到运行中的(以及以后要运行的)所有进程。
DLL注入
DLL注入的原理是从外部促使目标进程调用LoadLibrary()API(与一般DLL加载相同)
实现方法
1、创建远程线程(CreateRemoteThread()API)
2、使用注册表(AppInit_DLLs值)
3、消息钩取(SetWindowsHookEx()API)
调试时可以利用OD的各种断点功能
DLL卸载
原理是利用FreeLibrary()API,不过仅适用于卸载自己强制注入的DLL文件,PE文件直接导入的DLL文件无法在进程运行过程中卸载
通过修改PE加载DLL
修改的关键是找到知道PE文件的格式及组成,了解需要修改的内容
关于IDT的移动
新增DLL需要修改文件的IDT(Import Directory Table,导入地址表),若是空间不够,需要找到另外的地方整个移动IDT
有三种方法:1、查找文件中的空白区域。2、增加文件最后一个节区的大小。3、在文件末尾添加新节区。
方法一需要注意的是节区在磁盘文件和内存中的大小是不同的,需要计算容量
IMAGE_OPTIONAL_HEADER的导入表结构体成员用于指出IDT的位置(RVA)及大小,需要增加IID(IMAGE_IMPORT_DESCRIPTOR)结构体大小的字节数,删除绑定导入表(该表为可选项),创建新的IDT并在末尾加入与要导入的dll文件相对应的IID,并设置其指向其他数据结构(INT、Name、IAT)的成员的RVA值,最后更改IAT节区的属性值(加上WRITE属性以便PE装载器正常进行写入操作)
代码注入
代码注入是一种向目标进程插入独立运行代码并使之运行的技术,其一般调用CreateRemoteThread() API以远程线程的形式运行插入的代码,亦称为线程注入。代码以线程过程(ThreadProcedure)形式插入,而代码中使用的数据则以线程参数的形式插入,即代码和数据是分别注入的。
优点:占用内存少、难以查找痕迹、不需要额外的DLL文件,适用于代码量小且简单的情况。
使用汇编语言注入
基本操作是压入参数-调用函数,注意当把字符串放入代码段时,有一个很有意思的call指令用法
CALL 002D003F,就把002D0033作为返回地址压入了栈中,同时跳转到“函数“地址2D003F开始执行指令并等待RETN指令,但2D003F其实并不是函数,所以CALL作用仅仅是将紧随其后的字符串地址压入栈,然后再跳转到下一指令