检测用户何时对我的程序截屏

8
我正在编写一个Windows应用程序。如何知道有人在对它进行屏幕截图?我已经了解到如何检测热键被按下的情况,但我更担心的是每隔100毫秒左右另一个程序会对其进行截屏的情况。换句话说,我想注意到当有人创建另一个程序(比如使用ImageGrab的Python程序,正如在另一篇帖子中提到的那样)时,该程序会不断地对我的应用程序进行截屏,并使用这些截屏来读取信息。
我并不太关心如何防止截屏-一旦发现这种行为,我可以禁止用户。这种情况是否可能发生?是否有Windows消息在任何应用程序进行截屏时发送,就像WM_HOTKEY一样?或者Windows只是直接返回最新的画布信息给其他程序,而我的应用程序根本无法注意到?

你想禁止那些截取你的应用程序截图的人吗? - jjnguy
4
我非常好奇为什么您想要检测截屏(并采取如此激进的行动)。我可以告诉您检测到按键是可能的,但是执行该操作是不可能的。有许多程序以许多不同的方式进行截屏。那么录屏呢?您也会阻止吗? - Jake
1
@David:由同一人发布。 - Adam Jaskiewicz
2
你能告诉我们为什么需要这样做吗?还可以稍微介绍一下这个“害羞”的应用程序使用的环境吗?也许我们可以想出其他解决方案来解决你的问题... - Tarnay Kálmán
请参考以下问题:https://dev59.com/TnI-5IYBdhLWcg3wkJMA (该问题是关于视频的,但对于图片来说问题是一样的) - Piskvor left the building
显示剩余6条评论
10个回答

31
无论你做什么,人们总会想出方法绕过它。假设有这样一种方法,可以可靠地检测到另一个程序正在截取您的应用程序的屏幕截图。为了规避此问题,我可以安装VirtualBox,在其中运行您的应用程序,然后使用程序截取VirtualBox(包含您的应用程序)的屏幕截图。您的应用程序将完全无法知道它的屏幕截图正在被拍摄。

除非VirtualBox模拟Windows截图的方式完全一样,根据你的回答,你是在说它不会这样做? - Claudiu
1
我不是在谈论VirtualBox如何截图;我是在谈论另一个程序如何截取VirtualBox的屏幕截图。毕竟,VirtualBox基本上只是一个带有一些像素的窗口。 - Greg Hewgill
这是我的意思。在我的脑海中,当调用“takeScreenshot()”时,会调用某个特定的函数。该函数将递归地调用所有打开窗口的“takeScreenshot()”(因此桌面将在所有具有打开窗口的程序上调用它)。VirtualBox可以定义其“takeScreenshot()”处理程序以模拟在其模拟的所有应用程序上调用此“takeScreenshot()”。我不确定这是否完全正确,这就是为什么我在这里询问的原因。 - Claudiu
4
是的,完全不是这样运作的。截屏包括打开一个 DC(设备上下文)到相关窗口,并使用 BitBlt 读取屏幕上的位。截屏不涉及 WM_PAINT 或任何类似的东西。Win32 应用程序将不知道像素复制过程正在进行。你可能能够阻止打印屏幕快捷键完成其工作,但你无法检测另一个应用程序简单地从屏幕上读取位。 - Greg Hewgill
2
@Claudiu:实际上,如果您有一个正在运行(但未聚焦)的Virtualbox窗口,并且按下PrintScreen键,则不会传递任何内容到虚拟计算机。没有Printscreen键,没有消息,什么都没有。已测试并验证。 - Piskvor left the building
显示剩余2条评论

7
如果我使用视频摄像机呢?如果我捕捉计算机和显示器之间传输的视频呢?
我很惊讶地发现没有实用的方法可以做到这一点。

13
我还在努力开发仿冒许可证加密狗的仿生手臂原型!如果用户试图使用视频摄像机或相机,它会突然攻击并扼杀用户。 - dr. evil

7

这永远行不通。而且,试图提供这种安全级别会让99%的合法用户受到不便。

也许你最好从识别信息的非法使用/复制的角度来解决问题,并与使用该信息的人/公司接触。

版权法对于这种方法是适用的,但我理解有些情况下这种方法是无效的。


6
您可以使用SetWindowsHookEx来进行此操作(但不可靠)。

这里有一个完整的VB.NET示例。

然而,这种方法存在许多变通方法。在您之后安装的钩子将“覆盖”您的钩子。用户可以通过本帖中描述的多种方式拍摄屏幕截图。我建议您考虑其他保护选项。


3
首先,关于使用虚拟机的评论完全没有意义——检测运行在虚拟机下的Windows比检测截图更容易。
使截图变得困难的一个好方法是将程序重写以在某个祖传的DOS扩展器下全屏运行。
禁止95%曾尝试过截图的用户的好方法是在启动时显示一个巨大的闪烁横幅(“禁止截屏!你将被禁止!”),并在接下来的15秒内检测用户是否按下PrtScrn键。

最后一段哈哈。 - Claudiu
“更容易检测到在虚拟机下运行的Windows” - 是啊,我在Linux上运行我的合法许可的WinXP虚拟机,你的意思是什么? - Piskvor left the building

2

完全阻止这种情况是相当困难的......一个决心坚定的用户可以使用数码相机拍摄屏幕。


2

我认为这个目标不可能实现的另一个原因是:

很久以前,我曾试图截取Windows Media Player的内容,但失败了,因为(我认为)WMP会立即将内容流传输到显卡上。(有趣的细节:在将截屏粘贴到MS Paint后,视频仍然会继续播放,但保存图像最终会产生一个黑色正方形)。无论如何,使用VNC后,获取截屏变得非常容易。


3
我认为媒体播放器并不是为了防止截屏而这样做,那只是一个副作用。任何这样的覆盖层都无法正常地被捕获。但是,如果你关闭硬件加速,它就不会使用覆盖层,然后你就可以对其进行截屏。 - Jordan Miner
实际上,我也认为这是一个副作用。(尽管微软可能希望停止对DRM受保护内容的屏幕录制。) - Arjan

1
我通常从C#中调用BitBlt来截屏,这是许多屏幕绘制的基础。不确定如何以有意义的方式拦截对它的调用,因为可能系统上的每个程序都在低级别上使用它。

我曾经在第一人称射击作弊程序中看到过一个概念验证代码,它会冻结屏幕截图线程,直到作弊 HUD 被禁用。我认为它钩取了 BitBlt 或类似的东西。 - John Smith

1

我猜你可能做不到,因为人们总是可以在虚拟机中运行你的程序,然后在外部平台上使用截图程序,而要知道这是否正在发生是非常困难的。我建议更多地考虑特殊渲染速度或交错、特殊对比度等方面......

你还可以将输出运行到屏幕上,就像是一部电影,使用低速率和分辨率编码器进行编码,以便每 100 毫秒进行一次静态捕获,并且质量如此之低,以至于毫无价值。(你曾经尝试过冻结低质量的电影吗?)

然而,你真的应该考虑使用其他方法来保护你的信息。


-1

我认为有一种方法可以阻止这种情况发生。学习一下当图形显示被复制时会模糊的技术,比如:

屏幕截图, 用数码相机拍摄的照片 虚拟操作系统中的屏幕截图。

试着去尝试它,说不定你会发明出一些能让你赚上百万的东西。


“当图形显示被复制时,会模糊显示” - 这是科幻,而不是实际技术。在从程序通过操作系统到硬件之前,成为显示图像的位被复制并进行了大量修改。真正的问题在于解密意图,这对于人类来说已经很难了,更不用说计算机指令了。 - Piskvor left the building

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接