DLL注入-全局钩子注入
原理介绍
这是一种操作起来比较简单的dll注入,只需要了解相关的3个API即可上手使用,当然,这些API的本意不是dll注入,但刚好可以这么用罢了
对于消息的处理,Windows系统提供了专门处理消息的Hook API:
SetWindowsHookEx:
HHOOK
WINAPI
SetWindowsHookExW(
_In_ int idHook, //钩子的类型
_In_ HOOKPROC lpfn, //Hook函数的地址
_In_opt_ HINSTANCE hmod, //Hook函数所在模块的句柄
_In_ DWORD dwThreadId); //需要被挂钩的线程ID,全局则设置0
这个API有4个参数,1个是钩子类型,1个是被挂钩的线程id,以及两个需要的我们来获取到的参数:模块句柄、回调函数
当我们把第四个参数dwThreadId设置为0的时候,则是全局Hook,Hook所有基于消息机制的进程,Windows 提供了一种钩子:WH_GETMESSAGE,可以直接将DLL文件注入到所有基于消息机制的程序中去,这是一种dll注入的方法,也是一种Hook消息的方法(作为Hook的使用,我们后面讲Hook部分的时候单独细讲)
钩子的类型,详情见官方文档:https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setwindowshookexa
不同的类型的钩子,回调函数参数含义不同,但是参数名相同,均类似以下结构:
LRESULT CALLBACK KeyboardProc(
int code, //钩子编码
WPARAM wParam, //虚拟键编码
LPARAM lParam) //按键信息
而这个回调函数在每次消息触发的时候,都会执行一次,为了不影响消息的正常执行,我们需要把消息给传递下去:
CallNextHookEx API:
LRESULT
WINAPI
CallNextHookEx(
_In_opt_ HHOOK hhk,
_In_ int nCode,
_In_ WPARAM wParam,
_In_ LPARAM lParam);
相对的,除了设置钩子还有取消钩子的API UnhookWindowsHookEx:
BOOL
WINAPI
UnhookWindowsHookEx(
_In_ HHOOK hhk);//钩子句柄
dll注入代码示例
因为用这种方法进行dll注入,需要dll文件,而注入函数需要dll的模块句柄,所以把注入API写在dll里会很方便,然后通过另一个程序来加载这个dll并且导入其中的函数来进行操作。
dllmain.cpp
//回调函数,仅作为dll注入可不管,直接传递消息
LRESULT CALLBACK GetMsgProc(int code ,WPARAM wParam,LPARAM lParam) {
return CallNextHookEx(g_Hook,code,wParam,lParam);
}
//设置钩子,进行dll注入
VOID SetHookOn() {
g_Hook = SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, hInst, 0);
}
//取消钩子,卸载注入的dll
VOID SetHookOff() {
UnhookWindowsHookEx(g_Hook);
}
//dll加载之后执行的内容
BOOL APIENTRY DllMain( HMODULE hModule,DWORD ul_reason_for_call,LPVOID lpReserved){
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}