动态Dll注入和卸载(Dynamic DLL Injection And Unloading)
Dynamic DLL Injection And Unloading
提到注入技术,第一想到的可能是游戏外挂(我第一次听到注入也是在外挂。。。),病毒等等,但注入也会被应用到插件开发,应用拓展,修复bug上
远程线程注入
OpenProcess 用待注入进程的id拿到句柄
VirtualAllocEx 注入进程内申请远程一块虚拟空间
WriteProcessMemory 往这块虚拟内存写入dll名称
GetModuleHandle 获取kernel32.dll句柄
常见的系统模块kernel32.dll user32.dll gdi32.dll advapi32.dll shell32.dll等加载到各个进程虚拟地址的偏移是相同的(这个原因也就导致我们32位注入器只能注入32位进程,64位只能注入64位进程),这一点让我好像明白了windows dll为什么采用直接修改内存代码的基址重定位,不怕浪费内存吗?,这样看如果地址一样,直接在内存中映射一份就可以多进程共享了,(不过在实验(xp sp3里)中发现,或者说是多个本来映射到同一块,某个进程改时复制一块
aslr是每次启动系统时,系统模块加载基址会变
感觉这种机制也是为什么linux的服务端为什么会windows安全很多的原因之一
GetProcAddress从kernel32中获取LoadLibraryW函数地址
CreateRemoteThread向远程进程开启远程线程来调用LoadLibraryW注入到进程,进程执行DllMain
hack.dll
// dllmain.cpp : 定义 DLL 应用程序的入口点。 |
Inject.exe
|
如果注入另一帐户拥有的进程内存需要先获得SeDebug权限,需要我们注入器在管理员权限下做提权操作
SE_DEBUG_NAME TEXT (“SeDebugPrivilege”) | 调试和调整另一帐户拥有的进程内存所必需的。 用户权限:调试程序。 |
---|
BOOL SetPrivilege(LPCTSTR lpszPrivilege, BOOL bEnablePrivilege) { |
全局消息钩子注入
用SetWindowsHookEx把钩子挂入钩链
同样是32位程序只能给32位程序挂钩子
KeyHook.dll
// dllmain.cpp : 定义 DLL 应用程序的入口点。 |
MainHook.cpp
|
注册表注入
下面路径的AppInit_DLLs设置为要注入的DLL的路径并且将LoadAppInit_DLLs的值改成1,当程序重启的时候,所有加载user32.dll的进程都会根据AppInit_Dlls中的DLL路径加载指定的DLL
计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows |
可以在dll里加个判断只注入想注入的进程
if( !GetModuleFileName( NULL, szPath, MAX_PATH ) )//检索包含指定模块的文件的完全限定路径。 模块必须由当前进程加载。 |
DLL卸载
- CreateToolhelp32Snapshot去拍一个TH32CS_SNAPALL参数的系统快照
- Process32First和NEXT通过PROCESSENTRY32结构体的szExeFile来比较找到notepad
- CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPID)进程的所有模块快照找到dll加载基址 即dll句柄
- 后面和加载一样,创建远程线程FreeLibrary掉库
|