最近复习到DLL注入技术,这里特地来探讨一下。
原理:在目标进程中申请一块内存,写入你的 DLL 路径字符串。然后利用 CreateRemoteThread 在目标进程中启动一个新线程,线程的入口函数直接指向 LoadLibraryA,参数就是你写的路径。
特点:教科书级的注入方式。
缺点:太容易被拦截。反作弊只需要 Hook LoadLibrary 就能当场抓获。
注入流程:
1 打开进程 OpenProcess 2 远程进程中申请空间 VirtualAllocEx 3 向远程进程写入数据 WriteProcessMemory 4 在远程进程中创建远程线程 CreateRemoteThread 5 等待线程结束返回 WaitForSingleObject 6 释放空间 VirtualFreeEx
B 往 A注入需要提供线程函数的地址(需要在 A 中),和线程函数的参数(需要在 A 中)
线程函数是有格式要求的,返回类型是 DWORD ,调用约定是Win Api,默认调用约定stdcall,参数是 void* 指针,满足这个要求才能调用。有个 LoadLibrary 这个函数,返回值是个句柄(DWORD),参数虽然不是void* 但是可以转成void* 用。
所以在进程B中创建远程线程以后,直接把线程函数地址指向 LoadLibrary (A 进程中的地址),这个地址直接显式调用即可,因为这个模块是每个程序一定加载的,地址一样的。
LoadLibrary 需要一个参数,一个字符串地址,需要用 WriteProcessMemory 写入到 进程 A 中。就获得地址了。
自己执行 LoadLibrary 会获得一个模块句柄,远程线程注入可以通过 GetExitCodeThread 获取线程退出码获取。
DLL注入的代码:
DLL自身代码:
原理:利用 Windows 系统的消息机制(如键盘按键、窗口激活)。当你为一个窗口安装钩子(WH_KEYBOARD 等)时,系统会自动将你的 DLL 加载到所有符合条件的进程中。
特点:由系统“护送”进入目标,常用于全局监控。
缺点:容易造成系统卡顿,且目标进程必须有窗口和消息循环。
举个例子:普通场景 :比如输入法监听键盘事件、UI自动化工具监听窗口消息来进行模拟点击、按键精灵等记录和播放操作序列等。 恶意场景 :比如键盘记录木马(keylogger)窃取密码、远控软件劫持鼠标操作、注入恶意代码到指定进程等。 本文主要关注利用消息钩子注入代码的场景。
消息钩子是通过 SetWindowsHookEx和 UnhookWindowsHookEx这两个API来安装和卸载的。
DLL部分的代码:
注入器部分代码:
又叫做DLL Hijacking,原理:利用 Windows 加载 DLL 的搜索路径优先级。比如游戏需要加载 version.dll,你写一个同名的 DLL 放在游戏根目录下。游戏启动时会优先加载你的 DLL。
技术点:你需要在自己的 DLL 中把原本的函数调用再导回到真正的系统 DLL(转发),否则游戏会崩溃。
特点:不需要启动注入器,随游戏启动。
动态链接库 .Dll,英文全称:Dynamic Link Library。在Windows系统中运行可执行文件时,系统会调用相应需要的.dll链接库,系统的默认优先级规则是最优先调用是当前目录下的.dll链接库,寻找不到则去系统目录下寻找。 如果程序没有使用SetDllDirectory()函数设定dll加载绝对路径,则程序很大可能性即存在dll劫持注入漏洞。
Windows XP SP2及其以上版本系统默认dll链接库加载优先规则如下:启用 Dll安全模式搜索规则: 1.加载应用程序的目录 2.系统目录 3.16 位系统目录 4.Windows目录 5.当前目录 6.PATH 环境变量中列出的目录
禁用 Dll安全模式搜索规则: 1.加载应用程序的目录 2.当前目录 3.系统目录 4.16 位系统目录。 5.Windows目录 6.PATH 环境变量中列出的目录
程序在执行的时候Windows系统会优先在当前目录下寻找所需要.dll链接库,如果寻找不到则再去系统目录下寻找。(上述优先规则仅限于Windows XP SP2及其以上系统) 具体细节可查看微软官方文档: 动态链接库搜索顺序
DLL代码:
CPP代码:
原理:直接修改目标程序的 .exe 文件(静态修改),在它的导入表(Import Table)里强行添加一项你的 DLL 名字。
这种DLL注入的特点不同于前面分析的经典DLL注入、CreateRemoteThread(创建远程线程)等,上面的技术特点是使用Loadlibrary、createremotethreat等API函数来实现相应的注入,其注入以后会生成rundll32.exe,并使用rundll32来调用相应的DLL,其处置的时候只需要将rundll32.exe关闭就可以。
而使用导入到注入表这种注入会把相应的恶意DLL写入到目标程序的导入表中,这样的话每次调用目标程序时都会调用恶意的DLL程序,这样就可以加载相应的恶意DLL,而处置时必须将相应的DLL删除,并恢复导入表,不过个人建议比较好的处置方式是重新安装应用程序。
特点:静态修改,一次成型,永久生效。
当你双击运行一个.exe 时,Windows 加载器会按以下步骤执行:
1将.exe 文件映射到进程虚拟地址空间
2.解析.exe 的 导入目录表(Import Directory Table) ,获取所有依赖的 DLL 名称
3.依次将这些 DLL 加载到进程地址空间
4.解析每个 DLL 的导出表,找到程序需要的函数地址
5.将这些函数地址写入.exe 的 导入地址表(IAT, Import Address Table)
6. 跳转到.exe 的入口点(Entry Point)开始执行
静态 IAT 劫持的本质 :在步骤 2 之前,直接修改磁盘上.exe 文件的导入目录表 ,强行添加一个指向我们 DLL 的条目。这样 Windows 加载器会 "误以为" 这个 DLL 是程序的原生依赖,在程序启动时自动加载它,并执行我们 DLL 中的代码。
对于x86系统:
x86测试代码:
对于x64系统:
传播安全知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2天前
被BOSC叛忍编辑
,原因: