本文提纲:
1. 当前GA(Gaminganywhere)开发完成以及正在进行的工作;
2. Windows Hook(钩子)在GA中的应用;
3. 关于Windows Hook(钩子);
4. Windows Hook(钩子)代码举例,完成线程钩子,监听QQ特定对话窗口并解析键盘操作,将键盘信息保存到文件中;
5. 程序运行截图;
一、当前GA(Gaminganywhere)开发完成以及正在进行的工作;
1) 以《极品飞车》为例生成支持x64游戏以及采用DirectX11方式启动方式的代码改造;
针对《极品飞车》游戏的d11方式启动已经修改完成,期间也碰到了很多问题,在这些问题的解决中对GA的局限性以及我们自己的能动性也有了较新的认识,首先:支持d11方式启动的游戏在底层的实现细节中不一定是按照GA代码中特定的传统方式,比如说先通过D3D11CreateDeviceAndSwapChain创建出Device以及Swap,然后再进行Present()等,在修改代码的过程中,思维一直局限在按它的路子应该是先hook D3D11CreateDeviceAndSwapChain然后再向下执行,因此在调试的过程中一直过不去,直到查看到一篇帖子:https://github.com/scen/stanleycen.com/blob/master/posts/directx11-hooking.md 上面提到:并不是所有的游戏都需要调用D3D11CreateDeviceAndSwapChain函数,其它的方式是通过CreateDXGIFactory或CreateDXGIFactory1来代替,当采用这种方式的时候还需要调用CreateSwapChain,从这里就可以获得SwapChain,然后就可以进行后续的工作,而不采用D3D11CreateDeviceAndSwapChain()函数的一个表现就是通过调用它获得的swapChain一直等于NULL,而且没有报错,看到这里的时候我就知道肯定是这个原因了,于是利用detour到CreateDXGIFactory1上来从而代码执行安装预想的方式进行了;
2) GA服务端构建守护进程,同时客户端配合修改以完成一个客户端连接过来,直接启动游戏、建立连接、并进行数据传送;
关于这一部分,GA服务器端的守护进程已经成功创建,监听客户端建立连接的请求,原本GA的运行机制是运行服务器端将游戏启动起来后,客户端再连接过来获取视频流,我们改造后是GA守护进程启动,客户端请求的连接中跟随游戏的名称,即需要启动哪些游戏,服务器端与客户端进行一次socket通信获取到客户端需要启动什么程序,然后将该socket保存下来,在利用rtsp发送数据的时候就可以针对不同的客户端启动不同的应用,然后待应用程序启动后再进行一次通信通知客户端进程继续向下执行,这种解决方式应该会对并发连接的session上有较好的支持,这部分已经完成了一半,对我们的设想还没有测试。
二、Windows Hook(钩子)在GA中的应用:
Windows钩子的应用在GA的理解中起着很重要的作用,这是基于窗体捕捉的核心,在游戏启动之前它会挂上全局的钩子,当窗口启动就会调用钩子的回调函数,完成一系列的视频捕捉以及数据包的发送。由于是全局钩子,因此所有窗口的启动它都可以捕捉到,那我们如何区分哪个是我们真正需要捕捉的呢?在GA中如果是正常启动的游戏在进入挂钩之前都会写环境变量,在正式捕捉前会判断该环境变量的值是否存在,如果存在则说明是我们启动的游戏,如果没有则说明它是无关的窗口,直接detach掉就可以了。
三、关于Windows Hook(钩子);