服务中读取当前用户注册表HKEY_CURRENT_USER

服务 HKEY_CURRENT_USER HKEY_USER 读取 RegQueryValueEx 注册表

 

我在服务程序中使用RegQueryValueEx读取注册表HKEY_CURRENT_USER下的内容,发现读取到的内容不是预期的内容。

原因是:

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

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

================>导致在服务中读取HKEY_CURRENT_USER,不是当前登录的用户。同样,写入也不是。

所以如果我要操作HKEY_CURRENT_USER之内的键值,就必须模拟当前用户去读取。

 

有几种思路可以做到:

1.创建一个用户进程去操作注册表,使用CreateProcessAsUser函数可以做到

2.让当前线程模拟当前登录用户的安全上下文(lets the calling thread impersonate the security context of a logged-on user)。使用ImpersonateLoggedOnUser 函数可以做到。

 

第一个方法需要用到另外一个程序,感觉比较麻烦。

以下演示第二种方法:

 

1.要调用ImpersonateLoggedOnUser 函数,就先要获得该用户的令牌 (token)

DWORD pid = FindProcessByName(L"explorer.exe");
HANDLE ph = OpenProcess (PROCESS_ALL_ACCESS, FALSE, pid); 
HANDLE token; 
OpenProcessToken (ph, TOKEN_QUERY | TOKEN_DUPLICATE, &token);

 

2.模拟登录用户的安全上下文

ImpersonateLoggedOnUser (token);

 

3.获取用户名

wchar_t szBuf[MAX_PATH] = L"";

DWORD dwRet = MAX_PATH;
GetUserName(szBuf, &dwRet);

 

 4.到这里已经模拟完了,别忘记返回原来的安全上下文
 RevertToSelf();

 

 5.获取sid
PSID pSid = NULL;
LPWSTR sid;
GetAccountSid(szBuf, &pSid); //获取得到的是一个结构体
ConvertSidToStringSid(pSid, &sid); //从结构体中得到sid串

 

6.构造 sid+注册表位置
 例如想读取的注册表位置为,Software\\Microsoft\\Windows\\CurrentVersion\\Intern Settings\\

 你得到的sid为:S-1-5-21-1229272821-1897051121-682003330-1003

那么,应该组合成 :"S-1-5-21-1229272821-1897051121-682003330-1003\\Software\\Microsoft\\Windows\\CurrentVersion\\Intern Settings\\";

 

7.可以读取了,注意RegQueryValueEx的参数“HKEY_USERS”
keyPosition就是上面构造的那一串。
bool result = RegOpenKeyEx(HKEY_USERS,keyPosition,0,KEY_READ,&hKEY);
DWORD it = sizeof(DWORD);
DWORD dwType = REG_NONE;
DWORD dwCount = 0;
RegQueryValueEx(hKEY, 你要读的键值名, NULL, &dwType, NULL, &dwCount);   //获取长度
RegQueryValueEx(hKEY,你要读的键值名, NULL, &dwType, (LPBYTE)(&it), &dwCount);//读取

 

 

流程就是这样,有什么bug,欢迎反映

 

 

补上前面用到的两个函数:


//
// 查找进程pid
//
DWORD FindProcessByName(LPCWSTR ProcessName)
{
 HANDLE hHandle;
 DWORD i;
 BOOL Next;
 wchar_t szName[MAX_PATH];

 PROCESSENTRY32 p32 = {sizeof(p32)};
 hHandle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL); 
 Next = Process32First(hHandle, &p32);

 i = 0; 
 while (Next) 
 { 
  wsprintf(szName, L"%s", p32.szExeFile);
  if (lstrcmpi(szName, ProcessName) == 0)
  {
   return p32.th32ProcessID ;
  }
  Next = Process32Next(hHandle, &p32); 
  i++; 
 } 
 CloseHandle(hHandle); 
 return 0;
}

//
//获取用户sid
//
bool GetAccountSid(LPTSTR AccountName, PSID *Sid)
{
 PSID pSID = NULL;
 DWORD cbSid = 0;
 LPTSTR DomainName = NULL;
 DWORD cbDomainName = 0;
 SID_NAME_USE SIDNameUse;
 BOOL  bDone = FALSE;

 try
 {
  if(!LookupAccountName(NULL,
   AccountName,
   pSID,
   &cbSid,
   DomainName,
   &cbDomainName,
   &SIDNameUse))
  {
   pSID = (PSID)malloc(cbSid);
   DomainName = (LPTSTR)malloc(cbDomainName * sizeof(TCHAR));
   if(!pSID || !DomainName)
   {
    throw;
   }
   if(!LookupAccountName(NULL,
    AccountName,
    pSID,
    &cbSid,
    DomainName,
    &cbDomainName,
    &SIDNameUse))
   {
    throw;
   }
   bDone = TRUE;
  }
 }
 catch(...)
 {
  //nothing
 }

 if(DomainName)
 {
  free(DomainName);
 }
  
 if(!bDone && pSID)
 {
  free(pSID);
 }
 if(bDone)
 {
  *Sid = pSID;
 }

 return bDone;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值