如何在C#中检测Windows Server 2008上的防病毒软件?

19

在我寻找答案的过程中,我曾经看到过很多类似以下代码示例的内容:

using System;
using System.Text;
using System.Management;

namespace ConsoleApplication1
{
  class Program
  {
    public static bool AntivirusInstalled()
    {

      string wmipathstr = @"\\" + Environment.MachineName + @"\root\SecurityCenter";
      try
      {
        ManagementObjectSearcher searcher = new ManagementObjectSearcher(wmipathstr, "SELECT * FROM AntivirusProduct");
        ManagementObjectCollection instances = searcher.Get();
        return instances.Count > 0;
      }

      catch (Exception e)
      {
        Console.WriteLine(e.Message);
      }

      return false;
    } 

    public static void Main(string[] args)
    {
      bool returnCode = AntivirusInstalled();
      Console.WriteLine("Antivirus Installed " + returnCode.ToString());
      Console.WriteLine();
      Console.Read();
    }

  }
}

很遗憾,似乎Windows Server 2008没有SecurityCenterSecurityCenter2命名空间,因此我尝试该方法时会发生Invalid namespace异常。

有人知道如何确定Windows Server 2008是否正在运行防病毒软件吗?任何帮助将不胜感激!


15
不相关,但请养成使用return instances.Any();而不是Count > 0的习惯-如果instances是一个非常长的列表,仅仅为了查看成员是否大于零而计算所有成员是一个不好的主意 :) - carlpett
5
@Amitd,这仅适用于客户端/桌面操作系统。在Server 2003/2008上不存在SecurityCenter命名空间。 - wjhguitarman
8
只有当你使用Count()来枚举不是集合的IEnumerable对象时,才会出现这种情况。在集合中使用Count仅访问成员变量,是一个O(1)的操作。 - Hylaean
1
你是否可以访问服务器并打开SecurityCenter?它在2008中已经包含,但默认情况下未启用。请参阅此帖子http://social.msdn.microsoft.com/Forums/en/winserver2008appcompatabilityandcertification/thread/05f2b096-0e12-4429-9e4a-cd526b3b437c。 - Sorceri
4
您可以使用 Process.GetProcesses() 获取正在运行的进程列表,并循环遍历该列表,为您想要查找的每个防病毒产品创建过滤器。 - Nick Bray
显示剩余8条评论
5个回答

6

使用EICAR测试病毒。

  1. 让您的应用程序尝试在磁盘上写入以下文件之一:http://www.eicar.org/85-0-Download.html
  2. 捕获异常

它不仅可以在地球上的每个杀毒软件上运行,还可以告诉您杀毒软件是否处于活动状态!

如果您的杀毒软件处于活动状态,您可能会发现很难下载测试文件,因此您可以改用此字符串:

X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*

请记住,在将字符串写入磁盘之前,您可能希望在应用程序中保留其编码并在必要时进行解码。否则,您的应用程序可能会被检测为病毒 :) 在EICAR网站上,他们说:任何支持EICAR测试文件的防病毒产品都应该能够检测到以以下68个字符开头并且正好为68个字节长的任何文件中的文件。 但是,我不指望AV开发人员已经读过规范,因此最好仍然将字符串编码。事实上,我尝试将带有一些其他字符的字符串保存在桌面上的.txt文件中,Windows Defender开始大声叫喊。

1
运行测试文件后,我如何确切地知道防病毒软件是否处于活动状态? - athom
你不运行测试文件,就无法保存文件。防病毒软件会阻止你这样做。因此,如果你尝试在磁盘上写入一个包含上述字符串的文本文件,你应该会得到一个异常。为了双重检查,你可以尝试读取文件。它不应该存在,因为防病毒软件已经检测并删除了它。如果没有删除,最好检查一下防病毒软件是否正常工作。 - Jani Hyytiäinen
我将上述字符串复制到一个文本文件中并成功保存了。因此,Symantec终端保护要么无法处理该字符串,要么不是全包括的。 - wjhguitarman
SEP 应该处理那个字符串。请参见此处:http://www.symantec.com/business/support/index?page=content&id=TECH130969 - Jani Hyytiäinen
1
我认为这种方法并不适合我的特定情况。我检查反病毒软件的目的是因为我们的软件有时与防火墙/反病毒软件不兼容,所以可能将我们的应用程序标记为反病毒软件并不是正确的方法。感谢提供有用信息的人! - athom

3

嗯,我最终玩起了PowerShell:

$avSoftware = get-wmiobject -class "Win32_Product" -namespace "root\cimv2" -computername "." -filter "Name like '%antivirus%'"
if ($avSoftware.Count -gt 0) {
    foreach ($av in $avSoftware) {
        write-host $p.Name
    }
} else {
    write-host "No AV software found"
}

看起来它可以在我们的Windows Server 2008和2008 R2实例上正常工作...

更多信息请参见:https://serverfault.com/questions/12343/how-can-i-determine-whether-an-antivirus-product-is-installed


我的计算机上当前安装的 McAfee 版本显示为“McAfee VirusScan Enterprise”,因此 -filter "Name like '%virus%'" 可能匹配更多情况。 - Luke Quinane

2

我曾经为一位客户面对这个问题,最终在本地系统驱动程序和进程上执行了一个字典搜索,寻找已知的反病毒签名模式(例如文件夹名称、进程名称等)。虽然不能百分之百确定,因为总有人会下载你不知道的全新反病毒软件,但除此之外,它非常有效...


我真的希望有一个更简单的答案,但现在听起来这可能是实现我想做的事情的唯一方法... - athom
我知道这听起来很繁琐和“愚蠢”,但我真的花了一些时间来思考这个问题(好吧,也许我有点傻)。 - Leonardo
我并不是特指你的具体操作方式,而是指编制一个检查防病毒产品清单的一般想法。尤其是因为相比于编制一个要检查的防病毒软件清单所需付出的努力,我的检查防病毒软件的原因似乎有点微不足道哈哈。 - athom
这是一种许多病毒、木马和蠕虫执行的工作,以便规避特定的反病毒扫描器。这可能看起来有点奇怪,但从另一个角度寻找编写此类恶意代码的来源可能会有所帮助。深入探索互联网的“黑暗角落”,那里“病毒作者”聚集... - s-m-e
@Leonardo 我可能会尝试几种不同的方法,但目前我正在考虑使用C#来实现这个方法。 - athom

1
这更像是一个想法而不是完美的解决方案。关于Leonardo的答案,如何使用实际的反病毒软件(链接)来搜索其他反病毒软件?ClamAV是开源的,是一个不错的起点。您只需要定义一个新的、相当特定的签名数据库即可。

0

根据大多数网站的说法,SecurityCenter和SecurityCenter2在Windows Server 2008上不可用(正如您自己已经发现的那样)。

我找到了这篇SO文章,其中包含一个解决方法。 如何检测安装在Windows 2003服务器和2008服务器2003服务器R2和2008服务器R2上的杀毒软件,使用WMI或其他C++实现

诚然,这是一个C++实现,但我认为它可以移植到C#。

还发现了这个页面,建议使用OESIS框架。 http://social.msdn.microsoft.com/Forums/en/windowsgeneraldevelopmentissues/thread/b0806608-fee0-413c-a34d-674aeb11be3c


3
Technet 上指出,你所链接的 C++ 实现在 Windows Server 2008 上是不可用的……根据 MSDN 的说明,所使用的 API 仅适用于“桌面应用程序”! - Yahia
链接中的答案/评论也指出它在服务器操作系统环境下不起作用。 - wjhguitarman

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