开好车的就一定是好人吗?
虽然这种启发式安装程序检测可以让一个旧有的安装程序能够直接在Windows Vista或者Windows 7上正常运行。但是,它本身也带来很多问题。一方面,一些不需要管理员权限就可以正常运行的应用程序,就因为文件名中含有了“setup”等相关的文字,比如,StockUpdater.exe,就被强行在运作的时候向用户询问请求管理员权限。这不仅给用户带来不便,同时也无形中降低了系统的安全性。甚至用户会因为担心系统受到损害而取消应用程序的运行。另一方面,一些恶意软件也会凭借这种机制的漏洞,将自己伪装成安装程序,从而轻松地,正大光明地获取管理员权限而给系统安全带来隐患。
与此相反的是,很多自定义的安装程序,并不使用Microsoft Windows Installer(MSI)技术,并且没有按照启发式安装程序检测的规则命名,这样,操作系统就不会认为它是一个安装程序。由于启发式安装程序检测不承认它是安装程序,所以用户在运行这些应用程序的时候,它并不会自动请求管理员权限运行,这就可能导致应用程序在向一些敏感位置写入数据时遇到拒绝访问错误,安装过程半途而废。
就像电影中的台词,“开好车的就一定是好人吗?”同样的,“姓Setup的就一定是安装程序吗?”
想要你就说嘛
既然微软的启发式安装程序检测这么弱智,那么我们只好自己麻烦一下,简单地为应用程序添加一个Manifest文件,告诉操作系统我们到底是不是安装程序,是否需要请求管理员权限。如果应用程序的源代码无法获得,我们只需要在应用程序的同一目录下为应用程序添加一个外部Manifest文件。这个Manifest文件的名字应该是应用程序文件名加上“.manifest”后缀。例如,StockUpdater.exe的Manifest文件的文件名应该是StockUpdater.exe.manifest。这个Manifest文件应该指明此应用程序在运行的时候是否需要申请管理员权限,或者是否在普通用户权限下就可以正常运行。
一个典型的外部Manifest文件如下所示:
<asmv1:assemblymanifestVersion="1.0"xmlns="urn:schemas-microsoft-com:asm.v1"xmlns:asmv1="urn:schemas-microsoft-com:asm.v1"xmlns:asmv2="urn:schemas-microsoft-com:asm.v2"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<assemblyIdentityversion="1.0.0.0"name="MyApplication.app"/>
<trustInfoxmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivilegesxmlns="urn:schemas-microsoft-com:asm.v3">
<!-- UAC Manifest 选项
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
-->
<requestedExecutionLevellevel="asInvoker"uiAccess="false" />
</requestedPrivileges>
</security>
</trustInfo>
</asmv1:assembly>
其中,requestedExecutionLevel属性就表示我们的应用程序正确执行所需要的权限。它有这样几个可选值:
• asInvoker – 它表示应用程序需要跟创建者相同的权限运行。也就是跟Windows Explorer相同的权限运行,通常就是普通用户权限。这个应用程序不是安装程序并且不会被启发式安装程序检测错误地标记。
• requireAdministrator – 它表示这个应用程序需要管理员权限才能正常运行。(它可能是一个安装程序。)
• highestAvailable – 它表示这个应用程序应该以尽可能高的权限运行。如果当前用户是一个管理员用户,那么它就等同于requireAdministrator 。如果当前用户是普通用户,那么它会在运行的时候请求管理员权限。
当我们为应用程序添加外部Manifest文件后,操作系统会根据Manifest文件中的定义为应用程序制定相应的UAC规则。例如,我们可以通过外部Manifest文件,为一个自定义的安装程序在执行时请求管理员权限。
图2 自定义安装程序