Hook por Trampolín (Ejemplo en el mismo Proceso)
Código
#include <windows.h> #include <stdio.h> DWORD HookFunction(LPCSTR lpModule, LPCSTR lpFuncName, LPVOID lpFunction, unsigned char *lpBackup); BOOL UnHookFunction(LPCSTR lpModule, LPCSTR lpFuncName, unsigned char *lpBackup); int Hooked_MessageBox(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType); BYTE BackUp[6]; LPCSTR Function = "MessageBoxExA"; void WinMainCRTStartup() { MessageBoxA(0, "=( Sin Hook", "", MB_OK); // Mensaje HookFunction("user32.dll", Function, Hooked_MessageBox, BackUp); // Hookear Función MessageBoxA(0, "=( Sin Hook", "", MB_OK); // Mensaje } int Hooked_MessageBox(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType) // Función a la que se desvia la función original { UnHookFunction("user32.dll", Function, BackUp); // Se llama a la función UnHook para evitar la recursividad int x = MessageBoxA(hWnd, "=) Hooked", lpCaption, uType); // Se llama la función original HookFunction("user32.dll", Function, Hooked_MessageBox, BackUp); // Se aplica el Hook nuevamente return x; // Se retorna el resultado de la función original } DWORD HookFunction(LPCSTR lpModule, LPCSTR lpFuncName, LPVOID lpFunction, unsigned char *lpBackup) // Función que realiza el Hook al API { DWORD dwAddr = (DWORD)GetProcAddress(GetModuleHandle(lpModule), lpFuncName); // Obtiene la dirección de la API // Array de opcodes en lenguaje de maquina (ASM) para desviar la función BYTE jmp[6] = { 0xe9, //jmp 0x00, 0x00, 0x00, 0x00, //address 0xc3 }; //retn ReadProcessMemory(GetCurrentProcess(), (LPVOID)dwAddr, lpBackup, 6, 0); // Se guardan los primeros 6 bytes de la función DWORD dwCalc = ((DWORD)lpFunction - dwAddr - 5); // ( to - from) - 5 // Se calcula la posición donde se escribira el salto WriteProcessMemory(GetCurrentProcess(), (LPVOID)dwAddr, jmp, 6, 0); // Se escribe en memoria los 6 bytes del salto return dwAddr; // Se retorna la dirección del API } BOOL UnHookFunction(LPCSTR lpModule, LPCSTR lpFuncName, unsigned char *lpBackup) // Función que retira el Hook de la API { DWORD dwAddr = (DWORD)GetProcAddress(GetModuleHandle(lpModule), lpFuncName); // Se obtiene la dirección de la API if (WriteProcessMemory(GetCurrentProcess(), (LPVOID)dwAddr, lpBackup, 6, 0)) // Si se logra escribir los bytes guardados en la función HookFunction { return TRUE; // Se retorna TRUE } return FALSE; // Sino entonces se retorna FALSE }
Inyecta código en un proceso externo (Ejemplo hacer que un proceso externo ejecute un MessageBox)
Código
#include <windows.h> #include <tlhelp32.h> #include <stdio.h> //Creamos un puntero a la api que queremos inyectar typedef int (WINAPI *datMessageBoxA) (HWND, LPCTSTR, LPCTSTR, UINT); //La estructura que inyectaremos struct datos { datMessageBoxA apiMessageBoxA; char titulo [20]; char mensaje [20]; }; //Declaración de funciones DWORD GetAdres(char *module, char *function); //La función que inyectaremos DWORD inyectada (datos *data) { data -> apiMessageBoxA (0, data->mensaje, data->titulo, 0); return 0; } //La función inyectora void inyectora() { int pid; // Este es el pid del proceso en el que nos queremos inyectar HANDLE proc; // El handle del proceso en el que inyectaremos datos dat; // El tipo de dato de la estructura DWORD TamFun; // El tamaño de la función a inyectar void* esp; // Lugar de memoria donde copiaremos nuestra función HANDLE handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); //Obtenemos el pid PROCESSENTRY32 procinfo = { sizeof(PROCESSENTRY32) }; while(Process32Next(handle, &procinfo)) { { CloseHandle(handle); pid = procinfo.th32ProcessID; } } CloseHandle(handle); //Abrimos el proceso en el que nos inyectaremos proc = OpenProcess(PROCESS_ALL_ACCESS, false, pid); //Metemos la dirección de la api en la estructura llamando a la función GetAdres dat.apiMessageBoxA = (datMessageBoxA) GetAdres ("USER32.DLL", "MessageBoxA"); //Inicializamos las variables que contendrán el mensaje //Reservamos espacio para nuestra estructura en el proceso a inyectar y la escribimos datos *dat_ = (datos*) VirtualAllocEx(proc, 0, sizeof(datos), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); WriteProcessMemory(proc, dat_, &dat, sizeof(datos), NULL); //Calculamos el tamaño de la función a inyectar TamFun = (long unsigned int) inyectora - (long unsigned int)inyectada; //Reservamos espacio para la función, escribimos en él y creamos un hilo esp = VirtualAllocEx(proc, 0, TamFun, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); WriteProcessMemory(proc, esp, (void*)inyectada, TamFun, NULL); CreateRemoteThread(proc, NULL, 0, (LPTHREAD_START_ROUTINE) esp, dat_, 0, NULL); } //La función main int main() { inyectora(); return EXIT_SUCCESS; } //Función que nos devuelve un DWORD con la dirección de una api DWORD GetAdres(char *module, char *function) { HMODULE dh = LoadLibrary(module); DWORD pf = (DWORD)GetProcAddress(dh,function); FreeLibrary(dh); return pf; }