全局消息钩子注入 Dll

常用的线程注入方法有:远程线程注入、全局消息钩子注入、应用层 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 文件中设置全局消息钩子,但笔者感觉比较麻烦,所以在此不多做详述。

posted @ 2024-09-02 22:44  lostin9772  阅读(69)  评论(0)    收藏  举报