2014-02-25 123 views
0

我正在开发DirectX游戏的小工具,并且我想阻止用户在某段时间内按某个键(本例中为F12)。拦截并取消DirectX游戏的按键事件

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

语言并不重要,但我宁愿一个C#或C++的解决方案,或只是轻推在正确的方向:)

提前感谢!

+0

DirectX游戏是你的,还是第三方(即你有源代码)?另外,你在使用什么操作系统? – parrowdice

+0

@parrowdice没有游戏不是我的,我没有源代码。它是第三方游戏。我在Windows上。 – Nadeeja

+0

你可能想看看[Window's Hooks API](http://msdn.microsoft.com/en-us/library/windows/desktop/ms632589(v = vs.85).aspx)。这将允许您在系统到达目标窗口之前拦截系统中的消息。 –

回答

2

好消息是,我之前做过这件事,所以我可以说这是可能的,它确实有效。

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

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

所以,你想从改变流量:

Raw Input --> Game

Raw Input --> Your Code --> Game

而不必访问至t他是游戏的源代码,你必须找到一种方法来插入你的代码。

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

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

如果我们可以将我们的某个函数的地址写入/修补到该表中,那么当游戏调用GetRawInputData时,它会不会很棒?我们可以!它被称为导入地址表修补。

有一个相当不错的article on it here在C++中的一些工作代码。你应该首先阅读它来更详细地了解它是如何工作的,然后你可以修改它以支持你的需求。它会工作,但我知道它可能比你所期望的更多的工作(更多的工作),但基本上你正在窃取这个从不容易做到的应用程序。

值得去做,即使只是为了更好地了解幕后的Windows。

祝你好运!

编辑

正如西蒙说,windows钩子是一个更简单的,如果游戏没有使用原始输入做方式。 DirectX游戏通常是一种特殊情况,对于标准Hooks来说,它们并不能很好地工作,因为它们使用特殊方法从用户那里获得输入。尽管如此,尽管如此,如果它有效,它会变得更容易。

+0

谢谢你的详细答案!你让我对Windows的低级感兴趣。 IAT补丁例如听起来很棒。我会按照你的建议给Hooks一个尝试,然而即使Hooks完成了工作,我也会试着实施你的方法。这将是一个非常好的学习练习。再次感谢:D – Nadeeja