Sono interessato all'aggancio e ho deciso di vedere se potevo agganciare alcune funzioni. Non mi interessava usare una libreria come le deviazioni perché voglio avere l'esperienza di farlo da solo. Con alcune fonti che ho trovato su internet, sono stato in grado di creare il codice qui sotto. È semplice, ma funziona bene. Tuttavia, quando si agganciano funzioni chiamate da più thread, risulta estremamente instabile. Se due chiamate vengono effettuate quasi alla stessa ora, si bloccherà. Dopo alcune ricerche penso di aver bisogno di creare una funzione trampolino. Dopo aver cercato per ore tutto ciò che non riuscivo a trovare altro che una descrizione generale su cosa fosse un trampolino. Non sono riuscito a trovare nulla di specifico sulla scrittura di una funzione di trampolino o su come funzionassero davvero. Se qualcuno può aiutarmi a scriverne uno, pubblicare alcune fonti, o almeno indirizzarmi nella giusta direzione, raccomandando alcuni articoli, siti, libri, ecc. Lo apprezzerei molto.Come creare una funzione trampolino per gancio
Di seguito è riportato il codice che ho scritto. È molto semplice, ma spero che altri possano imparare da esso.
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;
}
Stavo per pubblicare un collegamento a GD, ma ho notato che anche tu sei un membro. Hai provato a usare la loro funzione di ricerca? Ne vengono fuori tonnellate di esempi :) –
Puoi controllare il codice di EasyHook, credo che sia open source. Ci sono anche molti altri esempi in giro. Se hai intenzione di usarlo in un'applicazione distribuita, ti consiglio di utilizzare una libreria (come EasyHook) che può già gestire la ricorsione su gancio/trampolino, threading e alcune delle cose divertenti. – ssube
@Tom Knapen Ho cercato GD, MPGH e alcuni altri siti prima di pubblicare. La ricerca di 'trampolino' su GD restituisce alcuni post leggermente correlati ma non quello che sto cercando. – Stratus