您的位置:首页 > 其它

windows下服务或SYSTEM权限读取当前用户注册表HKEY_CURRENT_USER

2014-06-04 10:36 639 查看
最近一直在给一个程序增加一个功能,需要修改注册表 HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\MountPoints2 下的值,刚开始自认为很简单,就调用修改注册表的API函数,但是各种尝试之后一直返回错误码2,自己纠结了很久。研究了两天才找到原因,我的程序是个服务权限是 SYSTEM,读取不到 HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\MountPoints2
下的值。原因如下(自己这么想的,对不对也不确定):

1. 服务运行在系统权限之下,而不是任何一个用户

2. HKEY_CURRENT_USER存储的是当前用户的信息

3. HKEY_CURRENT_USER的部分注册表写操作被重定向到HKEY_USERS下面去了;

经过各种大神的指导,终于解决了该问题。

有两种方法:

(一)模拟一个普通用户登陆,可以操作 HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\MountPoints2

(二) 获取 SID,操作HKEY_CURRENT_USER被重定向到 HKEY_USERS
的值。

方法一:

(1)
获取sessionId


DWORD cursessionid;

cursessionid = WTSGetActiveConsoleSessionId();

(2)根据
seesionid 获取用户令牌

HANDLE hToken


WTSQueryUserToken(cursessionid, &hToken)

(3)
模拟用户登陆


ImpersonateLoggedOnUser(hToken)

(4)获取用户名

TCHAR szUsername[MAX_PATH];

DWORD dwUsernameLen = MAX_PATH;

GetUserNameGetUserName(szUsername, &dwUsernameLen);

(5)保存当前模拟用户的信息并终止当前用户标识的模拟


PROFILEINFO cuProfileInfo;


cuProfileInfo.dwSize = sizeof(cuProfileInfo);

cuProfileInfo.lpUserName = szUsername;

cuProfileInfo.dwFlags = 1;


RevertToSelf();

(6)
根据保存的普通用户信息加载环境变量,加载完之后我们就可以用作普通用户操作注册了,要特别注意红字部分,否则还是操作失败


LoadUserProfile(hToken, &cuProfileInfo)


regedit = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\MountPoints2\\";


RegOpenKeyExA((struct HKEY__ *)cuProfileInfo.hProfile,
regedit.c_str(), NULL, KEY_ALL_ACCESS , &hkey);


操作完成之后记得卸载环境变量


UnLoadUserProfile(hToken);

方法二:

既然我们知道注册表被重定向到 HKEY_USER 下了,那我们就可以找到具体重定向那里了。

同 方法一的前 五步骤一样的,只是我们不加载普通用户的环境变量而是获取 用户的 SID。获取到 SID 我们就可以查找到重定向的位置

PSID pSID = NULL;

DWORD cbSid = 0;

LPTSTR DomainName = NULL;

DWORD cbDomainName = 0;

SID_NAME_USE SIDNameUse;

BOOL bDone = FALSE;

if(!LookupAccountName(NULL,

szUsername,

pSID,

&cbSid,

DomainName,

&cbDomainName,

&SIDNameUse))

{

pSID = (PSID)malloc(cbSid);

DomainName = (LPTSTR)malloc(cbDomainName * sizeof(TCHAR));

if(!pSID || !DomainName)

{

log_error("malloc memery is failed\s");

}

if(!LookupAccountName(NULL,

szUsername,

pSID,

&cbSid,

DomainName,

&cbDomainName,

&SIDNameUse))

{

log_error("%s LookupAccountName is failed\s", __FUNCTION__);

}

}

LPTSTR strsid;

ConvertSidToStringSid(pSID, &strsid);

FreeSid(pSID);

log_printf("%s\n", strsid);

if(strsid)

{

std::string regedit = strsid(这里不对的话可能是编码原因,注意编码的转换);

(在我们需要打开的子键前面再加上获取到的 SID, 就是 HKEY_CURRENT_USER 下注册表被重定向到 HKEY_USER 下的位置)

regedit += "\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\MountPoints2\\

RegOpenKeyExA(HKEY_USER, regedit.c_str(), NULL, KEY_ALL_ACCESS , &hkey);

我们打开 HEKY_USER 下的子键。

}

以上的步骤只是我自己操作的简单说明,可能有不对的地方,大家可以根据 MSDN 说明具体尝试
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐