/* Terminology: * * fish = function to patch * hook = patch to apply * coolbox = overwritten bytes and stack fixer * scales = memory security flags */ #include #include #include #include #include #include #include "hooks.h" #include "ollydisasm/disasm.h" /*register int *stackp asm ("esp"); register int *basep asm ("ebp");*/ unsigned long CleanBiteOff(const uint8_t *ptr, size_t amount); // how many bytes should i overwrite to fit a jump and not leave garbage behind int attachRawHook(uintptr_t fish, uintptr_t hook) { #define JMP_SIZE 5 unsigned long safeSize = CleanBiteOff((uint8_t*)fish, JMP_SIZE); uint8_t *overwrite = malloc(safeSize); overwrite[0] = 0xE9;//call e8 -- jmp e9 for (int i = JMP_SIZE; i < safeSize; i++) overwrite[i] = 0x90; DWORD oldScales, newScales; //__asm("int $3"); uint8_t* coolbox; #define XCHG_SIZE 13 #define FOOTER_SIZE 2*JMP_SIZE+XCHG_SIZE if ((coolbox = VirtualAlloc(NULL, safeSize + FOOTER_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE)) == NULL) return __HOOK_VIRTUALALLOC_COOLBOX; uintptr_t relative = (uintptr_t)coolbox + safeSize - fish; memcpy(&overwrite[1], &relative, JMP_SIZE-1); memcpy(coolbox, (void*)(fish), safeSize); relative = -relative; /* push ecx mov ecx, %coolbox xchg dword [esp+4], ecx xchg dword[esp], ecx {0x51,0xB9,0,0,0,0,0x87,0x4C,0xE4,0x04,0x87,0x0C,0xE4} */ #define FOUR_BYTES 0,0,0,0 uint8_t coolboxfooter[FOOTER_SIZE] = {0xE9,FOUR_BYTES,0x51,0xB9,FOUR_BYTES,0x87,0x4C,0xE4,0x04,0x87,0x0C,0xE4, 0xE9/*,FOUR_BYTES*/}; memcpy(&coolboxfooter[1], &relative, JMP_SIZE-1); memcpy(&coolboxfooter[JMP_SIZE+2], &coolbox, JMP_SIZE-1); relative = hook - ((uintptr_t)coolbox + safeSize + FOOTER_SIZE); memcpy(&coolboxfooter[JMP_SIZE+XCHG_SIZE+1], &relative, JMP_SIZE-1); memcpy(coolbox+safeSize, coolboxfooter, FOOTER_SIZE); if (VirtualProtect((LPVOID) fish, safeSize, PAGE_READWRITE, &oldScales) == 0) return __HOOK_PROTECTION_DISABLE; memcpy((void*)fish, overwrite, safeSize); if (VirtualProtect((LPVOID)fish, safeSize, oldScales, &newScales) == 0) return __HOOK_PROTECTION_ENABLE; return __HOOK_ALL_OK; } unsigned long CleanBiteOff(const uint8_t *ptr, size_t amount) { static t_disasm disasm; unsigned long size = 0; do {size += Disasm(ptr+size, 16, 0x00401AAC, &disasm, DISASM_SIZE);} while(size < amount); return size; }