-
-
[原创]初探DLL注入
-
发表于: 2022-7-10 16:39 8875
-
DLL注入是指向运行中的其它进程强制插入特定的DLL文件。从技术细节来说,DLL注入命令其它进程自行调用LoadLibrary()API,加载用户指定的DLL文件。DLL注入与一般DLL加载的区别在于,加载的目标进程是其自身或其他进程。
从上图可以看到,test.dll已被强制插入进程(本来notepad并不会加载test.dll)。加载到某一进程中的test.dll与已经加载到某一进程中的dll一样,拥有访问notepad.exe进程内存的权限。
使用LoadLibrary()API加载某个DLL时,该DLL中的DLLMain()函数会被调用执行。DLL注入的工作原理就是从外部促使目标进程调用LoadLibrary()API,所以会强制调用执行DLL的DLLMain函数。并且被注入的DLL拥有目标进程内存的访问权限,用户可以随意操作。
运行process explorer(或者火绒剑,任务管理器)获取notepad.exe进程的pid
可以看见process explorer.exe的pid为2788
运行InjectDll.exe将myhack.dll注入到notepad.exe进程当中。可以看到dll文件已经被注入到里面。
要想在process explorer中看见注入的dll文件,需要依次选择view->Lower Pane view->DLLS选项
进行注入时需要注意
同时可以看见文件内已经多了一个html文件,此文件是dll中所指定的文件。
在DLLMmain()函数中可以看到,这个dll被加载(DLL_PROCESS_ATTACH)时,先输出一个字符串("<myhack.dll> Injection!!!"),然后再创建线程调用函数(ThreadProc)。在ThreadProc函数中通过调用URLDownloadToFile来下载指定网站的index.html文件。前面提到过,向进程注入dll后会调用dll的DLLMain函数。所以当dll文件注入到exe进程后,会调用URLDownloadToFile下载文件。
main函数的主要功能时检查输入程序的参数,然后调用InjectDLL函数。InjectDLL函数是用来进行dll注入的核心,其作用是使目标进程自行调用LoadLibrary这个api。
下面来详细分析一下injectDll函数
调用 OpenProcess这个API,借助程序运行时以参数形势传递过来的dwPID值,获取exe进程的句柄(PROCESS_ALL_ACCESS)。得到PROCESS_ALL_ACCESS之后,就可以用获取的句柄控制对应进程。
需要把即将加载的dll文件的路径通知目标进程。因为任何内存空间都无法进行写入操作,所以先使用VirtualAllocEx() API在目标进程的内存空间中分配一块缓冲区,且指定的缓冲区大小为dll文件路径字符串的长度。
使用WriteProcessMemory将DLL路径字符串(xxx\xxx\xxx.dll)写入到分配所得缓冲区地址。WriteProcessMemory所写的内存空间也是hProcess句柄所指的目标进程的内存空间。
调用LoadLibrary前需要先获取其地址。LoadLibraryW()是LoadLibrary()的Unicode字符串版本。
我们的目标明明是获取加载到 notepad.exe 进程的kernel32.dll的 LoadLibraryW的起始地址,但代码却用来获取加载到 InjectDll.exe进程的kernel32.dll的 LoadLibraryW的起始地址。如果加载到 notepad.exe 进程中的kernel32.dl的地址与加载到 InjectDll.exe 进程中的kernel32.dll的地址相同,那么上面的代码就不会有什么问题。但是如果kernell32.d在每个进程中加载的地址都不同,那么上面的代码就错了,执行时会发生引用错误 .
根据 Os 类型、语言、版本不同,kerne32.dll加载的地址也不网。并且 Vista /7中应用了新的 ASLR 功能,每次启动时。系统 DLL 加载的地址都会改0。但是在系统运行期间它都会被映射( Mapping )到号进程的相同地址。
Windows 作系统中, DLL 首次进入内存称为“加载”( Loading ),以后其他进程需要使用相网 DLL 时不必再次加载,只要将加载过的 DLL 代码与资源映射一下即可,这种映射技术有利于提高肉存的使用效率。
像上面这样, OS 核心 DUL 会被加载到自身固有的地址, DLL 注人利用的就是 Windows Os 这一特性(该特性也可能会被恶意使用,成为 Windows 安全漏洞)。导人InjectDll.exe进程中LoadlibraryW地址与导人notepad.exe进程中的LoadLibraryWO地址是相同的。
在目标进程中运行远程线程,pThreadProc是exe进程内存中LoadlibraryW的地址,pRemoteBuf是exe进程内存中dll字符串的地址
CreateRemoteThread用来在目标进程中执行其创建的线程,其函数原型如下:
除第一个参数 hProcess 外,其他参数与 CreateThread ()函数完全一样。 hProcess 参数是要执行线程的目标进程(或称“远程进程”、“宿主进程”)的句柄。 IpStartAddress 与 IpParameter 参数分别给出线程函数地址与线程参数地址。需要注意的是,这2个地址都应该在目标进程虚拟内存空间中(这样目标进程才能认识它们)。
查看ThreadProc与LoadLibrary。两函数都有一个4字节的参数,并返回一个4字节的值。也就是说,二者形态结构完全一样灵感即源于此。调用 CreateRemoteThread 时,只要将 LoadLibrary函数的地址传递给第四个参数 IpStartAddress ,把要注人的 DLL 的路径字符串地址传递给第五个参数 IpParameter 即可(必须是目标进程的虚拟内存空间中的地址)。由于前面已经做好了一切准备,现在调用该函数使目标进程加载指定的 DLL 文件就行了。
CreateRemoteThread (函数最主要的功能就是驱使目标进程调用LoadLibrary函数,进
而加载指定的 DLL 文件。
DLL卸载(DLL Ejection):将强制插入进程的DLL弹出的技术
原理:驱使目标进程调用FreeLibrary() API
先注入dll到目标进程
注入成功后,卸载dll
分析一下EjectDll.exe
获取进程中加载的DLL信息。
获取目标进程的句柄。
获取FreeLibrary API地址
在目标进程中运行线程
计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows
填入dll文件路径
修改LoadAppInit_DLLs
重启系统使修改生效,使用火绒剑,process explorer查看是否注入成功。可以看见已经被注注入成功了。并且是注入了所有加载了user32.dll的进程。但是由于此dll的目标是notepad.exe进程,所以只要当运行这个exe之后才会有所动作。
myhack2.dll的源码比较简单。主要目的为加载进程为notepad.exe的程序,然后隐藏并连接指定网站。
钩子过程(hook procedure)是系统调用的回调函数
安装钩子时,钩子过程需要在DLL内部,该DLL的示例句柄(instance handle)即hMod
线程ID如果为0,则钩子为“全局钩子”
用SetWindowsHookEx()设置好钩子后,在某个进程中生成指定消息时,操作系统会将相关DLL文件强制注入相应进程。
首先运行HookMain.exe
赞赏
- BUUCTF-reverse1解题思路 8095
- [原创]浅学PE结构(一) 5341
- [原创]初探DLL注入 8876
- [求助]未来职业方向渗透还是逆向、二进制之类的? 5867
- 从crackme程序中接触VB文件以及加密算法 7853