我正在尝试从LocalSystem服务模拟管理员帐户以便从管理员HKEY CURRENT USER注册表中获取数据 - 为了模仿我正在使用在Uwe Keim编写的以下站点中找到的codeproject代码:{{3 }}
我的源代码如下:
using (new Impersonator("user", ".", "pass"))
{
RegistryKey rk = Registry.CurrentUser.OpenSubKey("Software\\CompanyName");
string sValue = rk.GetValue("Value", "").ToString();
rk2.Close();
}
我的期望是sValue来自用户/通行证帐户(因为我冒充它)但奇怪的是它仍然是我的服务运行的LocalSystem帐户的sValue ......
我做错了什么线索?任何帮助将非常感激。 谢谢,
答案 0 :(得分:3)
我在这个主题上阅读的所有内容似乎都表明模拟可以让您访问模拟帐户的HKEY_CurrentUser。但是,它可能是.NET注册表实现中的一个怪癖。
这只是一种预感,而且是一种未经测试的,但您是否考虑使用Registry.Users而不是Registry.CurrentUser?
管理员帐户需要find the SID,但您应该能够使用Regedit推断出
答案 1 :(得分:1)
我猜你会发现你运气不好。它无法完成。
如果应用程序能够模拟管理员帐户并将值写入Windows中的注册表,则会出现巨大的安全漏洞。我的猜测是Registry.CurrentUser
属性总是会引用运行你的应用程序的用户......无论你是否尝试模仿。
修改强>
原来我没有阅读您正在使用的Impersonator代码的实现细节。你的问题可能完全不同。
在您的模拟代码运行之前,您的代码是否引用了Registry
静态类?如果是这样,那就是问题所在。如果查看Reflector中的Registry.CurrentUser
属性,您将看到它是由Registry
对象的静态构造函数设置的。首次引用静态对象时会调用静态构造函数。
在您的情况下,如果您引用Registry
对象(无论是否涉及CurrentUser
),则会调用静态构造函数,即将CurrentUser
设置为原始用户。 ..不是假冒帐户。
答案 2 :(得分:1)
我知道这是一个旧线程,但我最近遇到了同样的问题(虽然来自C ++ Windows服务)并且认为我会分享我的发现,因为很多论坛都提出了同样的问题但没有人留下令人满意的答案
基本上,我已经找到了两种方法来解决这个问题,尽管对于C应用程序而不是.NET(我没有使用pinvoke进行测试但它可能有效),这是一个答案。
解决方案1: 而不是使用RegOpenKey,使用RegOpenCurrentUser()来获取密钥句柄。显然,RegOpenKey没有获取模拟用户密钥的原因是因为HKEY_CURRENT_USER在正在运行的线程中缓存。
解决方案2: RegDisablePredefinedCache()。此禁用上面提到的缓存,并允许后续对HKEY_CURRENT_USER的调用是实际模拟的用户。这是我采用的解决方案。
希望这有帮助。
答案 3 :(得分:0)
默认情况下,HKEY_CURRENT_USER句柄在进程范围内缓存。因此,当您模拟用户然后访问当前用户配置单元时,您将访问启动该过程的用户的配置单元,而不是用户被模拟。对于所有Win32进程而言,这不仅仅是.Net。如果您希望禁用此缓存,以便所有当前用户调用转到HKEY_USERS下的正确用户配置单元,则必须通过pInvoke调用RegDisablePredefinedCache。
请注意,如果被模拟的用户未加载其个人资料,则任何CurrentUser请求都将转发给.DEFAULT用户。所以你可能还需要调用LoadUserProfile。
禁用句柄缓存也会导致所有CurrentUser请求略微减慢。