This is the code I'm using:
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <detours.h>
#include <fstream>
#define real_sendto 0x152942C6
void(__cdecl* originalFunction)();
void tompa_sendto() {
printf("Hellooo");
return originalFunction();
}
void hook() {
originalFunction = (void(__cdecl*)())DetourFunction((PBYTE)real_sendto, (PBYTE)tompa_sendto);
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
switch (ul_reason_for_call) {
case DLL_PROCESS_ATTACH: hook(); break;
case DLL_PROCESS_DETACH: return FALSE; break;
}
return TRUE;
}
This code has no problems, it places the hook at 0x152942C6 and I can see it's jumping to my tompa_sendto() and back again.
When I use this code instead as the hook it doesn't set the hook correctly,
in the memory I can see at 0x152942C6: jmp 00000000
void tompa_sendto() {
char buffer[] = {'x', 'y', 'z'};
return originalFunction();
}
Whatever code I place in tompa_sendto() crashes the program (becuase of the bad jmp), the only 2 codes that I've managed to put there is printf and messageBoxA.
I was able to reproduce the problem (only with detours 1.5 though), so I did some digging. It seems the problem is just that your detour function is empty.
When you end your call by returning from another call, the compiler do a specific optimization : it doesn't call the function, but defer the control directly, by jumping instead of calling. This doesn't push a return address, and therefore, when the next function return, it uses the previous function return address, and return from both at the same time. Long story short, the function ends with jmp func
instead of call func; ret
.
Now, your when your function is empty, this jump is the only instruction in the function. Another fact is that you call the original function through a variable, and this translate to an indirect jump. The thing is, Detours 1.5 specifically check if your function start with an indirect jump, and if it does, it hooks the target function with a direct jump based on the indirect jump it found. Why ? Because many functions, like DLL calls, are called through indirect jump tables, and Detours try to shortcut this if it find one.
In your case, the target function is hooked with a jump to originalFunction
, but this variable is 0 when you install the hook, hence the jmp 0
. Try to set originalFunction
to 3 before the hook, you will see. This problem won't happen if your function is not empty, so don't worry. A simple __nop();
before returning will make it works even if it is empty.