읽기 및 쓰기 위해 HKEY_CURRENT_USER 레지스트리에서 콘텐츠를 원하는, 그것은 서비스 프로그램에서 오류를 반환하지, 항상은 아니지만 작동합니다. 그 이유는 :
1.이 서비스는 오히려 어느 한 사용자보다 시스템 권한으로 실행
2.HKEY_CURRENT_USER 스토리지는 현재 사용자의 정보 ================> 사용자는 현재 서비스 데이터의 실제 작동 원인 HKEY_CURRENT_USER를 읽는에 기록되지 않습니다.
내가 HKEY_CURRENT_USER의 키를 조작하려는 경우 그래서, 읽을 현재 사용자를 시뮬레이션하는 것이 필요하다.
다음과 같이 인터넷은, 기록, 생각을 달성 할 수있는 방법을 찾기 위해 오랜 시간에 대한 정보를 찾을 수 있습니다
아이디어 : 현재의 thread가 로그온 한 사용자의 현재 보안 컨텍스트 시뮬레이션 할 수 있습니다. (부름에 스레드 가장 할을 할 수 있습니다 앳 보안 컨텍스트 사용자 (A)의 기록-ON). 사용 ImpersonateLoggedOnUser 기능을 수행 할 수 있습니다.
코드 :
보이드 윈도우 서비스 () { // 사용자 이름 TCHAR szUsername [MAX_PATH]; 플래그 BOOL = FALSE; HANDLE g_hToken = NULL; 하다 { 로거 ::의 getInstance은 () -> 정보 (__ FILE__, __LINE__는 "토큰을 얻기 위해 시작했다"); 플래그 INTER_GetExplorerToken을 (를 g_hToken) =; 경우 (플래그) { 로거 ::의 getInstance () -> 정보 (__ FILE__, __LINE__, "실패 토큰을 얻을"); 단절; } 그밖에 { 로거 ::의 getInstance () -> 정보 (__ FILE__, __LINE__, "토큰 성공을 얻을"); } //는 로그온 한 사용자의 보안 컨텍스트를 시뮬레이션 경우 (FALSE == ImpersonateLoggedOnUser (g_hToken)) { 단절; } DWORD dwUsernameLen = MAX_PATH; 경우 (FALSE == 때 getUserName (szUsername, dwUsernameLen)) 단절; //// 시뮬레이션은 원래의 보안 컨텍스트로 복귀하는 것을 잊지 마세요, 여기에 완료되었습니다 경우 (FALSE은 RevertToSelf == ()) 단절; } 동안 (FALSE); // 가져 오기 SID PSID PSID = NULL; LPWSTR은 SID; GetAccountSid (szUsername, PSID) //는 구조가 얻어지기 ConvertSidToStringSid (PSID, SID) 상기 구조체로부터 얻어진 SID // 문자열 wchar_t를 lswKeyPath [MAX_PATH] = {0}; StringCchPrintf (lswKeyPath, MAX_PATH, L "%의 LS \\ SOFTWARE \\ FatsClient"SID); LPCWSTR strSubKey = lswKeyPath; // _ T ( "SOFTWARE \\ FatsClient"); LPCWSTR strValueName = _T ( "경로"); 숯 strValue의 [256] = {0}; INT 길이 = 256; // 레지스트리를 읽고 부울 상태 QueryRegKey (strSubKey, strValueName strValue의, 길이) =; sprintf_s (BUF '경로 % = S, = LEN % D, 상태 = % d 개, SID = % LS "strValue의 길이, 상태 SID); 로거 ::의 getInstance () -> 정보 (__ FILE__, __LINE __, 버피); }
DWORD INTER_GetExplorerToken (pHandle에 phExplorerToken) { DWORD dwStatus = ERROR_FILE_NOT_FOUND; BOOL 브레 = FALSE; HANDLE hProcess = NULL; HANDLE hProcessSnap = NULL; 숯 szExplorerPath [MAX_PATH] = {0}; 숯 파일 이름 [MAX_PATH] = {0}; PROCESSENTRY32 PE32 = {0}; 시험 { hProcessSnap :: = 위해 CreateToolhelp32Snapshot (TH32CS_SNAPPROCESS, 0); 경우 (hProcessSnap == INVALID_HANDLE_VALUE) { 이 dwStatus을 GetLastError () =; } 그밖에 { pe32.dwSize =를 sizeof (PROCESSENTRY32); INT bMore :: = Process32First (hProcessSnap, PE32); 반면 (bMore) { (0 :: wcscmp (pe32.szExeFile, _T ( "explorer.exe를")) == 있으면) { hProcess :: = OpenProcess에 (PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID); 경우 (OpenProcessToken (hProcess, TOKEN_ALL_ACCESS, phExplorerToken)) { dwStatus = 0; } 그밖에 { 이 dwStatus을 GetLastError () =; } 단절; } bMore :: = Process32Next (hProcessSnap, PE32); } } } 캐치 (...) { } 경우 (hProcess) { 하여 CloseHandle (hProcess); } 경우 (hProcessSnap) { 하여 CloseHandle (hProcessSnap); } dwStatus를 반환; }
불리언 GetAccountSid (LPTSTR 계정 이름, PSID * SID) { PSID PSID = NULL; DWORD cbSid는 = 0; LPTSTR 도메인 이름 = NULL; DWORD cbDomainName는 = 0; SID_NAME_USE SIDNameUse; BOOL bDone = FALSE; 시험 { 만약 (! 중 LookupAccountName (NULL, 계정 이름, PSID, & cbSid, 도메인 이름, & cbDomainName, 및 SIDNameUse)) { PSID = (PSID)의 malloc (cbSid); 도메인 이름 = (LPTSTR)의 malloc (cbDomainName *를 sizeof (TCHAR)); 만약 (! PSID ||! 도메인 이름) { 던지다; } 만약 (! 중 LookupAccountName (NULL, 계정 이름, PSID, & cbSid, 도메인 이름, & cbDomainName, 및 SIDNameUse)) { 던지다; } bDone이 = TRUE; } } 캐치 (...) { //아무것도 } 경우 (도메인 이름) { 무료 (도메인 이름); } 만약 (! bDone && PSID) { 무료 (PSID); } 경우 (bDone) { * = PSID 시드; } bDone를 반환; }
불리언 QueryRegKey (LPCWSTR strSubKey, LPCWSTR strValueName, * CHAR strValue의, INT 길이) //이 세 매개 변수 전달 { DWORD dwType = REG_SZ // 정의 데이터 형식 DWORD dwLen = MAX_PATH; 데이터의 wchar_t [MAX_PATH] = {0}; HKEY HKEY; 긴 ERR = ERROR_SUCCESS; // HKEY_CURRENT_USER KEY_READ ERR == RegOpenKeyEx (HKEY_USERS, strSubKey, 0, KEY_READ, HKEY); 경우 (ERR == ERROR_SUCCESS) { 숯 bufLog [128] = {0}; 로거 ::의 getInstance () -> 정보 (__ FILE__, __LINE__, "RegOpenKeyEx 성공"); 긴 errRet = RegQueryValueEx (HKEY, _T ( "경로"), NULL, dwType (LPBYTE) 데이터, dwLen); 경우 (ERROR_SUCCESS == errRet) { wcharTochar (데이터 strValue의 길이); // wprintf (L "데이터 = %의 LS 렌 % D = \ n", 데이터 나 strlen ((CONST * CHAR) 데이터)); sprintf_s (bufLog "RegQueryValueEx : 데이터 = %의 LS, 렌 = % d의"데이터 나 strlen ((CONST * CHAR) 데이터)); 로거 ::의 getInstance () -> 정보 (__ FILE__, __LINE__, bufLog); sprintf_s (bufLog "RegQueryValueEx : % S = strValue의 길이 = % D"strValue의 길이); 로거 ::의 getInstance () -> 정보 (__ FILE__, __LINE__, bufLog); 을 RegCloseKey (HKEY); // 닫기 레지스트리 true를 반환; } 그밖에 { 숯 bufLog [128] = {0}; sprintf_s (bufLog "RegQueryValueEx 실패 : RET = % D"errRet); 로거 ::의 getInstance () -> 정보 (__ FILE__, __LINE__, bufLog); } 을 RegCloseKey (HKEY); // 닫기 레지스트리 } 그밖에 { 숯 bufLog [128] = {0}; sprintf_s (bufLog "RegOpenKeyEx : strSubKey = % LS 렌 = % LD"strSubKey, ERR); 로거 ::의 getInstance은 () -> 정보는 (__ FILE__는, __LINE__, "RegOpenKeyEx successOpenRegKey 반환은 false입니다!"); } false를 반환; }
所 需要 的 头 文件합니다 : #include <iostream> #INCLUDE <assert.h를> 사용법 #include "WINDOWS.H"사용법 #include "tchar.h"사용법 #include "conio.h와"사용법 #include "STDIO.H"#INCLUDE <strsafe .H> 사용법 #include <sddl.h> 사용법 #include "tlhelp32.h"사용법 #include <atlstr.h>