The signature of the MyUC2Packets
is probably incorrect. Since the functions use stdcall calling convention they are required to clean up the stack before they return. If you call one of these functions with the wrong number of parameters the stack pointer will be incorrect when it returns.
The reason it does not happen when the print statements are removed is because the compiler is likely optimizing the forwarding call down to a single jmp
instruction. When the print statements are included the detour function actually has work to do and adjusts the stack by an incorrect value before it returns. If MyUC2Packets
expects 6 parameters but the function signatures only take 5 parameters this will cause problems any time the detour function can't be optimized down.
The code below demonstrates this by simulating the detour setup in your example. The function being hooked takes 4 parameters but the detour expects only 3. It simulates calls from a client expecting a function that takes 4 parameters.
#include <stdio.h>
#include <ios>
#pragma inline_depth(0)
typedef void (WINAPI *Function3)(int, int, int);
typedef void (WINAPI *Function4)(int, int, int, int);
void WINAPI FinalFunction(int x, int y, int z, int q);
void WINAPI DetourFunction(int x, int y, int z);
void WINAPI DetourFunctionPrint(int x, int y, int z);
Function3 callFinalFunction = reinterpret_cast<Function3>(FinalFunction);
Function4 callDetourFunction = reinterpret_cast<Function4>(DetourFunction);
Function4 callDetourFunctionPrint = reinterpret_cast<Function4>(DetourFunctionPrint);
void WINAPI FinalFunction(int x, int y, int z, int q)
{
std::cout << x << " " << y << " " << z << " " << q << std::endl;
}
void WINAPI DetourFunction(int x, int y, int z)
{
callFinalFunction(x, y, z); // Optimzed to a single jmp instruction.
}
void WINAPI DetourFunctionPrint(int x, int y, int z)
{
printf("%d", x);
printf("%d\n", y);
callFinalFunction(x, y, z);
}
int main()
{
// This works
callDetourFunction(0, 1, 2, -1);
// This does not
callDetourFunctionPrint(0, 1, 2, -1);
return 0;
}