系統權限進程讀取用戶註冊表
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;
}
}