在Windows上最安全的单一运行的应用程序防护

我想改进应用程序如何检查另一个实例尚未运行的方式。 现在我们使用命名的互斥体来检查正在运行的进程。

目标是防止安全攻击(因为这是安全软件)。 我现在的想法是,“防弹”解决scheme只是写一个驱动程序,它将提供这种信息,并通过签名的二进制文件validation客户端。

有没有人解决这个问题? 你有什么意见和build议?

首先,让我说,最终没有办法保护你的进程有管理员或系统访问的代理。 即使你编写了拦截所有系统调用的rootkit驱动程序(本身是一个困难和不安全的做法),仍然有办法使用管理员访问权限进行访问。如果这是必需的,那么设计错误。

如果将安全进程设置为作为服务运行,则可以使用服务控制管理器启动它。 SCM将只启动一个实例,监视它保持运行状态,允许您定义要执行的动作(如果它崩溃),并允许您查询当前状态。 由于这是由SCM控制的,并且服务数据库只能由管理员修改,攻击过程将无法欺骗它。

我不认为有这样做的安全方法。 无论您使用哪种系统唯一的或用户唯一的命名对象,恶意第三方软件仍然可以使用完全相同的名称,从而阻止您的应用程序启动。

如果您使用检查当前正在执行的进程的方法,并检查是否没有运行同名的可执行文件 – 如果恶意软件具有相同的可执行文件名,则会遇到问题。 如果您还检查该可执行文件的路径,则可以从不同位置运行两个应用程序副本。

如果你在开始/结束的时候创建/删除一个文件 – 那也可能被欺骗了。

唯一让我想到的是,通过将应用程序的所有逻辑放入一个COM对象中,然后让一个GUI应用程序通过COM接口与它交互,你也许能够达到预期的效果。 这样做只能确保只有一个COM对象 – 您可以根据需要运行尽可能多的GUI客户端。 请注意,我不是建议这是一个防弹的方法 – 它可能有自己的漏洞(例如 – 有人可以让你的GUI客户端连接到第三方COM对象,只需编辑注册表)。

所以,简短的回答 – 没有真正安全的方法来做到这一点。

我使用一个命名管道¹,其中名称是从必须是唯一的条件派生的:

  • 应用程序的名称(这不是可执行文件的文件名)
  • 启动应用程序的用户的用户名

如果命名管道创建失败,因为具有该名称的管道已经存在,那么我知道一个实例已经在运行。 我使用第二个锁来检查线程(进程)的安全性。 命名管道在应用程序终止时自动关闭(即使终止是由于“结束进程”命令导致的)。

¹这可能不是最好的一般选项,但在我的情况下,我最终在应用程序生命周期的稍后时间发送数据。

在伪代码中:

numberofapps = 0 for each process in processes if path to module file equals path to this module file increment numberofapps if number of apps > 1 exit 

有关如何枚举进程的详细信息,请参见msdn.microsoft.com/en-us/library/ms682623(VS.85).aspx 。