拦截并取消DirectX游戏的按键事件

时间:2014-02-25 09:36:57

标签: c# c++ directx keystroke

我正在为DirectX游戏开发一个小工具,我希望阻止用户在某段时间内按某个键(在这种情况下为F12)。

我可以找到许多用于模拟按键的选项,但是在游戏读取之前将键击归零会有什么选择?

这种语言并不重要,虽然我更喜欢C#或C ++解决方案,或只是朝着正确的方向推进:)

提前致谢!

1 个答案:

答案 0 :(得分:2)

好消息是,我之前已经这样做过,所以我可以说这是可能的,而且确实有效。

坏消息是,这并不简单。它需要很多复杂的代码,可能需要很长时间才能实现,但我会解释你是如何做到的。

DirectX游戏等应用程序通常为register for raw input。 由于您想要阻止键盘事件到达应用程序,您需要一种方法在原始输入和游戏之间插入代码,以便您可以检查原始输入并决定是否允许它传递给游戏:

所以你想改变以下的流程:

Raw Input --> Game

Raw Input --> Your Code --> Game

无法访问游戏的源代码,您必须找到插入代码的方法。

当有可用的键盘输入时,游戏将调用WinAPI函数GetRawInputData,它将告诉它键盘事件。理想情况下,我们想要的是当游戏调用此函数时,它实际上调用我们的代码而不是WinAPI函数。然后我们可以决定告诉游戏关于键盘事件的内容,我们可以告诉它我们想要什么(例如忽略F12)。听起来不错吧?这是有趣的地方......

我们可以利用windows如何将可执行文件加载到内存中。通常,程序使用(或“导入”)对其他DLL(例如User32.dll中的GetRawInputData)中的函数的调用。当程序加载到内存中时,Windows将填入一个表(导入地址表(IAT)),其中包含指向相应DLL中可执行代码的指针。这意味着当程序调用该函数时,它会被定向到内存中User32.dll中的可执行代码以运行它。

如果我们可以将其中一个函数的地址写入/修补到该表中,那会不会很好,所以当游戏调用GetRawInputData时,它实际上会被定向到我们的函数供我们处理?好吧,我们可以!它被称为导入地址表修补。

在C ++中有一些很好的article on it here和一些工作代码。您应该首先阅读它以更详细地了解它是如何工作的,然后您可以对其进行修改以满足您的需求。它会起作用,但我知道它可能比你希望的更多的工作(更多的工作),但实质上你是在破解那些从来不容易做的应用程序。

值得做的,甚至只是为了在幕后更好地了解Windows。

祝你好运!

修改

正如西蒙所说,如果游戏不使用原始输入,Windows Hooks是一种更简单的方法。 DirectX Games往往是一个特殊的案例,它与标准的Hook并不是很好用,因为它们使用特殊的方法来获取用户的输入。一定要试一试,如果有效的话会更容易。