windows “以管理员身份运行”和带有 requireAdministrator 的清单有什么区别?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3224804/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What are the differences between "Run as administrator" and a manifest with requireAdministrator?
提问by Daniel Stutzbach
I've written a program with a manifest that includes requireAdministrator. On Windows 7 systems with UAC enabled, Windows pops up a dialog asking for permissions, as it should. Works great.
我编写了一个包含 requireAdministrator 的清单的程序。在启用了 UAC 的 Windows 7 系统上,Windows 会弹出一个对话框,询问权限,这是应该的。效果很好。
If a user starts my program by right-clicking it and choosing "Run as administrator", then Windows 7 also pops up a dialog asking for permissions. However, there are some slight differences in how my program operates in some of the more esoteric parts of my program.
如果用户通过右键单击它并选择“以管理员身份运行”来启动我的程序,则 Windows 7 还会弹出一个对话框,要求获得权限。但是,在我的程序的一些更深奥的部分中,我的程序的运行方式存在一些细微的差异。
So what are the differences between "Run as administrator" and a manifest with requireAdministrator? Any links to documentation that describe differences would be appreciated.
那么“以管理员身份运行”和带有 requireAdministrator 的清单有什么区别?任何指向描述差异的文档的链接将不胜感激。
Edit: This is with UAC enabled.
编辑:这是启用了 UAC。
Edit: As promised below is the full explanation of the difference I'm seeing.
编辑:正如下面所承诺的,是我所看到的差异的完整解释。
I'm using the EasyHook libraryto inject a DLL into another process. When my application is run with "Run as administrator", the injected process crashes and EasyHook returns the error "Unknown error in injected assembler code". None of the code in my DLL gets a chance to execute; the crash occurs before then. (Moreover, the crash occurs even if I strip the DLL down to nothing)
我正在使用EasyHook 库将 DLL 注入另一个进程。当我的应用程序以“以管理员身份运行”运行时,注入的进程崩溃并且 EasyHook 返回错误“注入的汇编代码中的未知错误”。我的 DLL 中的所有代码都没有机会执行;崩溃发生在此之前。(此外,即使我将 DLL 剥离到零,也会发生崩溃)
If I run my program normally (i.e., elevated via requireAdministrator), everything works fine.
如果我正常运行我的程序(即通过 requireAdministrator 提升),一切正常。
My application is composed of a few different executables. The process that the user launches is not the same process that performs the injection.
我的应用程序由几个不同的可执行文件组成。用户启动的进程与执行注入的进程不同。
回答by Dirk Vollmar
With the information given there would be no differences in the permissions between the two processes.
根据给出的信息,两个进程之间的权限没有区别。
If you request an execution level of "requireAdministrator" via the applications manifest your application will either be launched with the full access token of an administrator or not at all if the user denies consent (see Create and Embed an Application Manifest (UAC)for further information).
如果您通过应用程序清单请求“requireAdministrator”的执行级别,您的应用程序将使用管理员的完整访问令牌启动,或者如果用户拒绝同意则根本不启动(请参阅创建和嵌入应用程序清单 (UAC)以获取更多信息)信息)。
The same will happen when a user chooses Run as Administrator.
当用户选择Run as Administrator时,也会发生同样的情况。
The only difference is the way that the process is started. When you start an executable from the shell, e.g. by double-clicking in Explorer or by selecting Run as Administratorfrom the context menu, the shell will call ShellExecute
to actually start process execution. The whole process of elevation is hidden inside this function. Kenny Kerr describes this process in more details in Windows Vista for Developers – Part 4 – User Account Control:
唯一的区别是该过程的启动方式。当您从外壳启动可执行文件时,例如通过在资源管理器中双击或从上下文菜单中选择以管理员身份运行,外壳将调用ShellExecute
以实际启动流程执行。整个提升过程都隐藏在这个函数里面。Kenny Kerr 在Windows Vista for Developers – Part 4 – User Account Control中更详细地描述了这个过程:
ShellExecute first calls CreateProcess to attempt to create the new process. CreateProcess does all the work of checking application compatibility settings, application manifests, runtime loaders, etc. If it determines that the application requires elevation but the calling process is not elevated then CreateProcess fails with ERROR_ELEVATION_REQUIRED. ShellExecute then calls the Application Information service to handle the elevation prompt and creation of the elevated process since the calling process obviously doesn't have the necessary permissions to perform such a task. The Application Information service ultimately calls CreateProcessAsUser with an unrestricted administrator token.
If on the other hand you want to create an elevated process regardless of what application information is available then you can specify the little-known “runas” verb with ShellExecute. This has the effect of requesting elevation regardless of what an application's manifest and compatibility information might prescribe. The runas verb is not actually new to Windows Vista. It was available on Windows XP and Windows 2003 and was often used to create a restricted token directly from the shell. This behavior has however changed. Here is a simple example:
::ShellExecute(0, // owner window L"runas", L"C:\Windows\Notepad.exe", 0, // params 0, // directory SW_SHOWNORMAL);
ShellExecute 首先调用 CreateProcess 以尝试创建新进程。CreateProcess 执行检查应用程序兼容性设置、应用程序清单、运行时加载程序等的所有工作。如果它确定应用程序需要提升但调用进程没有提升,则 CreateProcess 失败并显示 ERROR_ELEVATION_REQUIRED。ShellExecute 然后调用应用程序信息服务来处理提升提示和提升进程的创建,因为调用进程显然没有执行此类任务所需的权限。应用程序信息服务最终使用不受限制的管理员令牌调用 CreateProcessAsUser。
另一方面,如果您想创建一个提升的进程而不管有哪些应用程序信息可用,那么您可以使用 ShellExecute 指定鲜为人知的“runas”动词。无论应用程序的清单和兼容性信息可能规定什么,这都会产生请求提升的效果。runas 动词实际上并不是 Windows Vista 的新内容。它在 Windows XP 和 Windows 2003 上可用,通常用于直接从外壳创建受限令牌。然而,这种行为已经改变。这是一个简单的例子:
::ShellExecute(0, // owner window L"runas", L"C:\Windows\Notepad.exe", 0, // params 0, // directory SW_SHOWNORMAL);
So essentially starting an executable using the Run as Administratoroption means that ShellExecute
bypasses the checks for compatibility settings, application manifests etc and directly requests elevation.
因此,本质上使用以管理员身份运行选项启动可执行文件意味着ShellExecute
绕过兼容性设置、应用程序清单等检查并直接请求提升。
Kenny Kerr's article also has sample code to query the current process' token for its permission using the OpenProcessToken
function. Possibly you can use the example to identify that there are no differences in the way your process is elevated.
Kenny Kerr 的文章还提供了示例代码,可以使用该OpenProcessToken
函数查询当前进程的令牌以获取其权限。也许您可以使用该示例来确定您的流程提升方式没有差异。
I'm definitely curious to know which differences you are observing as I strongly doubt they are related to elevation.
我非常想知道您观察到哪些差异,因为我强烈怀疑它们与海拔有关。
As a last thing: Can you double check that you really request a level of requireAdministratorand not by mistake only a level of highestAvailable?
作为最后一件事:你能仔细检查,你真的要求的水平 requireAdministrator而不是错误只的水平highestAvailable?
回答by Kate Gregory
One possible difference might be the rarely used/understood/deliberately-chosen uiAccess attribute. Can you create two manifests, one with uiAccess=false and one with uiAccess=true, then tell us whether one of them gives the same behaviour as you see with right-click-run-as-admin?
一种可能的区别可能是很少使用/理解/故意选择的 uiAccess 属性。您能否创建两个清单,一个是 uiAccess=false,一个是 uiAccess=true,然后告诉我们其中一个是否与您在右键单击以管理员身份运行时看到的行为相同?
回答by DieDaily
The EasyHook documentation for the RemoteHooking class' IsAdministrator property mentions:
RemoteHooking 类的 IsAdministrator 属性的 EasyHook 文档提到:
Due to UAC on Windows Vista, this property in general will be false even if the user is in the builtin-admin group. As you can't hook without administrator privileges you should just set the UAC level of your application to requireAdministrator.
由于 Windows Vista 上的 UAC,即使用户在 builtin-admin 组中,此属性通常也会为 false。由于没有管理员权限您无法挂钩,因此您应该将应用程序的 UAC 级别设置为 requireAdministrator。
It's hard to imagine why this is happening, but it is conceivable (especially as you are seeing it happen!) that assets, processes, assemblies, &c, with possibly different trust levels and so forth, will not inherit the elevation of your main app. Setting the requireAdministrator flag may handle/enforce this globally across the entire scope of resources and dependencies. Would love to know how this turns out.
很难想象为什么会发生这种情况,但可以想象(尤其是当您看到它发生时!)资产、流程、程序集等,可能具有不同的信任级别等,不会继承您的主应用程序的提升. 设置 requireAdministrator 标志可以在整个资源和依赖项范围内全局处理/强制执行此操作。很想知道结果如何。
回答by jlarchibald
I thought I was seeing a difference between these as well. However, it turned out that in my case the issue was this:
我以为我也看到了这些之间的区别。然而,事实证明,就我而言,问题是这样的:
When I click "Run as Administrator" from my file browser (Q-Dir), the working directory is different than when I try simply double clicking an application with requireAdministrator
set in the manifest. This changed the behavior of some buggy DLLs I had received. In fact, it turned out that 100% of the differences I saw were due to running from different working directories (specifically, it mattered whether I was on C: drive or a different drive letter) and that the method of getting the program to run as administrator had nothing to do with it.
当我从文件浏览器 (Q-Dir) 单击“以管理员身份运行”时,工作目录与我尝试双击requireAdministrator
清单中设置的应用程序时不同。这改变了我收到的一些有问题的 DLL 的行为。事实上,事实证明我看到的 100% 的差异是由于从不同的工作目录运行(具体来说,我是在 C: 驱动器上还是不同的驱动器盘符上很重要)以及让程序运行的方法作为管理员与它无关。
It's an issue that is specific to my computer's exact configuration, but it is a possible clue into the type of thing that might be happening (or might have happened 7 years ago . . . )
这是一个特定于我的计算机的确切配置的问题,但它是可能发生的事情类型的线索(或者可能发生在 7 年前......)