dll注入的几种方式


提示:在测试dll注入的时候,要在虚拟机上测试,否则一旦出现小失误,可能会引起蓝屏等各种问题

dll注入的几种方式:

1.注册表注入法

2.windows挂钩法

3.远程线程注入法

4.函数转发器


1.注册表注入法

使用到的windowsAPI函数:

RegOpenKeyEx()	//打开注册表键值
RegQueryValueEx()//查询键值
RegSetValueEx()//设置键值
RegCloseKey()//关闭键值

前提:只有使用了User32.cll的程序,才能被注入

原理:window系统上,如果 LoadAppInit_DLLs 的值大于0 则凡是直接或间接调用过User32.cll的程序  都会先LoadLibrary一次AppInit_DLLs 里的全部dll

注入方法:

打开注册表:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows

里面一般都会有 AppInit_DLLs 和 LoadAppInit_DLLs 这两项

其中 AppInit_DLLs 里 填写dll路径列表 LoadAppInit_DLLs 是否大于0则决定了User32.cll程序运行前 是否要加载AppInit_DLLs 列表里的dll

所以注入方式就是 把要注入的dll路径 加入AppInit_DLLs  并 把LoadAppInit_DLLs的值改为大于0即可触发我们的dll里的 DLL_PROCESS_ATTACH (dll函数入口的一个分支)

优点:全局注入,不需要注入的程序可以自己过滤

缺点:死版,不主动,没使用User32.cll的程序无法注入

2.Windows挂钩法(Hook)

前提:必须是GUI应用程序,并且只能处理消息(GUI是图形化程序CUI是控制台程序)

使用到的windowAPI:

SetWindowsHookEx() //将指定的代码 挂载到指定的进程中(如果dwThreadld参数为null,则会挂载全局)
UnhookWindowsHookEx() //解除挂载,取消Hook
CallNextHookEx() //扔给下一个hook处理

原理:

GUI的应用程序内部一般都有捕获消息处理消息,但是它捕获到消息后并不会立即处理,而是先丢给所有的hook到进程的dll列表都处理一遍,再回到程序自身来处理消息

在hook中处理完消息 必须要使用CallNextHookEx()来传递给下一个hook处理,否则就会断掉这个消息(除非特殊情况,故意想拦截不让后面的处理程序执行)

过程图:   GUI应用程序 -> 捕获消息 -> 1.dll -> 2.dll -> 3.dll -> n.dll -> 回到程序自身的消息处理函数

优点:灵活,可以只挂指定线程,也可以全局,并且可以随时挂载和卸载

缺点:只能处理消息

3.远程线程注入法

原理和方法:先获取目标进程句柄权限,目标进程创建线程,通过创建的线程使用LoadLibrary()来加载我们的dll,从而触发DLL_PROCESS_ATTACH

用到的WindowsAPI:

OpenProcess();//打开目标进程
CreateRemoteThread(); //给非自身的进程 创建线程
LoadLibrary(); //加载dll
//由于LoadLibrary的dll名称需要储存到目标进程中,所以需要在目标进程里申请内存空间
VirtualAllocEx() //在目标进程里 申请空间  也就是分配虚拟内存
VirtualFreeEx()//释放内存
ReadProcessMemory(); //读进程内存
WriteProcessMemory(); //写进程内存

优点:线程独立,针对进程,复杂

缺点:没有权限,一切白干,无法全局挂载,只针对某个进程操作

4.函数转发器

原理:用山寨的dll替换原版的dll, 并把原版的函数调用转发给原版的dll来保证功能正常运行的同时,再加入自己的逻辑代码

方法:把原版的dll名字 例如  原.dll  修改为  原_副本.dll

然后我们自己创建一个dll 名字写成山寨的 原.dll

并在代码里写

#pragma comment(linker,"/exprot:hello=原_副本.hello")
//意思就是 当程序向这个山寨dll 调用 hello函数的时候  我们给他转发到原版的 hello函数去处理