WIN XP作業系統中任意進程的函數掛鈎 —-API HOOK 之菜鳥篇
來源:互聯網
上載者:User
shaoji (菜花書生的機機) 2003-12-17 12:17:56 在
VC/MFC /
進程/線程/DLL 提問API HOOK 菜鳥篇之WIN XP作業系統函數掛鈎
--------------掛鈎任意進程的任意函數
第一步:工具準備
1、VC++開發工具,2、Detours工具(Microsoft Research Detours Package,Version 1.5)包含Detours.h和串連 Detours.lib 。
第二步:具體實現
1。注入DLL到目標進程。如:
#include "stdafx.h"
#include "HookOther.h"
#include "HookOtherDlg.h"
#include "detours.h"
#include "tlhelp32.h"
//尋找名稱為hookWindow對應字串的視窗,hookWindow為要掛鈎的進程。
HWND thread_hwnd=::FindWindow(NULL,hookWindow);
if (NULL==thread_hwnd)
{
//沒找到相應的程式,則退出鉤子安裝程式
::MessageBox(NULL,"被掛鈎的視窗找不到","視窗沒找到",MB_OK);
return false;
}
//Snapshot拍一張系統所有進程的快照,找出要掛鈎的進程
PROCESSENTRY32 pe32={0};
pe32.dwSize=sizeof(PROCESSENTRY32);
DWORD Process_id;
HANDLE hSnapshot;
BOOL bFind=FALSE;
//PROCESSENTRY32:描述了一個被指定進程所應用的模組的struct
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
BOOL bOk = Process32First( hSnapshot, &pe32);
while (bOk&&(!bFind))
{
if (0==::lstrcmpiA(pe32.szExeFile, hookMoudle))
{
//得到要掛鈎的進程ID,為OpenProcess要的參數做準備
Process_id=pe32.th32ProcessID;
::MessageBox(NULL,pe32.szExeFile,"被掛鈎進程 為",MB_OK);
bFind=TRUE;
}
bOk = Process32Next(hSnapshot, &pe32);
}
if (NULL==Process_id)
{
::MessageBox(NULL,"被掛鈎進程ID為空白","進程ID為空白",MB_OK);
return false;
}
::CloseHandle(hSnapshot);
HANDLE hProcess=::OpenProcess(PROCESS_ALL_ACCESS,FALSE,Process_id);
if (NULL==hProcess)
{
::MessageBox(NULL,"被掛鈎進程為空白","hProcess為空白",MB_OK);
return false;
}
if (!DetourContinueProcessWithDllA(hProcess, szDllPath))
{
::MessageBox(NULL,"DetourContinueProcessWithDll_fail","Failed",MB_OK);
return false;
}
2。替換目標進程的函數。在HOOKDLL.dll的DllMain函數中實現,
如下:
// HookDll.cpp : Defines the entry point for the DLL application.
//
#include "stdafx.h"
#include "ImageHlp.h"
#include "detours.h"
//
#pragma comment(lib,"ImageHlp") //定義全域共用資料區段
#pragma data_seg("Shared")
HMODULE hmodCaller=NULL; //要調用函數的模組
PROC pfnOld=NULL; //原函數地址
PROC pfnNew=NULL; //新函數地址
#pragma data_seg()
#pragma comment(linker,"/Section:Shared,rws") //設定全域共用資料區段的屬性
//to do handle
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
if (ul_reason_for_call==DLL_PROCESS_ATTACH)
{
if (!(pfnOld=::GetProcAddress(::GetModuleHandle ("DialogDll.dll"),"ShowDlg")))
return FALSE;
if (!(pfnNew=::GetProcAddress(::GetModuleHandle("HookDll.dll"),"HookDialog")))
return FALSE;
DetourFunction((PBYTE)pfnOld,(PBYTE)pfnNew); //替換函數
}
return TRUE;
}
//new dialog
//新的對話方塊函數,用來替換舊對話方塊
void HookDialog()
{
//彈出新的對話方塊
::MessageBox(NULL,"這是新的對話方塊from Other DLL","Other DLL Dialog",MB_OK);
//調用原來的舊對話方塊
pfnOld();
}