#include <IOSTREAM> #include <WINDOWS.H> using namespace std; void main() { //與靜態庫相關聯 HMODULE hDll = LoadLibrary("HookAPIDll.dll"); printf("被鉤掉的那個API,MessageBox,如今變成了打開calc.exe\n"); printf("你如今看的是一個計算器,對不對,哈哈!\n"); //第一個MessageBox MessageBox(NULL,"這是第一個MessageBox","Test",0); printf("觀察發現,會出現第二個MessageBox\n"); //若是在靜態庫DLL中 沒有 調用HookOff();的話,全部的messagebox都會被改掉,若是調用了的話, // 那麼下面這個messagebox將能正常使用 //第二個MessageBox MessageBox(NULL,"這是第二個MessageBox,若是你只看到這一個MessageBox的話,說明第一個MessageBox已經被鉤掉了。,你能看到第二個MessageBox,那是由於這裏用了OffHook,將地址又弄回去了,其實這裏我也搞不太清楚,不過你能夠去試試,若是不調用OffHook()函數的話,全部的MessageBox都出不來的,病毒思想,哈哈哈!","Test",0); } void Add() { }
// HookAPIDll.cpp : Defines the entry point for the DLL application. // #include "stdAfx.h" //咱們在這裏定一個全局的函數指針能夠用來保存原來的函數的地址 PROC g_Func = NULL; BYTE g_NewFunc[5]; BYTE g_OldFunc[5]; //定義一個全局的句柄 HANDLE g_hProcess = NULL; void WINAPI MyMessageBox(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaption,UINT uType); void WINAPI MyMainProc(); BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: { MyMainProc(); break; } case DLL_PROCESS_DETACH: { break; } } return TRUE; } void HookAPI(LPCTSTR ModuleName,LPCTSTR ApiName,FARPROC lpNewFunc) { //後面調用是這樣的 // HookAPI("user32.dll","MessageBoxA",(FARPROC)MyMessageBox); // 這裏傳進來的是咱們本身寫的MyMessageBox, // 整個函數的功能就是(還要結合後面的兩個函數) // 在user32.dll模塊中,去找到MessageBox這個函數, // 而後計算出咱們本身寫的那個函數MyMessageBox 的偏移, // 最後將它蓋掉原來的函數,也就是執行MessageBox 的時候實際上執行的是咱們本身的MyMessageBox函數 //FARPROC 是一個4字節指針,指向一個函數的內存地址 //這裏須要那個庫 還有就是API函數的名字 g_NewFunc[0] = 0xe9; //這是咱們構建的字符數組中的第一個字節 //咱們經過兩個函數能夠獲得原來的那個API函數的地址 g_Func=GetProcAddress(GetModuleHandle(ModuleName),ApiName); //給我一個模塊,給我一個函數,GetProcAddress的返回值就是這個函數的偏移地址 //這步驟執行以後,g_Func中保存的就是原先函數的地址,,也就是還沒被鉤掉的MessageBox函數的地址 //e8 10ab memcpy(g_OldFunc,(void*)g_Func,5); g_hProcess = GetCurrentProcess(); //咱們要這個值是爲了可以往進程的內存中寫值 //GetCurrentProcess 得到當前進程,獲開進程以後(得到進程的地址空間),須要把地址寫進去, //g_hProcess是一個全局的句柄 //覆蓋函數的jmp後的4個字節指令 DWORD* pStart = NULL; pStart = (DWORD*)&g_NewFunc[1] ; //pStart指向的是0xe9,也就是jmp後面的那個地址 *pStart = (DWORD)lpNewFunc - (DWORD)g_Func - 5; //計算咱們實際要運行的函數和原來函數的偏移 //這裏lpNewFunc是一個 FARPROC 類型的指針,指向函數的內存地址, } void SetHook() { DWORD dwFlag; WriteProcessMemory(g_hProcess,(void*)g_Func,(void*)g_NewFunc,5,&dwFlag); //把g_NewFuc中保存的5個字節的內容,寫到g_Func中去, //這裏的意思,就是把咱們本身寫的MyMessaBox函數,去替換原來的MessageBox函數 //由於經過HookAPI函數,g_Func存放的是原來函數的地址(0xe8 .....), // g_NewFunc存放的是如今函數的偏移地址以及一個jmp(0xe9 .....) //因此,進程中的內存地址空間的這5個字節就被改寫了。 //因此原本要執行系統的MessaBox,就變爲執行咱們本身寫的MessagBox了。 } //功能和SetHook相反 void HookOff() { DWORD dwFlag; WriteProcessMemory(g_hProcess,(void*)g_Func,(void*)g_OldFunc,5,&dwFlag); } void WINAPI MyMainProc() { HookAPI("user32.dll","MessageBoxA",(FARPROC)MyMessageBox); SetHook(); } void WINAPI MyMessageBox(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaption,UINT uType) { HookOff(); // MessageBoxA(hWnd,"Hooking MessageBox","Test",MB_OK); STARTUPINFO si; PROCESS_INFORMATION pi; ZeroMemory( &si, sizeof(si) ); si.cb = sizeof(si); ZeroMemory( &pi, sizeof(pi) ); CreateProcess("C:\\Windows\\System32\\calc.exe", // No module name (use command line). NULL, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi ); // SetHook(); //這裏能夠繼續設置而後繼續抓API函數 }