windows截屏录屏 (D3d) 游戏黑屏 解决思路

先随手记下来,以后补代码,整排版


最近忽然想折腾点游戏辅助(w a i g u a。。)自己玩玩

最简单直接的思路就是获得游戏画面,然后判断,然后干一些事情了。

可是搜出来的几个windows截屏方法,都对游戏不起作用,截出来对应区域是黑屏。


总结一下几个常见方法吧:


 (1) python调库。。哈哈哈哈。不过我没见到过能截到游戏的库。

我试的几个, Pillow,pyautogui。。。python的确舒服,这些库用起来都贼舒服。就是截不到游戏呀。。。

 

(2) 按键盘的PrintScreen,读剪切板内容。

PrintScreen不知道什么个原理。没见过PrintScreen截不到的图。。。

这个PrintScreen背后到底搞了什么还没查到

TODO!!!

但是就我感觉来看,效率有点低呐。

我这个破电脑,本来玩守望先锋都卡。fps烧高香了才能勉强五十多。按一次PrintScreen卡半天。我外接个手机给屏幕照相感觉都比这快。。


 (3) windows的GDI系列。windows普通窗口都是走GDI这条路的。这也是最常见的截图方法。

先GetWindowDC,再把内容BitBlt到我们创建的bitmap里。

或者用PrintScreen。详见msdn吧。

和BitBlt的主要区别在于 PrintScreen是主动要求把窗口画一遍给我们,所以就算窗口在屏幕边界外面,或者窗口被遮挡了,或者最小化了。都能截到。


 (4)D3D,自己创建一波设备什么的,然后把off-screen buffer读出来。这个我没试,嫌麻烦。看别人的回馈,对游戏也没用。

貌似是因为游戏一般都把buffer存到overlay了还是什么。导致off-screen里面没有游戏的真正像素,只有个占位置的黑块?

(。。本人才疏学浅,只知道最普通的D3D流水线,没见过这么多黑科技。。。说错了麻烦告知)


 (5) 微软给了个windows media套件,里面有截图功能。这个也没试


 (6) 听说可以自己伪造一个驱动。。。没找到。


 (7) 听说还有个https://msdn.microsoft.com/en-us/library/windows/desktop/hh404487(v=VS.85).aspx

这个也能截图,也没试。


反正我估计都不行。

这就奇怪了,直播平台都能录屏。见过有些外挂也能。PrintScreen也可以。

说明肯定有办法的。


不过搞外挂的一般都不分享他们的核心技术。。。毕竟人家靠这个吃饭,说出来,不说教会了徒弟饿死了师父。万一被游戏公司看见了,给这种方法封了就尴尬了。

各种外挂论坛也鱼龙混杂。pass掉。


然后我去试了试录屏软件。果然,几乎都录不到,大多数底层估计都是上面那些方法。但是!的确有几款可以录到。

在这个过程中也发现了,游戏截屏应该是一种特殊的技术。能截到游戏的软件,一般都是把截游戏归为单独的一类,和普通的窗口截屏不一样。

我发现的几个可以截图或者录屏游戏的软件:

EV录屏(不开源)

D3Dgear(不开源)

OBS(开源,注意有协议)

还有个ZD software screen recorder,在以管理员模式运行情况下,能录到。但是不管怎样都截不到。

这个ZD software有偿提供SDK。


我甚至还专门整了波 大名鼎鼎的大漠插件,里面有封装好的专门处理Dx游戏的函数。可是似乎也不行。。。(有些别的游戏,上面普通方法处理不了的,但是大漠可以处理。就是OW不行,不知道为什么。是大漠不更新了,没支持到D3D11?)


EV录屏不知道什么原理,我怀疑它是狂截图模式。。。对游戏没做特殊处理。

D3Dgear,需要让它启动游戏,然后就可以了,随心所欲。注意到它会在正常游戏窗口上附加自己的东西,这个我觉得应该是一种dll注入吧。那种在程序入口之前就把东西折腾好的dll注入。然后再让程序开始。它应该把d3d的某些函数hook了,然后加入一些自己的逻辑。

OBS,开源项目。实际上我把知名开源录屏截屏项目几乎都试了试。只有OBS可以。

然后狠狠看了一波OBS源码。。这个项目这个大呀。。不过这个项目的确NB。

中间如何看代码如何艰难就不说了。


最后OBS获得游戏窗口画面的方式如下:

判断游戏用的哪个版本的d3d,然后找,该版本的d3dxx.dll里面的关键函数在哪里。比如说d3d11,就去找present。

知道了函数偏移量,然后自己写一个dll,把这个dll注入到游戏里执行。该dll去把d3d11.dll的present函数给换成另一个函数。(因为知道函数位置了,直接在该函数处搞一个jump,这样每次调用present,都会调到我们的函数那里)。

present的一个参数是DXGISwapChain,这个就是切入点。换了函数以后,我们的函数从参数得到了DXGISwapChain,然后就可以一步一步把游戏用的d3d device什么的都搞出来了。当然这里没必要那么麻烦,从swapchain把screen buffer搞出来,这就是游戏窗口的画面了。然后弄一个跨进程线程通信,把这个东西传回去就行了。OBS用的是共享内存区好像是。


这种方式其实感觉很类似外挂了,应该是反作弊系统的重点追查对象。。但是目前也没发现什么别的思路。开源项目里面只有OBS可以,其他的也没人分享。


最后,感谢一下OBS项目。

https://github.com/jp9000/obs-studio

有事没事去给OBS个star,支持支持




-----------

有价值的几个网页

https://github.com/jp9000/obs-studio

https://blogs.msdn.microsoft.com/dsui_team/2013/03/25/ways-to-capture-the-screen/

http://www.zdsoft.com/screen-recorder-sdk/cn/

https://msdn.microsoft.com/en-us/library/windows/desktop/hh404487(v=VS.85).aspx

你可能感兴趣的:(windows截屏录屏 (D3d) 游戏黑屏 解决思路)