`
coolsooner
  • 浏览: 1302838 次
文章分类
社区版块
存档分类
最新评论

UAC相关的几个问题/Manifest文件

 
阅读更多

Vista/Win7/Windows Server 2008,加入了UAC功能,这就给开发带来了很多问题,总结了一下碰到的问题和解决办法。
1)权限提升之前,即使是管理员权限帐号(built-in Administrator除外)登陆,也不能向根目录,C:/windows, C:/program files等目录下写文件。
还有也不能访问其他用户的私有文件夹,比如其他用户的Desktop文件夹等。

2)有时候执行一个安装程序,UAC的权限提升询问对话框(就是屏幕变暗那个)就会弹出来,Windows怎么知道这个程序需要权限提升才能执行呢?
a) 编译的时候加入manifest:<requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>
反过来,如果不希望提升,就指定为level="asInvoker"。下面会谈到,某些时候Windows也会误认为你的程序需要提升权限,本来是不需要。
但是这样有可能在WindowXP SP2造成程序崩溃的问题。
产生这个问题,目前已知的原因:手动编辑 manifest 文件导致的;使用 Visual Studio 2005 自动产生 manifest 文件导致的。
解决办法:http://support.microsoft.com/kb/921337/en-us
b) 程序名字或者文件说明里面包含了setup, install等单词,Windows就会把它当作一个安装程序,认为需要提升权限了。
很容易证明,随便找个EXE,把名字改成setup.exe,再去执行,看看会出现什么。这个时候,如果本来不需要提升,那就需要manifest了。

3)CreateProcessWithLogonW这个API,本来可以利用它来进行用户切换。
比如为了安装软件,通常需要管理员权限用户登录,
管理员可预先设定好管理权限用户密码,保存在安装包中,发给普通用户,
普通用户登陆执行安装包,通过这个API就可以切换到管理员权限,执行安装。这样就省事多了。
但是UAC下,任何调用 CreateProcess系列API来启动一个需要提升权限的程序(例如安装程序),这个API就会失败,返回ERROR_ELEVATION_REQUIRED(740)。
解决办法,写个壳程序,它不需要权限提升,CreateProcessWithLogonW切换用户并启动这个壳程序,
然后由这个壳程序调用ShellExecute来启动目标程序。
当然,调用ShellExecute提升权限的时候,还是会弹出UAC的权限提升询问对话框,否则就等于绕过UAC了。

4)RUN/RUNONCE注册表项
已知:(参考http://msdn2.microsoft.com/en-us/library/bb325654.aspx
a) UAC下,通过Startup菜单或者RUN注册表项启动的应用程序,如果此程序需要权限提升,将会被UAC阻止(Block)。
这个时候,右下角的任务栏上会出现个图标。
类似上面3)的办法,先启动个不需要权限提升的壳程序,这个壳程序再启动目标程序,可以解决这个问题。

b) UAC下,写在RUNONCE注册表的项目,如果用普通用户(非管理员用户)登陆,不会被执行。
好像没什么解决办法。

5)UAC使用UIPI(User Interface Privilage Intergrity)技术
来防止低权限(Lower Integrity)的进程通过向其他已提升权限的进程发送消息的方式来进行一些可能危害系统安全的操作。
但是如果我们需要这样做怎么办呢?
Vista之后提供了一个新的API, 提升过权限的进程调用它可以打开这个限制,允许接受从低安全等级的进程发送过来的消息。
API是ChangeWindowMessageFilter,有2个参数,消息代码和操作类型(接受还是拒绝)。
参考:http://msdn2.microsoft.com/en-us/library/ms632675(VS.85).aspx



使用Visual Studio进行开发的时候,默认是把Manifest文件嵌入到exe或者dll文件中的。
随Visual Studio提供一个工具mt.exe,可以用来把Manifest文件嵌入到exe或者dll文件中,或者反之,从文件中导出Manifest。
因此可以使用mt.exe来查看manifest。
exe文件:mt.exe -inputresource:<exe-file>;#1 -out:<manifest-file>
dll文件:mt.exe -outputresource:<dll-file>;#2 -out:<manifest-file>


和Manifest相关的一个技术是Side-by-Side Assembly(SxS),这是微软在Visual Studio 2005中引入的技术,用来解决Windows平台上的DLL Hell问题。
http://msdn.microsoft.com/en-us/library/aa376307%28VS.85%29.aspx
例如,使用VS2005生成exe中嵌入以下的manifest文件:


winsxs下有2个相关目录:
1)存放manifest文件
%WINDIR%/WinSxS/Manifests/x86_microsoft.vc80.crt_<版本>.manifest,该清单用来标识此程序集并列出其内容(属于此程序集的 DLL)
2)程序集
%WINDIR%/WinSxS/Manifests/x86_microsoft.vc80.crt_<版本>目录下。

这样程序启动时,需要到winsxs目录下去根据manifest中的版本信息加载相应的WinCRT。

并行程序集还可以使用发行者配置文件(也称为策略文件),以便在全局上重定向应用程序和程序集,使其从使用并行程序集的一个版本变为使用该程序集的另一版本。
Windows XP中该文件在%WINDIR%/WinSxS/Policies/下面。
Windows Vista以后在%WINDIR%/winsxs/Manifests/下面。
文件名是x86_policy.8.0.microsoft.vc80.crt_<版本>。
例如,在一台没有安装上面exe的manifest中记载版本(8.0.50608.0)的CRTWindowsVista系统上,也能正常运行此exe。
原因是在已经安装的CRT的策略文件中有如下记载:


以上策略指定,对于需要此程序集8.0.41204.256-8.0.50608.0版的任何应用程序或程序集,都应改用此程序集的8.0.50727.5592版,此版本是安装在系统上的当前版本。
所以程序会改为加载8.0.50727.5592的CRT,也就能够正常启动了。

也可以将 CRT 程序集作为私有并行程序集,安装在应用程序的本地文件夹中。如果操作系统未能找到 CRT 或作为共享程序集的任何其他程序集,它会开始将该程序集作为私有程序集来查找。它将按以下顺序搜索私有程序集:
1.在应用程序本地文件夹中查找名为 <assemblyName>.manifest 的清单文件。在此示例中,加载程序尝试在exe所在的文件夹中查找 Microsoft.VC80.CRT.manifest。如果找到该清单,加载程序将从应用程序文件夹中加载 CRT DLL。如果未找到 CRT DLL,加载将失败。

2.尝试在exe本地文件夹中打开文件夹 <assemblyName>,如果存在此文件夹,则从中加载清单文件 <assemblyName>.manifest。如果找到该清单,加载程序将从 <assemblyName> 文件夹中加载 CRT DLL。如果未找到 CRT DLL,加载将失败。

因此对于VS2005,可以到
<VS2005安装目录>/VC/redist/x86/Microsoft.VC80.CRT目录下,把以下4个文件拷贝出来,和exe一起发布。注意不能只是拷贝dll文件,必须也拷贝manifest文件。
Microsoft.VC80.CRT.manifest
msvcm80.dll
msvcp80.dll
msvcr80.dll

另外,VS2010中似乎已经取消了使用winsxs,至少默认是不用的。

可以参考http://blogs.msdn.com/b/vcblog/archive/2008/10/28/visual-studio-2010-ctp-released.aspx

New deployment model for Visual C++ Libraries (changed to not use Windows SxS configuration)

分享到:
评论

相关推荐

    解决VC6无法指定manifest文件,调用msvcr90.dll出现R6034错误

    解决VC6无法指定manifest文件,在启动MSVCR90前没有CreateActCtxA和ActivateActCtx导致的R6034运行时错误

    UAC相关资料

    UAC相关资料

    易语言UAC添加器

    易语言UAC添加器源码,UAC添加器,按钮1_被左键按下,按钮2_被左键按下,取文件格式,更新Manifest清单,BeginUpdateResource,UpdateResource,EndUpdateResource,FindResource

    win7/win8/win10 vc过UAC

    老外对于32/64位win7/win8/win10系统下过UAC总结的几种思路,vs2012编译,供大家参考学习

    威纶通触摸屏用户登录权限案例 UAC指令

    UAC指令 主要功能: ①用户登录 ②权限级别修改设置 ③新建删除用户 ④密码修改 威纶通触摸屏用户登录模板 触摸屏软件版本6.08.01.350s

    delphi7 程序以管理员权限运行 uac.RES 经典控件界面

    下载的uac.RES文件在用{$R 'uac.res'}指令编译后,生成的可执行程序都是Win7控件界面,而我们要的结果可能只是需要程序以管理员权限运行,并且Win7控件界面运行的Delphi7程序有一些兼容性问题,要就遇到了,所以,就...

    pyinstaller打包单文件时–uac-admin选项不起作用怎么办

    也就是双击exe文件运行时,需要弹出一个uac界面让用户授权。 于是我查找pyinstaller的官方文档,说是在打时包加上--uac-admin参数就行了! 然而我实际操作了一下,发现直接加上这个参数仅在打包成多文件时有效 ,...

    UAC标准文档.rar

    USB开发音频方面的官方文档,UAC(USB Audio Class)的标准英文文档。详细描述了UAC的通信规则,内含UAC1.0和UAC2.0两个标准文档

    彻底关闭UAC

    彻底关闭UAC小工具体积在200KB左右,是单文件绿色版软件,支持在vista到windows 10或更新的操作系统上彻底关闭windows的UAC。

    windream.rar

    dumpbin.exe link.exe midlrtmd.dll mspdb140.dll mt.exe tbbmalloc.dll uac.bat uac.manifest

    关闭UAC &以管理员方式运行所有程序.bat

    右键-以管理员方式运行此批处理-重启-会得到两个效果: 效果1:鼠标左键双击任何程序都是以管理员身份运行,等同于鼠标右键-以管理员身份运行。 效果2:UAC用户控制设置滑块调为最最低(从不通知)。

    易语言添加UAC信息源码,易语言添加UAC信息模块

    易语言添加UAC信息模块源码,添加UAC信息模块,添加UAC信息,开始更新资源,更新资源,结束更新资源

    UAC_UAS例子

    UAC_UAS例子,两个exe可执行程序,UAC和UAS分别监听本地的15060、15061端口 命令行输入参数进行测试

    Win7不关UAC去除单个程序右下角盾牌限制-给UAC添加白名单

    Win7不关UAC去除单个程序右下角盾牌限制-给UAC添加白名单

    close_uac 脚本文件

    在windows上进行开发的时候,有些地方需要管理员的权限才可以。这个脚本的作用就是设置每次软件的运行丢失管理员的权限

    win7 uac探究

    对于windows7里面uac功能的探究

    UAC_1.0版本规范.7z

    UAC的官网资料,网上能下载需要积分都太多,自己传一份帮助大家可以学习研究。没有积分的,单独联系我分享给你。

    Windows7关闭UAC的方法

    Windows7关闭UAC的方法Windows7关闭UAC的方法

    UAC提权Oday

    UAC提权Oday,第一次使用感觉不错,分享了哦

    活学活用UAC安全机制

    在UAC的保护下,当用户在系统中执行更改设置、运行程序、安装软件等操作时,因为这些操作可能影响到系统的安全性和稳定性,系统就会对其进行拦截,并弹出UAC提示窗口,提醒用户是否真的进行该操作,此时其它任何操作...

Global site tag (gtag.js) - Google Analytics