7

我们正在开发一个 C# .NET windows 服务。

我们的服务在系统帐户下运行,我们正在尝试模拟登录用户 USER。模拟工作正常,即在System.Security.Principal.WindowsIdentity.GetCurrent()模拟后调用时,我们得到正确的用户'USER'。

问题是当我们尝试访问用户配置文件时,我们没有得到预期的结果。一个示例是访问注册表 CURRENT_USER。我们收到拒绝访问错误。当使用第三方功能时,我们假设它部分使用了注册表,我们获得了“真实”(在模拟之前)用户的详细信息。此外,在调用时,Environment.ExpandEnvironmentVariables("%TEMP%")我们会获取系统配置文件而不是登录的用户配置文件。

有没有办法完全模仿不同的用户?我知道我们可以使用 LoadUserProfile 来获取特定的用户配置文件,但这对我们不利,因为我们正在运行使用当前用户配置文件的第三方 dll。

我们的模拟代码就是基于

4

2 回答 2

3

正如您所发现的,模拟不会设置HKEY_CURRENT_USER或环境。

这是因为模拟令牌是每个线程的,而 HKCU 和环境是每个进程的。

如果您需要访问用户的常用环境,您将需要使用HKEY_USERS\SID和模拟用户的 SID HKEY_USERS\S-1-5-21-12345678-12345678-12345678-1234,例如。调用LoadUserProfile以确保已加载密钥。(如果它应该是当前登录的用户,它应该已经加载,所以你可能不应该这样做,但检查它是否存在,如果不存在则返回错误)。

您还可以计算出他们通常的环境,因为这是在 HKCU 内的关键“环境”下。您只需要将它与系统环境结合起来。

如果第三方 DLL 确实需要正确设置 HKCU 和环境,则需要在用户的登录会话中创建一个进程来托管 DLL,并以某种方式将任何操作的结果发回。如果只需要环境,可以创建一个子进程,手动设置环境。

但是,您还没有说为什么要这样做。听起来您已经将此作为解决更大问题的一部分。如果可能的话,我建议您看看是否有一种方法可以在不获取用户环境或 HKCU 的情况下完成您需要的操作。

为什么 DLL 不能直接在用户自己的会话中运行?为什么需要一项服务?您能否重新设计您的解决方案,以便在登录会话中运行并托管第三方 DLL 的用户模式部分,并与服务进行通信,以便服务只执行绝对需要的操作?

于 2013-01-08T14:45:56.367 回答
2

我注意到代码没有调用LoadUserProfile,因此没有加载用户配置文件。

请注意该功能的备注,HKEY_CURRENT_USER但仍然没有被替换。

认为你可以通过调用来解决这个问题(在调用第三方 DLL 之前)RegOverridePredefKey

请注意,让这一切正常工作可能涉及很多巫术 - 我会尽量确保在第三方调用之前尽可能晚地发生覆盖,并在之后尽快恢复(希望这就是全部对图书馆的一次调用)。

作为替代方案,我会认真尝试寻找不同的 3rd 方产品,它不需要所有这些跳过箍。

于 2013-01-08T14:37:37.773 回答