将挂钩函数与 cout 一起使用时应用程序崩溃

Application crashes when using hooked function with cout

我正在尝试使用它的地址挂钩一个函数,到目前为止它总体上运行良好!

唯一的问题是,当结合使用 std::cout 和挂钩 WinAPI 的 MessageBoxA 时,它会崩溃!奇怪的是,它只在特定情况下崩溃,如果它与 printf 或简单地 int i = MessageBoxA(...);

结合调用则不会

为了测试,我将函数地址处的指令直接设为returns 32我知道的钩子不多,但这只是为了测试。

// mov eax, 32
// ret
const DWORD instructionCount = 6;
BYTE instructions[instructionCount] = { 0xB8, 0x20, 0x00, 0x00, 0x00, 0xC3 };

除了必须更改 VirtualProtect() 区域的保护之外,然后 现在我基本上就是做

memcpy(MessageBoxA, instructions, instructionCount);

现在用这个测试它:

int i = MessageBoxA(NULL, "Hello World", "Injector", MB_OK);

printf("Works: %d\n", i);
printf("Works: %d\n", MessageBoxA(NULL, "Hello World", "Injector", MB_OK));

std::cout << "Works: " << i << std::endl;
std::cout << "Doesn't: " << MessageBoxA(NULL, "Hello World", "Injector", MB_OK) << std::endl;

printf("Hello World\n");

然后它在 std::cout << MessageBoxA(...) 之后崩溃。删除该行,一切正常!

注意它成功打印了32,它在到达下一条语句时崩溃了。

同样,只有在这种情况下它才不起作用,所以使用这个:

__declspec(noinline) int testFunction(int i)
{
    return i;
}

然后重新使用上面的代码并将 MessageBoxA 更改为 testFunction(以及参数),现在所有 4 个语句都有效!


最重要的是,对于在特定情况下导致崩溃的原因和原因,是否有人有任何想法?当其他情况完全正常时。

我认为问题在于您破坏了堆栈指针。尝试使用以下内容:

const DWORD instructionCount = 8;
BYTE instructions[instructionCount] = { 0xB8, 0x20, 0x00, 0x00, 0x00, 0xC2, 0x10, 0x0 };

正如 Peter Cordes 提到的那样,这会将 args 从堆栈中弹出。希望对您有所帮助。