繁体   English   中英

使用DirectX防止屏幕捕获

[英]Prevent screen capturing with DirectX

我想使用DirectX渲染单个图像。 它应该类似于VLC播放器的“directx视频输出”,如果不能使用简单的屏幕捕获软件或printscreen-key捕获帧。 制作屏幕截图不可能(或非常困难)!

有谁知道这在VLC播放器中是如何工作的?

还有其他可能的解决方案吗? 也许使用“输出保护管理器”(参见http://msdn.microsoft.com/en-us/library/dd388980(VS.85).aspx

我在学校大约有3年的C#编程经验。 我也做了一些C ++编程,但是我会使用WPF或Managed DirectX来提供C#解决方案。

对不起我的英文,感谢您的帮助!

首先,当您使用打印屏幕或其他屏幕捕获技术时,未捕获VLC内容的原因是(至少在旧版本的Windows上),他们使用“叠加”来呈现视频。 这是一种特殊的GPU结构,允许渲染到正常屏幕表面上方的虚拟“平面”。 由于这绕过了其他所有内容并直接进入GPU,因此没有任何直接的方法来捕获它。 注意:在Windows的最后几个版本中,规则改变了很多关于叠加的内容。 应用程序不能假设支持D3D9 / DDraw覆盖,现在应用程序不应使用它们,因为系统具有更好的方法来呈现具有相同高性能的内容。

Direct3D 9叠加

如果您使用Direct3D 9显示视频内容,您也可以使用叠加层。 有关如何执行此操作的信息,请参阅MSDN上的此页面 D3D9覆盖的使用存在很多限制,很多硬件都不支持它们,因此我将介绍其他一些方法。

此技术不会阻止其他应用将其注入您的地址空间并捕获您的礼物。 此外,由于某些硬件不支持它,而某些捕获API实际上禁用了覆盖,因此它不能提供非常强大的保护保证。

基于GPU的内容保护

如果您有足够的时间来了解GPU内容保护,并且您知道您将显示非标准受DRM保护的视频格式,则可以使用GPU内容保护来滚动自己的受保护媒体路径。 我不是这方面的专家,而且很少有人。 我不推荐这个,但我想指出来。 MSDN上的这个页面讨论了如何在Direct3D 9中实现它, 另一个页面讨论了如何使用Direct3D 11实现它。

由于密钥交换几乎完全通过硬件(例如HDCP)发生,因此该技术提供了未捕获内容的强有力保证。

媒体基金会受保护的媒体路径(PMP)

如果使用支持良好的基于​​DRM的媒体格式显示视频,则可以使用Media Foundation的受保护媒体路径,该路径利用前面介绍的基于GPU的内容保护。 它还将大多数功能封装在一个单独的受保护进程中,而其他应用程序无法拦截或以其他方式与之交互。 如果有人试图安装测试签名的驱动程序或以其他方式注入未受信任的根权限进行代码签名的二进制文件,Windows将不允许解密内容并且您的内容将保持安全。 该技术提供了未捕获内容的有力保证。 Netflix在Windows,Blueray播放器和其他播放器上使用它。

DXGI交换链标志

假设您使用Direct3D 10.x / 11.x呈现内容(现在希望与2014年的D3D 9相反),您可以在交换链上使用多个标记来锁定内容。

如果系统没有HDCP或类似HDCP的输出保护,您可以在交换链标志中传递DXGI_SWAP_CHAIN_FLAG_RESTRICTED_CONTENT以使交换链失败。 这可能不是您的目的所必需的,但如果您担心人们捕获HDMI或模拟输出,那么这是很好的。

您绝对需要的标志称为DXGI_SWAP_CHAIN_FLAG_DISPLAY_ONLY 这可以防止所有屏幕捕获API看到您的交换链。 它只会显示为黑色矩形。

有关所有DXGI交换链标志,请参阅此页面

这种技术不能提供基于GPU的内容保护提供的强有力保证,但如果您非常确信其他应用程序没有做出疯狂的事情,例如将自己注入地址空间并挂钩当前的呼叫,那么您可以放心这可以防止其他人看到您的内容(当然除了显示器)。

全窗保护

有时您可能想要保护的不仅仅是DXGI呈现的内容。 在这种情况下,您实际上可以使用类似的机制来简单地保护整个窗口不被各种屏幕捕获技术捕获。 这是一个名为SetWindowDisplayAffinity的API。 它在强度和功能上等同于为交换链传递DXGI_SWAP_CHAIN_FLAG_DISPLAY_ONLY标志,但它也保护了使用GDI,旧版DirectX技术等提供的内容。传递WDA_MONITOR标志以启用对给定HWND的保护,或传递WDA_NONE以禁用保护。

为了完全披露,我在Microsoft工作的团队处理显示逻辑,包括某些形式的屏幕捕获和内容保护。

也许通过它的声音,您需要通过挂钩到全局Windows过程来拦截WM_PRINTCLIENT ,如果使用WM_PRINTCLIENT消息,只需从钩子窗口过程返回。 有关WM_PRINTCLIENT的详细信息,请参阅此处。 这样做的另一种方法是拦截剪贴板功能,其中的数据是从特定应用程序和剪贴板中包含一个位图。请参见拉里·奥斯特曼的关于博客这个 这是一篇关于实现全局Windows钩子的CodeProject的文章,我可以在这里这里提供另外两个链接。 (全部在CodeProject上)

希望这会有所帮助,最好的问候,汤姆。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM