1. 程式人生 > >SetWindowsHookEx為某個程序安裝鉤子

SetWindowsHookEx為某個程序安裝鉤子

HMODULE GetModuleHandle (LPCTSTRlpModuleName);
功能說明

獲取一個特定的應用程式或動態連結庫的模組控制代碼,且這個模組必須已經被載入到呼叫者的程序空間中,否則呼叫LoadLibrary

GetModuleHandle(NULL);
這將返回自身應用程式控制代碼(好像一直是0x40000000,和GetCurrentProcess(一直是0xFFFFFFFF)是不一樣的,一個是模組一個程序,用在不同的地方)即使是在模組內,返回的也是呼叫它的應用程式的控制代碼,而不是模組本身的控制代碼。

要在模組中獲得模組本身的控制代碼,可以通過如下函式獲得,該函式通過模組內的函式獲得模組的控制代碼

HMODULE ModuleFromAddress(PVOID pv) 
{
MEMORY_BASIC_INFORMATION mbi;
if(::VirtualQuery(pv, &mbi, sizeof(mbi)) != 0)
{
return (HMODULE)mbi.AllocationBase;
}
else
{
return NULL;
}
}

傳入的引數為模組內的任意函式

要獲得模組內某一匯出函式的地址

FARPROC GetProcAddress
HMODULE hModule, // DLL模組控制代碼
LPCSTR lpProcName // 函式名

要獲得程序或模組的磁碟檔名,用如下函式

DWORD GetModuleFileName(
HMODULE hModule,
LPTSTR lpFilename,
DWORD nSize
);
函式引數說明:
HMODULE hModule 裝載一個程式例項的控制代碼。如果該引數為NULL,該函式返回該當前應用程式全路徑。
LPTSTR lpFileName 是你存放返回的名字的記憶體塊的指標,是一個輸出引數
DWORD nSize,裝載到緩衝區lpFileName的最大值

要獲得別的程序的全路徑 可以用GetModuleFileNameEx 或者命令列 wmic process

獲得自身程序id

GetCurrentProcessId

獲得其他程序id

1 通過GetWindowThreadProcessId函式:找出某個視窗的建立者(執行緒或程序),返回建立者的標誌符。

DWORD GetWindowThreadProcessId(
HWND hWnd,
LPDWORD lpdwProcessId
);

而獲得視窗控制代碼,可以用FindWindow函式

2 通過快照獲得所有程序

//獲取對應程序名的ID
DWORD GetSpecifiedProcessId(const char *pszProcessName)
{
DWORD id;
//獲得系統快照程序控制代碼 (通俗的講, 就是得到當前的所有程序)
HANDLE hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0) ;
PROCESSENTRY32 pInfo; //用於儲存程序資訊的一個數據結構
pInfo.dwSize = sizeof(pInfo);
//從快照中獲取程序列表
Process32First(hSnapShot, &pInfo) ; //從第一個程序開始迴圈 
do
{
//這裡的 pszProcessName 為你的程序名稱
if(strcmp(strlwr(_strdup(pInfo.szExeFile)), pszProcessName) == 0)
{
id = pInfo.th32ProcessID ;
break ;
}
}while(Process32Next(hSnapShot, &pInfo) != FALSE);
return id; //id 就是你要的程序PID 了
}
ps:獲得模組控制代碼的方法

// 取得本程序的模組列表
HANDLE hSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, ::GetCurrentProcessId());


// 遍歷所有模組,分別對它們呼叫ReplaceIATEntryInOneMod函式,修改匯入地址表
MODULEENTRY32 me = { sizeof(MODULEENTRY32) };
BOOL bOK = ::Module32First(hSnap, &me);
while(bOK)
{

bOK = ::Module32Next(hSnap, &me);
}
::CloseHandle(hSnap);

3 通過控制代碼獲得id

DWORD WINAPI GetProcessId( _In_ HANDLE Process );

GetCurrentProcessId=GetProcessId(GetCurrentProcess);

通過id獲得控制代碼的方法

HANDLE OpenProcess(
DWORD dwDesiredAccess, //渴望得到的訪問許可權(標誌)
BOOL bInheritHandle, // 是否繼承控制代碼
DWORD dwProcessId// 程序標示符
);

例如HANDLE hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, ID );

SetWindowsHookEx 其四個引數分別為鉤子型別 鉤子函式地址 鉤子函式所在DLL的例項控制代碼 安裝鉤子後想監控的執行緒的ID號 (設定ID為0,安裝一個全域性的鉤子)返回引數為鉤子控制代碼