/** * @brief Makes sure the given replacement function is run once func is called. * * Tries to construct a trampoline for the given function (@see HardHook::cloneCode) * and then injects replacement function calling code into the first 6 bytes of the * original function (@see HardHook::inject). * * @param func Pointer to function to redirect. * @param replacement Pointer to code to redirect to. */ void HardHook::setup(voidFunc func, voidFunc replacement) { if (baseptr) return; fods("HardHook: Setup: Asked to replace %p with %p", func, replacement); unsigned char *fptr = reinterpret_cast<unsigned char *>(func); unsigned char *nptr = reinterpret_cast<unsigned char *>(replacement); call = (voidFunc) cloneCode((void **) &fptr); if (call) { bTrampoline = true; } else { // Could not create a trampoline. Use alternative method instead. bTrampoline = false; call = func; } DWORD origProtect; if (VirtualProtect(fptr, CODEPROTECTSIZE, PAGE_EXECUTE_READ, &origProtect)) { unsigned char **iptr = reinterpret_cast<unsigned char **>(&replace[1]); replace[0] = 0x68; // PUSH immediate 1 Byte *iptr = nptr; // (imm. value = nptr) 4 Byte replace[5] = 0xc3; // RETN 1 Byte // Save original 6 bytes at start of original function for (int i = 0; i < CODEREPLACESIZE; ++i) orig[i] = fptr[i]; baseptr = fptr; //TODO: Why do we want to force, even without a trampoline?!? We may // break the x86 instructions. // This is only safe as long as we always restore before calling .call. inject(true); DWORD tempProtect; VirtualProtect(fptr, CODEPROTECTSIZE, origProtect, &tempProtect); } else { fods("HardHook: setup failed; failed to make original code read and executable"); } }
/** * @brief Makes sure the given replacement function is run once func is called. * * Tries to construct a trampoline for the given function (@see HardHook::cloneCode) * and then injects replacement function calling code into the first 6 bytes of the * original function (@see HardHook::inject). * * @param func Pointer to function to redirect. * @param replacement Pointer to code to redirect to. */ void HardHook::setup(voidFunc func, voidFunc replacement) { if (baseptr) return; unsigned char *fptr = reinterpret_cast<unsigned char *>(func); unsigned char *nptr = reinterpret_cast<unsigned char *>(replacement); fods("HardHook: Asked to replace %p with %p", func, replacement); call = (voidFunc) cloneCode((void **) &fptr); if (call) { bTrampoline = true; } else { // Could not create a trampoline. Use alternative method instead. bTrampoline = false; call = func; } DWORD oldProtect; if (VirtualProtect(fptr, 16, PAGE_EXECUTE_READ, &oldProtect)) { unsigned char **iptr = reinterpret_cast<unsigned char **>(&replace[1]); replace[0] = 0x68; // PUSH immediate 1 Byte *iptr = nptr; // (imm. value = nptr) 4 Byte replace[5] = 0xc3; // RETN 1 Byte for (int i=0;i<6;i++) // Save original 6 bytes at start of original function orig[i] = fptr[i]; baseptr = fptr; inject(true); DWORD restoreProtect; VirtualProtect(fptr, 16, oldProtect, &restoreProtect); } else { fods("HardHook: Failed vprotect"); } }
void HardHook::setup(voidFunc func, voidFunc replacement) { int i; DWORD oldProtect, restoreProtect; if (baseptr) return; unsigned char *fptr = reinterpret_cast<unsigned char *>(func); unsigned char *nptr = reinterpret_cast<unsigned char *>(replacement); ods("HardHook: Asked to replace %p with %p", func, replacement); if (VirtualProtect(fptr, 16, PAGE_EXECUTE_READ, &oldProtect)) { call = (voidFunc) cloneCode((void **) &fptr); if (call) { bTrampoline = true; } else { bTrampoline = false; call = func; } unsigned char **iptr = reinterpret_cast<unsigned char **>(&replace[1]); *iptr = nptr; replace[0] = 0x68; replace[5] = 0xc3; for (i=0;i<6;i++) orig[i]=fptr[i]; baseptr = fptr; inject(true); VirtualProtect(fptr, 16, oldProtect, &restoreProtect); } else { ods("Failed initial vprotect"); } }