從Windows系統服務擷取活動使用者的註冊表資訊(當前活動使用者的sessionId. 當前活動使用者的 hUserToken)

來源:互聯網
上載者:User

標籤:dir   ack   variable   lld   tail   擷取   seh   read   複製   

首先,對“活動使用者”的定義是,當前擁有案頭的使用者。對於Windows XP及其以後的系統,即使是可以多個使用者同時登入了,擁有案頭的也僅僅只有一個。 
如果系統級服務調用Windows API來擷取註冊表索引值的時候,直接以HKEY_CURRENT_USER為參數,則取到的並不是活動使用者的註冊表資訊,而是系統使用者的註冊表資訊,即,位於HKEY_LOCAL_MACHINE之下的。那麼如何以系統服務的身份擷取活動使用者(真正的HKEY_CURRENT_USER)之下的註冊表資訊呢?主要有以下這麼幾步:

  1. 系統服務程式調用 WTSGetActiveConsoleSessionId() 以擷取當前活動使用者的sessionId.
  2. 以此sessionId為參數,調用 WTSQueryUserToken() 以擷取當前活動使用者的 hUserToken.
  3. 以此hUserToken為參數,調用 DuplicateTokenEx() 以複製一個token,如hFakeToken.
  4. 以此hFakeToken為參數,調用 ImpersonateLoggedOnUser() 以類比活動使用者登入的環境.
  5. 調用 RegOpenCurrentUser() 以開啟活動使用者的 HKEY_CURRENT_USER.
  6. 調用 RegOpenKeyEx() 以擷取指定位置的註冊表索引值.

以QT和Windows API來實現的代碼如下:

void GetUserRegistryFromSystemService(){#ifdef Q_OS_WIN    DWORD sessionId = WTSGetActiveConsoleSessionId();    qInfo() << "Session ID = " << sessionId;    wchar_t * ppUserName[100];    DWORD sizeOfUserName;    WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, sessionId, WTSUserName, ppUserName, &sizeOfUserName);    qInfo() << "Windows User Name = " << QString::fromWCharArray(*ppUserName);    std::wstring strValueOfBinDir = L"Unknown Value";    LONG regOpenResult = ERROR_SUCCESS;    HANDLE hUserToken = NULL;    HANDLE hFakeToken = NULL;    if (WTSQueryUserToken(sessionId, &hUserToken))    {         if (DuplicateTokenEx(hUserToken, TOKEN_ASSIGN_PRIMARY | TOKEN_ALL_ACCESS, 0, SecurityImpersonation, TokenPrimary, &hFakeToken) == TRUE)         {            if (ImpersonateLoggedOnUser(hFakeToken))            {                HKEY hKey;                regOpenResult = RegOpenCurrentUser(KEY_READ, &hKey);                if (regOpenResult != ERROR_SUCCESS)                {                    qCritical() << "Failed to call RegOpenCurrentUser(), Error is " << regOpenResult;                }                HKEY hSubKey;                RegOpenKeyEx(hKey,                             TEXT("Software\\Baidu\\BaiduYunGuanjia"),                             0,                             KEY_READ,                             &hSubKey);                GetStringRegKey(hSubKey, TEXT("installDir"), strValueOfBinDir, TEXT("Unknown"));                RevertToSelf();            }            else            {                qCritical() << "Failed to ImpersonateLoggedOnUser...";            }            CloseHandle(hFakeToken);        }        else        {            qCritical() << "Failed to call DuplicateTokenEx...";        }        CloseHandle(hUserToken);    }    else    {        qCritical() << "Failed to get the user token of session " << sessionId;    }    qInfo() << "The value of Registry is " << QString::fromWCharArray( strValueOfBinDir.c_str() );#endif}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64

最後,取註冊表資訊一些方法:

HKEY hKey;LONG lRes = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Perl", 0, KEY_READ, &hKey);bool bExistsAndSuccess (lRes == ERROR_SUCCESS);bool bDoesNotExistsSpecifically (lRes == ERROR_FILE_NOT_FOUND);std::wstring strValueOfBinDir;std::wstring strKeyDefaultValue;GetStringRegKey(hKey, L"BinDir", strValueOfBinDir, L"bad");GetStringRegKey(hKey, L"", strKeyDefaultValue, L"bad");LONG GetStringRegKey(HKEY hKey, const std::wstring &strValueName, std::wstring &strValue, const std::wstring &strDefaultValue){    strValue = strDefaultValue;    WCHAR szBuffer[512];    DWORD dwBufferSize = sizeof(szBuffer);    ULONG nError;    nError = RegQueryValueExW(hKey, strValueName.c_str(), 0, NULL, (LPBYTE)szBuffer, &dwBufferSize);    if (ERROR_SUCCESS == nError)    {        strValue = szBuffer;    }    return nError;}LONG GetDWORDRegKey(HKEY hKey, const std::wstring &strValueName, DWORD &nValue, DWORD nDefaultValue){    nValue = nDefaultValue;    DWORD dwBufferSize(sizeof(DWORD));    DWORD nResult(0);    LONG nError = ::RegQueryValueExW(hKey,        strValueName.c_str(),        0,        NULL,        reinterpret_cast<LPBYTE>(&nResult),        &dwBufferSize);    if (ERROR_SUCCESS == nError)    {        nValue = nResult;    }    return nError;}LONG GetBoolRegKey(HKEY hKey, const std::wstring &strValueName, bool &bValue, bool bDefaultValue){    DWORD nDefValue((bDefaultValue) ? 1 : 0);    DWORD nResult(nDefValue);    LONG nError = GetDWORDRegKey(hKey, strValueName.c_str(), nResult, nDefValue);    if (ERROR_SUCCESS == nError)    {        bValue = (nResult != 0) ? true : false;    }    return nError;}

 

http://blog.csdn.net/nirendao/article/details/52077637

 

從Windows系統服務擷取活動使用者的註冊表資訊(當前活動使用者的sessionId. 當前活動使用者的 hUserToken)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.