可选稳定性修复¶
本章描述的 Reset() 和 EndScene() 钩子应该适用于任何运行 Direct3D 9 的游戏,但稍微不稳定。如果游戏在跳转钩子放置时尝试执行 EndScene(),它会因为字节正在被修改而崩溃。有两种方法可以修复。首先,你可以从 PeekMessage() 上的 IAT 钩子内部放置跳转钩子。这会有效,因为放置 IAT 钩子是线程安全操作,但它假设 PeekMessage() 只从进行 Direct3D 绘制的同一个线程调用。
更安全但更复杂的替代方案是遍历游戏中的每个线程(类似于线程劫持的方式),用 SuspendThread() 暂停游戏中的所有线程(当然,放置钩子的线程除外)。暂停线程前,你必须确保它的 EIP 没有在执行 EndScene() 的前 5 个字节。放置钩子后你必须用 ResumeThread() 恢复执行,让钩子生效。