標籤:dir ack variable lld tail 擷取 seh read 複製
首先,對“活動使用者”的定義是,當前擁有案頭的使用者。對於Windows XP及其以後的系統,即使是可以多個使用者同時登入了,擁有案頭的也僅僅只有一個。
如果系統級服務調用Windows API來擷取註冊表索引值的時候,直接以HKEY_CURRENT_USER為參數,則取到的並不是活動使用者的註冊表資訊,而是系統使用者的註冊表資訊,即,位於HKEY_LOCAL_MACHINE之下的。那麼如何以系統服務的身份擷取活動使用者(真正的HKEY_CURRENT_USER)之下的註冊表資訊呢?主要有以下這麼幾步:
- 系統服務程式調用 WTSGetActiveConsoleSessionId() 以擷取當前活動使用者的sessionId.
- 以此sessionId為參數,調用 WTSQueryUserToken() 以擷取當前活動使用者的 hUserToken.
- 以此hUserToken為參數,調用 DuplicateTokenEx() 以複製一個token,如hFakeToken.
- 以此hFakeToken為參數,調用 ImpersonateLoggedOnUser() 以類比活動使用者登入的環境.
- 調用 RegOpenCurrentUser() 以開啟活動使用者的 HKEY_CURRENT_USER.
- 調用 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)