系统权限进程读取用户注册表
system权限的进程、服务若要操作用户注册表(HKEY_CURRENT_USER),如果直接操作则获取的内容不是真正想要获取的内容,因为路径被重定向的,所以要从HKEY_USERS中来操作。
首先获取用户SID,然后再将该SID与要操作的注册表项拼接在一起,就可以操作HKEY_CURRENT_USER中的项了
//这个函数的的代码不美观哈
BOOL GetTokenByName(HANDLE &hToken,LPTSTR lpName)
{
if (!lpName)
return FALSE;
HANDLE hProcessSnap = NULL;
BOOL bRet = FALSE;
PROCESSENTRY32 pe32 = {0};
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, );
if (hProcessSnap == INVALID_HANDLE_VALUE)
return (FALSE);
pe32.dwSize = sizeof(PROCESSENTRY32);
if (Process32First(hProcessSnap, &pe32))
{
do
{
if(!_tcscmp(_tcsupr(pe32.szExeFile),_tcsupr(lpName)))
{
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION,FALSE,pe32.th32ProcessID);
bRet = OpenProcessToken(hProcess,TOKEN_ALL_ACCESS,&hToken);
CloseHandle (hProcess);
CloseHandle (hProcessSnap);
return (bRet);
}
}
while (Process32Next(hProcessSnap, &pe32));
bRet = FALSE;
}
else
{
bRet = FALSE;
}
CloseHandle (hProcessSnap);
return (bRet);
}
//
//获取用户sid
//
bool GetAccountSid(LPTSTR AccountName, PSID *Sid)
{
PSID pSID = NULL;
DWORD cbSid = ;
LPTSTR DomainName = NULL;
DWORD cbDomainName = ;
SID_NAME_USE SIDNameUse;
BOOL bDone = FALSE;
do
{
if(LookupAccountName(NULL,
AccountName,
pSID,
&cbSid,
DomainName,
&cbDomainName,
&SIDNameUse))
{
bDone = TRUE;
break;
}
pSID = (PSID)malloc(cbSid);
DomainName = (LPTSTR)malloc(cbDomainName * sizeof(TCHAR));
if(!pSID || !DomainName)
{
printf("malloc error\n");
break;
}
if(!LookupAccountName(NULL,
AccountName,
pSID,
&cbSid,
DomainName,
&cbDomainName,
&SIDNameUse))
{
printf("LookupAccountName error code:%d\n",GetLastError());
break;
}
bDone = TRUE;
}while(FALSE);
if(DomainName)
{
free(DomainName);
DomainName = NULL;
}
if(!bDone && pSID)
{
free(pSID);
pSID = NULL;
}
if(bDone)
{
*Sid = pSID;
}
return bDone;
}
//修改注册表
void WriteReg()
{
HANDLE hToken = NULL;
do
{
if (!GetTokenByName(hToken,_T("EXPLORER.EXE")))
{
printf("GetTokenByName error\n");
break;
}
// 模拟登录用户的安全上下文
if(FALSE == ImpersonateLoggedOnUser(hToken))
{
printf("ImpersonateLoggedOnUser error\n");
break;
}
// 获取用户名
TCHAR szUsername[MAX_PATH];
DWORD dwUsernameLen = MAX_PATH;
if(FALSE == GetUserName(szUsername, &dwUsernameLen))
break;
// 到这里已经模拟完了,别忘记返回原来的安全上下文
if(FALSE == RevertToSelf())
break;
// 获取sid
PSID pSid = NULL;
LPWSTR sid;
BOOL ret = GetAccountSid(szUsername, &pSid); //获取得到的是一个结构体
if (!ret)
{
printf("GetAccountSid fail\n");
break;
}
ret = ConvertSidToStringSid(pSid, &sid); //从结构体中得到sid串
if (!ret)
{
printf("ConvertSidToStringSid fail code %d\n",GetLastError());
break;
}
/*
这里就可以操作CURRENT_USER中的注册表项了
将用户的SID与要操作的注册表项拼接在一起就可以操作了
*/
} while (false);
if(hToken)
{
CloseHandle(hToken);
hToken = NULL;
}
if (pSid)
{
free(pSid);
pSid = NULL;
}
}