在开发检查软件时,我有一个要求防止通过TeamViewer,AnyDesk,Ammyy Admin等应用程序进行桌面共享,或者至少阻止对其进行检测。我们的考试软件是用C#开发的,它是一种winform逐一呈现问题。
我不认为检测如此简单,因为它们有多种捕获屏幕桌面复制API,BitBlt,Direct3D,DirectX,DirectShow等方法。
因此,我开始探索如何防止启动桌面共享时显示我的c#winform。为此,到目前为止,我已经尝试了以下操作:
SetWindowDisplayAffinity
设置为WDA_MONITOR
以对Winform进行保护。通过在我开始桌面共享时执行此操作,远程控制的计算机可以看到表单上的黑色层。但是,并非所有桌面共享应用程序都具有相同的行为。就像TeamViewer的行为一样,但Ammyy Admin和AnyDesk的行为一样。 某些应用程序如何显示黑层而有些却不显示?我还能做些什么吗? if (winForm != null)
{
if (Protect)
result = SetWindowDisplayAffinity(winForm.Handle, WDA_MONITOR);
else
result = SetWindowDisplayAffinity(winForm.Handle, WDA_NONE);
}
我编码的这种方法不能完全证明所有桌面共享应用程序的正确性,那么有没有100%的解决方案来防止/检测桌面共享?
如果您尝试了VLC播放器的“ DirectX(DirectDraw)视频输出”,则此输出方法也具有与SetWindowDisplayAffinity
相同的功能,当启动任何桌面共享应用程序时,它将在视频上显示黑色层测试了它是否可以与将近9种桌面共享应用程序一起使用,知道如何完成吗?可以用c#winform完成吗?
更新29-05-2019
检查VLC代码后,我知道它们正在使用DirectDraw进行硬件叠加。因此,我创建了vc ++项目并使用d3d9并创建了具有红色表面的覆盖,现在,如果我将机器移开,则红色的表单将显示黑色。答对了!!解决了一半问题。
现在,我正在尝试为该窗口设置透明度,以便叠加层将显示在我的C#应用程序的顶部,并且考生可以进行考试,如果采取远程操作,则叠加层将以黑色显示。为了使窗口透明,我使用了DwmExtendFrameIntoClientArea
winapi,但是现在在远程也可以看到透明的窗口。有什么办法吗?
答案 0 :(得分:2)
我想将此添加为答案,因为很多讨论是在moved to chat的注释中进行的,因此我想对其进行总结,以便即将来临的观众获得有关讨论和解决方案的想法我结束了。
首先,我想澄清一下VLC的“ DirectX(DirectDraw)视频输出”如何工作? VLC的这种特殊输出模式使用DirectDraw创建硬件覆盖并在其上播放视频。屏幕捕获(不是从移动或外部相机捕获)时,大多数捕获机制都是通过向屏幕请求GDI来捕获屏幕的,但是硬件叠加层直接呈现在GPU上,GDI无法访问GPU。就像GDI-> CPU + RAM,DirectX-> GPU + VRAM一样,这就是为什么在屏幕捕获中VLC的视频播放部分显示为黑色。有关更多信息,https://stackoverflow.com/a/21535254/1629242
但是作为RomanR。聊天中提到“使用视频叠加层不会帮助隐藏应用的用户界面”。
我也确认相同,正如我在更新中提到的那样,我创建了一个vc ++项目,如果我在其上播放视频,则使用D3D9创建硬件覆盖,然后在屏幕录制中显示黑色区域,但是我找不到任何方法该叠加层是透明的,以便可以将其放在我的应用程序上或将应用程序内容放在叠加层上,以便在录制屏幕时不会显示应用程序内容。
Riddel提出了一个新的想法:“防病毒的工作方式以及在所有过程中进行迭代的方式以及哈希检查常用的屏幕共享工具”,但是我个人认为这不是通用解决方案,因为我必须维护此类应用程序的列表并且是哈希,如果找到任何新的应用程序,则更新该列表。同样,任何人都可以编辑字节来破坏散列,从而使此错误。
我接受的解决方案:
Windows API提供了有助于仅在监视器上显示窗口内容的功能。即SetWindowDisplayAffinity
,这就像魅力一样!!
最低支持的操作系统问题:
尽管MSDN文档提到“最低支持的客户端:: Windows 7”,但是在Windows 7上,它不适用于所有屏幕捕获应用程序。罗曼·R。在评论中说:“这将从Windows 8(可能还有Windows 7的Platform Update)开始正常工作。在纯Windows 7上,您将获得免费的桌面共享,并且无法保护您的内容。”
因此,目前,SetWindowDisplayAffinity
我已经完成了,实现为:
private const uint WDA_NONE = 0x0;
private const uint WDA_MONITOR = 0x1;
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern bool SetWindowDisplayAffinity(IntPtr hWnd, uint dwAffinity);
public static bool SetDRM(Form winForm, bool Protect)
{
bool result = false;
if (winForm != null)
{
if (Protect)
result = SetWindowDisplayAffinity(winForm.Handle, WDA_MONITOR);
else
result = SetWindowDisplayAffinity(winForm.Handle, WDA_NONE);
}
return result;
}