常用的线程注入方法有:远程线程注入、全局消息钩子注入、APC 应用层异步注入、ZwCreateThreadEx 强力注入和纯汇编实现的线程注入等。
今天我们讲一下全局消息钩子注入的这种方法,其原理是通过 SetWindowsHookEx
函数,注册一个全局消息钩子,当我们截获到消息时(只要权限足够,任何基于消息机制的程序都会被截获消息),会先强制将我们制定的 Dll 注入到目标程序。
step 1
首先我们编写一个回调函数,每当我们的全局消息挂钩截获到消息的时候,都会跳转到我们的回调函数中,由于我们的目的只是将 Dll 文件注入到指定进程,所以我们不对截获的全局消息进行处理,直接转发:
HHOOK g_hHook = NULL;
// 截获消息处理函数
LRESULT CALLBACK GetMsgProc(int code, WPARAM wParam, LPARAM lParam)
{
// 不对截获的消息做任何处理,直接将 hook 消息传递给当前 hook 链的下一个过程
return CallNextHookEx(g_hHook, code, wParam, lParam);
}
step 2
首先我们需要加载 Dll 文件,获取句柄:
HMODULE hModule = NULL;
// 加载动态链接库
hModule = LoadLibraryA("C:\\Users\\Administrator\\Desktop\\console_Dll.dll");
step 3
然后我们就可以通过 SetWindowsHookEx
函数设置全局消息挂钩了:
// 设置全局消息挂钩,将挂钩函数安装到 hook 链中
g_hHook = SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC)GetMsgProc, hModule, 0);
if (NULL == g_hHook)
{
printf("全局消息钩子注入失败\r\n");
system("pause");
return -1;
}
else
{
printf("全局消息钩子注入成功\r\n");
system("pause");
}
需要注意的是,该函数的第一个参数表示需要挂钩消息的类型,第二个参数表示截获消息处理函数,第三个参数表示需要注入的 Dll,第四个参数需要注入的线程(0 表示注入所有线程)。
当然,我们也可以对特定进程的线程进行遍历,指定截获特定进程中线程产生的消息。
step 4
最后我们要记得卸载挂钩,卸载后被加载到各个进程中的 Dll 也会被卸载。
// 卸载全局消息挂钩
if (NULL != g_hHook)
{
UnhookWindowsHookEx(g_hHook);
}
system("pause");
运行程序的时候要注意,最好在虚拟机中运行(否则路过的狗都会被注入一下),由于之前写的 Dll 文件中在被注入到进程中的时候会弹出一个消息框,因此在物理机上进行全局消息钩子注入 Dll 可能会导致机器卡死,运行结果如下:
当然我们也可以在 Dll 文件中设置全局消息钩子,但笔者感觉比较麻烦,所以在此不多做详述。
标签:钩子,截获,Dll,消息,全局,注入 From: https://www.cnblogs.com/lostin9772/p/18393685