我對掛鉤感興趣,我決定查看是否可以掛鉤一些功能。我對使用像走彎路這樣的圖書館不感興趣,因爲我希望有自己的經驗。有了我在互聯網上找到的一些消息,我可以創建下面的代碼。這是基本的,但它工作正常。但是,當掛鉤函數被多線程調用時,它證明是非常不穩定的。如果兩個電話幾乎同時發生,它會崩潰。經過一番研究後,我認爲我需要創建一個蹦牀功能。在找了幾個小時之後,我無法找到其他任何關於什麼是蹦牀的一般描述。我找不到任何關於編寫蹦牀功能的具體內容,或者他們的工作方式。如果有人能幫我寫一篇文章,發佈一些消息來源,或者至少通過推薦一些文章,網站,書籍等來指引我正確的方向。我將不勝感激。如何爲掛鉤創建蹦牀功能
下面是我寫的代碼。這是非常基本的,但我希望其他人可以從中學習。
TEST.CPP
#include "stdafx.h"
Hook hook;
typedef int (WINAPI *tMessageBox)(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType);
DWORD hMessageBox(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType)
{
hook.removeHook();
tMessageBox oMessageBox = (tMessageBox)hook.funcPtr;
int ret =oMessageBox(hWnd, lpText, "Hooked!", uType);
hook.applyHook(&hMessageBox);
return ret;
}
void hookMessageBox()
{
printf("Hooking MessageBox...\n");
if(hook.findFunc("User32.dll", "MessageBoxA"))
{
if(hook.applyHook(&hMessageBox))
{
printf("hook applied! \n\n");
} else printf("hook could not be applied\n");
}
}
hook.cpp
#include "stdafx.h"
bool Hook::findFunc(char* libName, char* funcName)
{
Hook::funcPtr = (void*)GetProcAddress(GetModuleHandleA(libName), funcName);
return (Hook::funcPtr != NULL);
}
bool Hook::removeHook()
{
DWORD dwProtect;
if(VirtualProtect(Hook::funcPtr, 6, PAGE_EXECUTE_READWRITE, &dwProtect))
{
WriteProcessMemory(GetCurrentProcess(), (LPVOID)Hook::funcPtr, Hook::origData, 6, 0);
VirtualProtect(Hook::funcPtr, 6, dwProtect, NULL);
return true;
} else return false;
}
bool Hook::reapplyHook()
{
DWORD dwProtect;
if(VirtualProtect(funcPtr, 6, PAGE_EXECUTE_READWRITE, &dwProtect))
{
WriteProcessMemory(GetCurrentProcess(), (LPVOID)funcPtr, Hook::hookData, 6, 0);
VirtualProtect(funcPtr, 6, dwProtect, NULL);
return true;
} else return false;
}
bool Hook::applyHook(void* hook)
{
return setHookAtAddress(Hook::funcPtr, hook);
}
bool Hook::setHookAtAddress(void* funcPtr, void* hook)
{
Hook::funcPtr = funcPtr;
BYTE jmp[6] = { 0xE9, //jmp
0x00, 0x00, 0x00, 0x00, //address
0xC3 //retn
};
DWORD dwProtect;
if(VirtualProtect(funcPtr, 6, PAGE_EXECUTE_READWRITE, &dwProtect)) // make memory writable
{
ReadProcessMemory(GetCurrentProcess(), (LPVOID)funcPtr, Hook::origData, 6, 0); // save old data
DWORD offset = ((DWORD)hook - (DWORD)funcPtr - 5); //((to)-(from)-5)
memcpy(&jmp[1], &offset, 4); // write address into jmp
memcpy(Hook::hookData, jmp, 6); // save hook data
WriteProcessMemory(GetCurrentProcess(), (LPVOID)funcPtr, jmp, 6, 0); // write jmp
VirtualProtect(funcPtr, 6, dwProtect, NULL); // reprotect
return true;
} else return false;
}
我打算髮佈一個鏈接到GD,但我只是注意到你也是那裏的成員。你嘗試過使用他們的搜索功能嗎?它提出了大量的例子:) – 2012-02-17 20:13:08
你可以檢查EasyHook的代碼,我相信它是開源的。還有很多其他的例子。如果你打算在部署的應用程序中使用它,我建議使用一個庫(如EasyHook),它可以處理掛鉤/蹦牀上的遞歸,線程和一些有趣的事情。 – ssube 2012-02-17 20:19:52
@Tom Knapen在我發佈之前,我搜索了GD,MPGH和其他一些網站。在GD上搜索「蹦牀」會返回一些稍微相關的帖子,但不是我正在尋找的內容。 – Stratus 2012-02-17 20:24:09