標籤:mat cat cti code setw 函數 turn new dial
1.首先編寫一個 win32 dll工程.
#include "stdafx.h"
int WINAPI add(int a,int b){ return a+b;}
BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ){ return TRUE;}
在def檔案添加顯式匯出: (沒找到def檔案需要添加)
LIBRARYDESCRIPTION "ADD LA"EXPORTS add @1;
2.編寫調用此dll的主程式 建立基於對話方塊的MFC工程
在dlg標頭檔裡添加聲明:
#include <windef.h>public: HINSTANCE hAddDll; typedef int (WINAPI*AddProc)(int a,int b); AddProc add;
在程式入口 編寫載入函數:
if (hAddDll==NULL) hAddDll=::LoadLibrary("add.dll"); add=(AddProc)::GetProcAddress(hAddDll,"add");
添加一個按鈕函數 調用:
int a=1; int b=2; int c=add(a,b); CString temp; temp.Format("%d+%d=%d",a,b,c); AfxMessageBox(temp);
到這裡運行主程式 就會看到。彈窗 1+2 = 3的結果。
3.編寫hook dll 建立一個MFC dll 工程。
在InitInstance函數中添加:
hinst=::AfxGetInstanceHandle(); DWORD dwPid=::GetCurrentProcessId(); hProcess=OpenProcess(PROCESS_ALL_ACCESS,0,dwPid); //調用注入函數 Inject(); return CWinApp::InitInstance();
所有的聲明:
#pragma data_seg("SHARED")static HHOOK hhk=NULL; //滑鼠鉤子控制代碼static HINSTANCE hinst=NULL; //本dll的執行個體控制代碼 (hook.dll)#pragma data_seg()#pragma comment(linker, "/section:SHARED,rws")CString temp; //用於顯示錯誤的臨時變數bool bHook=false; //是否Hook了函數bool m_bInjected=false; //是否對API進行了HookBYTE OldCode[5]; //老的系統API入口代碼BYTE NewCode[5]; //要跳轉的API代碼 (jmp xxxx)typedef int (WINAPI*AddProc)(int a,int b);//add.dll中的add函數定義AddProc add; //add.dll中的add函數HANDLE hProcess=NULL; //所處進程的控制代碼FARPROC pfadd; //指向add函數的遠指標DWORD dwPid; //所處進程ID://end of 變數定義//函數定義void HookOn();void HookOff(); //關閉鉤子LRESULT CALLBACK MouseProc(int nCode,WPARAM wParam,LPARAM lParam); //滑鼠鉤子函數void Inject(); //具體進行注射,替換入口的函數int WINAPI Myadd(int a,int b); //我們定義的新的add()函數BOOL InstallHook(); //安裝鉤子函數void UninstallHook(); //卸載鉤子函數
聲明函數的實現:
LRESULT CALLBACK MouseProc(int nCode,WPARAM wParam,LPARAM lParam){ LRESULT RetVal= CallNextHookEx(hhk,nCode,wParam,lParam); return RetVal;}BOOL InstallHook(){ hhk=::SetWindowsHookEx(WH_MOUSE,MouseProc,hinst,0); return true;}void UninstallHook(){ ::UnhookWindowsHookEx(hhk);} void Inject(){ if (m_bInjected==false) { m_bInjected=true; HMODULE hmod=::LoadLibrary("add.dll"); add=(AddProc)::GetProcAddress(hmod,"add"); pfadd=(FARPROC)add; if (pfadd==NULL) { AfxMessageBox("cannot locate add()"); } // 將add()中的入口代碼儲存入OldCode[] _asm { lea edi,OldCode mov esi,pfadd cld movsd movsb } NewCode[0]=0xe9;//實際上0xe9就相當於jmp指令 //擷取Myadd()的相對位址 _asm { lea eax,Myadd mov ebx,pfadd sub eax,ebx sub eax,5 mov dword ptr [NewCode+1],eax } //填充完畢,現在NewCode[]裡的指令相當於Jmp Myadd HookOn(); //可以開啟鉤子了 }}void HookOn() { ASSERT(hProcess!=NULL); DWORD dwTemp=0; DWORD dwOldProtect; //將記憶體保護模式改為可寫,老模式儲存入dwOldProtect VirtualProtectEx(hProcess,pfadd,5,PAGE_READWRITE,&dwOldProtect); //將所屬進程中add()的前5個位元組改為Jmp Myadd WriteProcessMemory(hProcess,pfadd,NewCode,5,0); //將記憶體保護模式改回為dwOldProtect VirtualProtectEx(hProcess,pfadd,5,dwOldProtect,&dwTemp); bHook=true; }void HookOff()//將所屬進程中add()的入口代碼恢複{ ASSERT(hProcess!=NULL); DWORD dwTemp=0; DWORD dwOldProtect; VirtualProtectEx(hProcess,pfadd,5,PAGE_READWRITE,&dwOldProtect); WriteProcessMemory(hProcess,pfadd,OldCode,5,0); VirtualProtectEx(hProcess,pfadd,5,dwOldProtect,&dwTemp); bHook=false; }int WINAPI Myadd(int a,int b){ //截獲了對add()的調用,我們給a,b都加1 a=a+1; b=b+1; HookOff();//關掉Myadd()鉤子防止死迴圈 int ret; ret=add(a,b); HookOn();//開啟Myadd()鉤子 return ret;}
在def檔案 添加顯式匯出:
InstallHook MouseProc Myadd UninstallHook
hook dll 就完成了。
4.回到主程式 添加2個按鈕 一個注入 一個卸載:
注入:
hinst=LoadLibrary("hook.dll"); if(hinst==NULL) { AfxMessageBox("no hook.dll!"); return; } typedef BOOL (CALLBACK *inshook)(); inshook insthook; insthook=::GetProcAddress(hinst,"InstallHook"); if(insthook==NULL) { AfxMessageBox("func not found!"); return;
DWORD pid=::GetCurrentProcessId();
BOOL ret=insthook();
卸載:
typedef BOOL (CALLBACK *UnhookProc)(); UnhookProc UninstallHook; UninstallHook=::GetProcAddress(hinst,"UninstallHook"); if(UninstallHook==NULL) UninstallHook(); if (hinst!=NULL) { ::FreeLibrary(hinst); } if (hAddDll!=NULL) { ::FreeLibrary(hAddDll); } CDialog::OnCancel();
運行主程式:
計算:顯示1+2 =3
注入:顯示 1+2=5
完。
有任何不明白的地方歡迎騷擾:0x7317AF28
windows鉤子 Hook樣本