Hook概述
Hook也就是鈎子,在Windows中大部分的應用程序都是基于消息機制,會根據不同的消息使用消息過程函數完成不同的功能。而鈎子是一種消息處理機制,它可以比你的應用程序先獲得消息,可以用來截獲、監視系統的消息,改變執行流程實現特定的功能。對于全局鈎子來說,它會影響所有應用程序,所以鈎子函數必須在DLL中實現。
函數介紹SetWindowsHookEx
作用:将程序定義的鈎子函數安裝到挂鈎鍊中,安裝鈎子的程序可以監視系統是否存在某些類型的時間,這些事件與特定線程或調用線程所在的桌面中的所有線程相關聯。
函數聲明:
HHOOK WINAPI SetWindowsHookEx(
_In_ int idHook,
_In_ HOOKPROC lpfn,
_In_ HINSTANCE hMod,
_In_ DWORD dwThreadId
)
參數:idHook:安裝的鈎子程序的類型,具體值參考官方手冊
lpfn:指向鈎子程序過程的指針,若參數dwThreadId為0或者指示了一個其他進程創建的線程之标識符,則參數lpfn必須指向一個動态鍊接中的挂鈎處理過程。否則,參數lpfn可以指向一個與當前進程相關的代碼中定義的挂鈎處理過程。
hMod:包含由lpfn參數指向的鈎子過程的DLL句柄。
dwThreadId:與鈎子程序關聯的線程标識符,如果為0,則鈎子過程與系統中所有線程相關聯。
返回值:成功:返回鈎子過程句柄失敗:返回NULL
UnhookWindowsHookEx
作用:卸載鈎子
函數聲明:
BOOL WINAPI UnsetGlobalHook(
_In_ HHOOK hhk
)
參數:hhk:卸載的鈎子句柄
實例代碼使用IDE:VS2019創建一個DLL項目
pch.h:
#include "framework.h"
extern "C" _declspec(dllexport) int SetGlobalHook();
extern "C" _declspec(dllexport) LRESULT GetMsgProc(int code, WPARAM wParam, LPARAM lParam);
extern "C" _declspec(dllexport) BOOL UnsetGlobalHook();
#endif //PCH_H
dllmain.cpp
// dllmain.cpp : 定義 DLL 應用程序的入口點。
#include "pch.h"
HMODULE g_hDllModule = NULL;
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH: {
g_hDllModule = hModule;
break;
}
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
鈎子過程:
SetGlobalHook(): 設置全局鈎子,WH_GETMESSAGE為監視發送到消息隊列的消息的鈎子,第二個參數則為鈎子的回調函數。GetMsgProc(): 鈎子的回調函數,CallNextHookEx表示将當前鈎子傳遞給下一個鈎子,若返回值為0,表示中斷鈎子傳遞,對鈎子進行攔截。UnsetGlobalHook(): 卸載鈎子共享内存: 由于全局鈎子是以DLL形式加載到進程中,進程都是獨立的,要将進程句柄傳遞給其他進程,可以使用共享内存突破進程獨立性,使用"/SECTION:mydata,RWS"設置為可讀可寫可共享的數據段。
pch.cpp:
#include "pch.h"
#include #include 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;
}
最終生成Dll1.dll
創建c 空項目編譯下面代碼,将Dll1.dll放在生成的exe下,運行
hook.cpp:
#include #include typedef BOOL(*PEN_HOOKSTART)();
typedef BOOL(*PEN_HOOKSTOP)();
int main() {
//加載dll
HMODULE hDll = LoadLibrary(L"./Dll1.dll");
if (NULL == hDll)
{
printf("LoadLibrary Error[%d]\n", ::GetLastError());
return 1;
}
BOOL isHook = FALSE;
//導出函數地址
PEN_HOOKSTART SetGlobalHook = (PEN_HOOKSTART)GetProcAddress(hDll, "SetGlobalHook");
if (NULL == SetGlobalHook)
{
printf("SetGlobalHook:GetProcAddress Error[%d]\n", GetLastError());
return 2;
}
PEN_HOOKSTOP UnsetGlobalHook = (PEN_HOOKSTOP)GetProcAddress(hDll, "UnsetGlobalHook");
if (NULL == UnsetGlobalHook)
{
printf("UnsetGlobalHook:GetProcAddress Error[%d]\n", GetLastError());
return 3;
}
isHook=SetGlobalHook();
if (isHook) {
printf("Hook is ok!\n");
}
else {
printf("Hook is error[%d]\n", GetLastError());
}
system("pause");
UnsetGlobalHook();
FreeLibrary(hDll);
return 0;
}
查看效果
使用Process Explorer查看dll:
可以看到已經注入了Dll1.dll
參考文獻
【網絡安全學習攻略】
,更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!