如何读取指定用户的 HKEY_CURRENT_USER 注册表键
2012-12-20 20:54
429 查看
注册表中 HKEY_CURRENT_USER 键下的内容隶属当前用户,所以当你以不同用户登陆时该键下的内容都是不尽相同的。但有时候我们有读取指定用户该键下内容的需求。比如,我们有一个服务程序运行在 Session0, SYSTEM 权限,而我们想读取的却是当前登陆到本地控制台的用户的 IE 代理服务器设置参数。我们当然不能直接从服务中打开 HKEY_CURENT_USER 键, 用我们当前令牌打开的是 SYSTEM 的 HKEY_CURRENT_USER 键,或许我们想可以通过当前线程扮演控制台用户来读取这个键
ImpersonateLoggedOnUser(hToken);
RegOpenKeyEx(HKEY_CURRENT_USER...);
RevertToSelf();
其实这个方法也是不行的,因为虽然我们取得了控制台用户的令牌,并且模仿该用户,但因为在当前空间并没有装载该用户的环境变量,用户上下文,所以这里的 RegOpenKeyEx 调用还是失败的。
好在微软为我们准备了 LoadUserProfile();
首先我们可以用
WTSGetActiveConsoleSessionId 取得当前控制台会话的 id, 这个API xp/2003 以上才有,2000 没有怎么办?2000直接可以省却这一步了,因为 2000 不支持用户切换,所以本地控制台永远运行在 Session0.
然后你可以用 WTSQueryUserToken 获得指定 Session 已登陆用户令牌。这个API依然是 xp/2003 才支持, 2000 怎么办,自己想办法吧(是不是可以打开 explorer.exe 的令牌看看 :) )。
然后 LoadUserProfile 装载该用户的环境变量了。
这段代码贴在下面吧, 可能不完整,我使用的这几个 API 都是动态装载的, 因为我们的软件可能要支持 98, 所以只能动态装载,否则就根本不能运行了。注意一下粗体部分,关键就在这里了。不清楚就看看 MSDN 吧,微软讲得很清楚了。向 MSDN team 致敬!
HANDLE hToken = NULL;
BOOL bImpersonated = FALSE;
PROFILEINFOA cuProfileInfo;
TCHAR szUsername[MAX_PATH];
DWORD dwUsernameLen = MAX_PATH;
if(GetConsoleUserToken(&hToken))
{
if(ImpersonateLoggedOnUser(hToken))
{
bImpersonated = TRUE;
//MessageBox(NULL, "I.. L.. User OK", "", NULL);
}
GetUserName(szUsername, &dwUsernameLen);
memset(&cuProfileInfo, 0, sizeof(cuProfileInfo));
cuProfileInfo.dwSize = sizeof(PROFILEINFOA);
cuProfileInfo.lpUserName = szUsername;
cuProfileInfo.dwFlags = 1;
if(bImpersonated)
{
RevertToSelf();
bImpersonated = FALSE;
}
if(pfnLoadUserProfile)
{
if(pfnLoadUserProfile(hToken, &cuProfileInfo))
{
RegOpenKeyEx((struct HKEY__ *)cuProfileInfo.hProfile, IEPROXY_LOCALUSER_KEY, 0, KEY_QUERY_VALUE, ®KeyFrom);
//MessageBox(NULL, "Open spc key", "", NULL);
}
else
{
RegOpenKeyEx(HKEY_CURRENT_USER, IEPROXY_LOCALUSER_KEY, 0, KEY_QUERY_VALUE, ®KeyFrom);
}
}
//MessageBox(NULL, "ImpersonateLoggedOnUser Successful", "atagtctl", NULL);
}
else
{
RegOpenKeyEx(HKEY_CURRENT_USER, IEPROXY_LOCALUSER_KEY, 0, KEY_QUERY_VALUE, ®KeyFrom);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
很多人写的服务都是以默认的 LocalSystem 帐号运行,该帐号在本机上有极高的权限,但有几个限制:
1. 不能访问网络资源;
2. 没有对应的 SID,不能访问需要登录才能访问的资源;
所以,这样的服务不能直接访问 HKEY_CURRENT_USER,读取会失败,写入则会被重定向到 HKEY_USER\.Default 下;
经过查资料,需要做两件事:
1. 模仿一个用户登录;
HANDLE hLogonToken = NULL;
HANDLE hAdminToken = NULL;
if (!LogonUser(m_strUserName, _T("."), m_strPassword,
LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &hLogonToken))
{
DebugInfo(_T("ImpersonateAdmin(): LogonUser() failed."));
return FALSE;
}
if (!DuplicateTokenEx(hLogonToken, TOKEN_ALL_ACCESS, NULL,
SecurityIdentification, TokenPrimary, &hAdminToken))
{
DebugInfo(_T("ImpersonateAdmin(): DuplicateTokenEx() failed."));
CloseHandle(hLogonToken);
return FALSE;
}
if (!ImpersonateLoggedOnUser(hAdminToken))
{
DebugInfo(_T("ImpersonateAdmin(): ImpersonateLoggedOnUser() failed."));
CloseHandle(hAdminToken);
CloseHandle(hLogonToken);
return FALSE;
}
CloseHandle(hAdminToken);
CloseHandle(hLogonToken);
// .....
RevertToSelf();
2. 把 HKEY_CURRENT_USER 映射到当前模仿的用户,这个工作需要程序员显式地调用;
HKEY hKey = HKEY_CURRENT_USER;
RegOpenCurrentUser(KEY_ALL_ACCESS, &hKey);
ImpersonateLoggedOnUser(hToken);
RegOpenKeyEx(HKEY_CURRENT_USER...);
RevertToSelf();
其实这个方法也是不行的,因为虽然我们取得了控制台用户的令牌,并且模仿该用户,但因为在当前空间并没有装载该用户的环境变量,用户上下文,所以这里的 RegOpenKeyEx 调用还是失败的。
好在微软为我们准备了 LoadUserProfile();
首先我们可以用
WTSGetActiveConsoleSessionId 取得当前控制台会话的 id, 这个API xp/2003 以上才有,2000 没有怎么办?2000直接可以省却这一步了,因为 2000 不支持用户切换,所以本地控制台永远运行在 Session0.
然后你可以用 WTSQueryUserToken 获得指定 Session 已登陆用户令牌。这个API依然是 xp/2003 才支持, 2000 怎么办,自己想办法吧(是不是可以打开 explorer.exe 的令牌看看 :) )。
然后 LoadUserProfile 装载该用户的环境变量了。
这段代码贴在下面吧, 可能不完整,我使用的这几个 API 都是动态装载的, 因为我们的软件可能要支持 98, 所以只能动态装载,否则就根本不能运行了。注意一下粗体部分,关键就在这里了。不清楚就看看 MSDN 吧,微软讲得很清楚了。向 MSDN team 致敬!
HANDLE hToken = NULL;
BOOL bImpersonated = FALSE;
PROFILEINFOA cuProfileInfo;
TCHAR szUsername[MAX_PATH];
DWORD dwUsernameLen = MAX_PATH;
if(GetConsoleUserToken(&hToken))
{
if(ImpersonateLoggedOnUser(hToken))
{
bImpersonated = TRUE;
//MessageBox(NULL, "I.. L.. User OK", "", NULL);
}
GetUserName(szUsername, &dwUsernameLen);
memset(&cuProfileInfo, 0, sizeof(cuProfileInfo));
cuProfileInfo.dwSize = sizeof(PROFILEINFOA);
cuProfileInfo.lpUserName = szUsername;
cuProfileInfo.dwFlags = 1;
if(bImpersonated)
{
RevertToSelf();
bImpersonated = FALSE;
}
if(pfnLoadUserProfile)
{
if(pfnLoadUserProfile(hToken, &cuProfileInfo))
{
RegOpenKeyEx((struct HKEY__ *)cuProfileInfo.hProfile, IEPROXY_LOCALUSER_KEY, 0, KEY_QUERY_VALUE, ®KeyFrom);
//MessageBox(NULL, "Open spc key", "", NULL);
}
else
{
RegOpenKeyEx(HKEY_CURRENT_USER, IEPROXY_LOCALUSER_KEY, 0, KEY_QUERY_VALUE, ®KeyFrom);
}
}
//MessageBox(NULL, "ImpersonateLoggedOnUser Successful", "atagtctl", NULL);
}
else
{
RegOpenKeyEx(HKEY_CURRENT_USER, IEPROXY_LOCALUSER_KEY, 0, KEY_QUERY_VALUE, ®KeyFrom);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
很多人写的服务都是以默认的 LocalSystem 帐号运行,该帐号在本机上有极高的权限,但有几个限制:
1. 不能访问网络资源;
2. 没有对应的 SID,不能访问需要登录才能访问的资源;
所以,这样的服务不能直接访问 HKEY_CURRENT_USER,读取会失败,写入则会被重定向到 HKEY_USER\.Default 下;
经过查资料,需要做两件事:
1. 模仿一个用户登录;
HANDLE hLogonToken = NULL;
HANDLE hAdminToken = NULL;
if (!LogonUser(m_strUserName, _T("."), m_strPassword,
LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &hLogonToken))
{
DebugInfo(_T("ImpersonateAdmin(): LogonUser() failed."));
return FALSE;
}
if (!DuplicateTokenEx(hLogonToken, TOKEN_ALL_ACCESS, NULL,
SecurityIdentification, TokenPrimary, &hAdminToken))
{
DebugInfo(_T("ImpersonateAdmin(): DuplicateTokenEx() failed."));
CloseHandle(hLogonToken);
return FALSE;
}
if (!ImpersonateLoggedOnUser(hAdminToken))
{
DebugInfo(_T("ImpersonateAdmin(): ImpersonateLoggedOnUser() failed."));
CloseHandle(hAdminToken);
CloseHandle(hLogonToken);
return FALSE;
}
CloseHandle(hAdminToken);
CloseHandle(hLogonToken);
// .....
RevertToSelf();
2. 把 HKEY_CURRENT_USER 映射到当前模仿的用户,这个工作需要程序员显式地调用;
HKEY hKey = HKEY_CURRENT_USER;
RegOpenCurrentUser(KEY_ALL_ACCESS, &hKey);
相关文章推荐
- 如何读取指定用户的 HKEY_CURRENT_USER 注册表键
- 如何读取指定用户的 HKEY_CURRENT_USER 注册表键收藏
- 如何读取指定用户的 HKEY_CURRENT_USER 注册表键
- windows下服务或SYSTEM权限读取当前用户注册表HKEY_CURRENT_USER
- 服务中读取当前用户注册表HKEY_CURRENT_USER
- 服务中读取当前用户注册表HKEY_CURRENT_USER
- 在服务中模拟当前登录用户读取HKEY_CURRENT_USER
- system 权限读取注册表HKEY_CURRENT_USER
- 如何在Windows服务程序中读写HKEY_CURRENT_USER注册表
- NT服务程序中对注册表中HKey_Current_User读取的问题
- C# winform webbrowser如何指定内核为IE11? 输出 this.webbrowser.Version 显示版本是IE11的,但实际版本不是啊! 网上打的修改注册表HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULA
- Impersonate时读取HKEY_CURRENT_USER的问题(Registry.CurrentUser为空)
- 读取指定用户注册表代码
- Windows服务中操作HKEY_CURRENT_USER注册表
- 如何理解Python的web框架tornado文档里面的用户认证的self.current_user?
- VC 用服务进程开启有UI的进程和写注册表HKEY_CURRENT_USER子键的问题
- mysql如何杀掉指定用户的所有链接
- 在内核中之获取HKEY_CURRENT_USER对应路径
- 如何在网页读取用户IP,操作系统版本等数据demo
- HKEY_LOCAL_MACHINE (or HKEY_CURRENT_USER)