SYSTEM權限的進程操作HKEY_CURRENT_USER註冊表

系統權限進程讀取用戶註冊表

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

參考:https://www.bbsmax.com/A/MAzAbMoyJ9/

https://blog.csdn.net/ly402609921/article/details/9127959

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章