您的位置:首页 > 编程语言

读取指定用户注册表代码

2009-05-25 21:10 501 查看
如何读取指定用户的 HKEY_CURRENT_USER 注册表键

注册表中 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);

}

are you sure WTSQueryUserToken successfully, do you DuplicateTokenEx with SecurityImpersonation ,

even though you ImpersonateLoggedOnUser successfully, however you still can not access HKCU directly, because in this session special user's Profile never be loaded, you should call LoadUserProfile() first, then use the returned handle to access HKCU,

fellow is some parts of my code, hope can help you.

I just got Logged on console user token, and our code support 2000, so I didn't use WTSQueryUserToken, and dynamic load some API

if(GetConsoleUserToken(hToken)) // the function defined follow

{

if(pfnImpersonateLoggedOnUser)

{

if(pfnImpersonateLoggedOnUser(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)

{

if(pfnRevertToSelf)

pfnRevertToSelf();

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);

}

BOOL GetConsoleUserToken(HANDLE& hToken)

{

if(CheckOsVersion() < MS_WINXP) return FALSE;

BOOL bRet = FALSE;

DWORD dwConsoleSessionId = 0;

g_hKernel32 = LoadLibrary("Kernel32.dll");

//g_hUserenv = LoadLibrary("userenv.dll");

if(g_hKernel32)

{

pfnWTSGetActiveConsoleSessionId = (WTSGetActiveConsoleSessionId) GetProcAddress(g_hKernel32, "WTSGetActiveConsoleSessionId");

//pfnLoadUserProfile = (LoadUserProfileA) GetProcAddress(g_hUserenv, "LoadUserProfileA");

if(pfnWTSGetActiveConsoleSessionId)

{

dwConsoleSessionId = pfnWTSGetActiveConsoleSessionId();

pfnWTSGetActiveConsoleSessionId = NULL;

FreeLibrary(g_hKernel32);

g_hKernel32 = NULL;

if(dwConsoleSessionId == 0xFFFFFFFF)

{

// There is no session attached to the console

return FALSE;

}

}

else

{

dwConsoleSessionId = 0;

FreeLibrary(g_hKernel32);

g_hKernel32 = NULL;

return FALSE;

}

}

else

{

return FALSE;

}

HMODULE hPsapi = LoadLibrary("psapi.dll");

HMODULE hAdvapi32 = LoadLibrary("advapi32.dll");

if(NULL == hPsapi || hAdvapi32 == NULL)

{

if(hPsapi)

{

FreeLibrary(hPsapi);

hPsapi = NULL;

}

if(hAdvapi32)

{

FreeLibrary(hAdvapi32);

hAdvapi32 = NULL;

}

return FALSE;

}

pfnEnumProcesses = (PEnumProcesses) GetProcAddress(hPsapi, "EnumProcesses");

pfnGetModuleFileNameEx = (PGetModuleFileNameEx) GetProcAddress(hPsapi, "GetModuleFileNameExA");

pfnOpenProcessToken = (POpenProcessToken) GetProcAddress(hAdvapi32, "OpenProcessToken");

pfnGetTokenInformation = (PGetTokenInformation) GetProcAddress(hAdvapi32, "GetTokenInformation");

if(NULL == pfnEnumProcesses

|| NULL == pfnGetModuleFileNameEx

|| NULL == pfnOpenProcessToken

|| NULL == pfnGetTokenInformation)

{

pfnEnumProcesses = NULL;

pfnGetModuleFileNameEx = NULL;

pfnOpenProcessToken = NULL;

pfnGetTokenInformation = NULL;

FreeLibrary(hPsapi);

FreeLibrary(hAdvapi32);

hPsapi = NULL;

hAdvapi32 = NULL;

return FALSE;

}

DWORD aProcesses[1024] = {0};

DWORD dwNeeded = 0;

DWORD dwProcesses = 0;

if(!pfnEnumProcesses(aProcesses, sizeof(aProcesses), &dwNeeded))

{

pfnEnumProcesses = NULL;

pfnGetModuleFileNameEx = NULL;

FreeLibrary(hPsapi);

hPsapi = NULL;

FreeLibrary(hAdvapi32);

hAdvapi32 = NULL;

return FALSE;

}

dwProcesses = dwNeeded / sizeof(DWORD);

HANDLE hProcess = NULL;

char szProcessName[MAX_PATH];

char szDrive[MAX_PATH];

char szDir[MAX_PATH];

char szName[MAX_PATH];

char szExt[MAX_PATH];

DWORD dwExplorerSessionID = 0;

DWORD dwRetLength = 0;

for(DWORD i=0; i<dwProcesses; i++)

{

ZeroMemory(szProcessName, MAX_PATH);

ZeroMemory(szDrive, MAX_PATH);

ZeroMemory(szDir, MAX_PATH);

ZeroMemory(szName, MAX_PATH);

ZeroMemory(szExt, MAX_PATH);

hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, aProcessesIdea);

if(NULL != hProcess)

{

if(0 != pfnGetModuleFileNameEx(hProcess, NULL, szProcessName, sizeof(szProcessName)))

{

_splitpath(szProcessName, szDrive, szDir, szName, szExt);

if( (stricmp("explorer", szName) == 0) && (stricmp(".exe", szExt) == 0) )

{

if(pfnOpenProcessToken(hProcess, TOKEN_DUPLICATE|TOKEN_QUERY|TOKEN_IMPERSONATE, &hToken))

{

if(pfnGetTokenInformation(hToken, TokenSessionId, &dwExplorerSessionID, sizeof(DWORD), &dwRetLength))

{

if(dwExplorerSessionID == dwConsoleSessionId)

{

CloseHandle(hProcess);

bRet = TRUE;

break;

}

}

}

}

}

if(hToken)

CloseHandle(hToken);

hToken = NULL;

CloseHandle(hProcess);

hProcess = NULL;

}

}

if(hPsapi)

{

FreeLibrary(hPsapi);

hPsapi = NULL;

}

if(hAdvapi32)

{

FreeLibrary(hAdvapi32);

hAdvapi32 = NULL;

}

pfnEnumProcesses = NULL;

pfnGetModuleFileNameEx = NULL;

pfnOpenProcessToken = NULL;

pfnGetTokenInformation = NULL;

return bRet;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: