提示:在测试dll注入的时候,要在虚拟机上测试,否则一旦出现小失误,可能会引起蓝屏等各种问题
1.注册表注入法
2.windows挂钩法
3.远程线程注入法
4.函数转发器
使用到的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的程序无法注入
前提:必须是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 -> 回到程序自身的消息处理函数
优点:灵活,可以只挂指定线程,也可以全局,并且可以随时挂载和卸载
缺点:只能处理消息
原理和方法:先获取目标进程句柄与权限,给目标进程创建线程,通过创建的线程使用LoadLibrary()来加载我们的dll,从而触发DLL_PROCESS_ATTACH
用到的WindowsAPI:
OpenProcess();//打开目标进程 CreateRemoteThread(); //给非自身的进程 创建线程 LoadLibrary(); //加载dll //由于LoadLibrary的dll名称需要储存到目标进程中,所以需要在目标进程里申请内存空间 VirtualAllocEx() //在目标进程里 申请空间 也就是分配虚拟内存 VirtualFreeEx()//释放内存 ReadProcessMemory(); //读进程内存 WriteProcessMemory(); //写进程内存
优点:线程独立,针对进程,复杂
缺点:没有权限,一切白干,无法全局挂载,只针对某个进程操作
原理:用山寨的dll替换原版的dll, 并把原版的函数调用转发给原版的dll来保证功能正常运行的同时,再加入自己的逻辑代码
方法:把原版的dll名字 例如 原.dll 修改为 原_副本.dll
然后我们自己创建一个dll 名字写成山寨的 原.dll
并在代码里写
#pragma comment(linker,"/exprot:hello=原_副本.hello") //意思就是 当程序向这个山寨dll 调用 hello函数的时候 我们给他转发到原版的 hello函数去处理