0x00 注入原理
Windows 中大部分的应用程序都是基于消息机制的,它们都有一个过程函数,根据不同的消息完成不同的功能。
Windows 操作系统提供的钩子机制就是用来截获和监视系统中这些消息的。
局部钩子是针对某个线程的
全局钩子则是作用于整个系统的基于消息的应用。
全局钩子需要使用 DLL 文件,在 DLL 中实现相应的钩子函数。
接下来,以实现全局hook注入为例。
0x01 注入过程
1.在dll中实现全局hook,使用SetWindowsHookEx(),设置钩子类型为WH_GETMESSAGE。(这个API只能注入到有界面的进程里)
2.Loadlibaray() 获得dll的实例句柄
3. GetProcAddress() 根据实例句柄以及函数名来获取函数的地址. 也称为函数指针.
0x02 代码实现
dll实现:
#include "stdafx.h"
extern HMODULE g_hDllModule;
// 共享内存
#pragma data_seg("mydata")
HHOOK g_hHook = NULL;
#pragma data_seg()
#pragma comment(linker, "/SECTION:mydata,RWS")
// 钩子回调函数
LRESULT GetMsgProc(
int code,
WPARAM wParam,
LPARAM lParam)
{
return ::CallNextHookEx(g_hHook, code, wParam, lParam);
}
// 设置全局钩子
BOOL SetGlobalHook()
{
g_hHook = ::SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC)GetMsgProc, g_hDllModule, 0);
if (NULL == g_hHook)
{
return FALSE;
}
return TRUE;
}
// 卸载钩子
BOOL UnsetGlobalHook()
{
if (g_hHook)
{
::UnhookWindowsHookEx(g_hHook);
}
return TRUE;
}
cpp实现:
#include "stdafx.h"
#include <Windows.h>
int _tmain(int argc, _TCHAR* argv[])
{
typedef BOOL(*typedef_SetGlobalHook)();
typedef BOOL(*typedef_UnsetGlobalHook)();
HMODULE hDll = NULL;
typedef_SetGlobalHook SetGlobalHook = NULL;
typedef_UnsetGlobalHook UnsetGlobalHook = NULL;
BOOL bRet = FALSE;
do
{
hDll = ::LoadLibrary("GlobalHook_Test.dll");
if (NULL == hDll)
{
printf("LoadLibrary Error[%d]\n", ::GetLastError());
break;
}
SetGlobalHook = (typedef_SetGlobalHook)::GetProcAddress(hDll, "SetGlobalHook");
if (NULL == SetGlobalHook)
{
printf("GetProcAddress Error[%d]\n", ::GetLastError());
break;
}
bRet = SetGlobalHook();
if (bRet)
{
printf("SetGlobalHook OK.\n");
}
else
{
printf("SetGlobalHook ERROR.\n");
}
system("pause");
UnsetGlobalHook = (typedef_UnsetGlobalHook)::GetProcAddress(hDll, "UnsetGlobalHook");
if (NULL == UnsetGlobalHook)
{
printf("GetProcAddress Error[%d]\n", ::GetLastError());
break;
}
UnsetGlobalHook();
printf("UnsetGlobalHook OK.\n");
} while (FALSE);
system("pause");
return 0;
}