- lumenFC 축구 동호회
- 마샤블
- 웍스프레소
- 소셜@나눔<소셜미디어나눔연구소>
- 리버스코어
- LAIN
- LAIN 이사한 블로그
- TeamCR@K
- Sunnyday
- 보안 걱정이
- 리버싱 학습
- securityfirst_jo
- Practical Security Blog
- 세상, 그 유쾌한 전장
- 악성코드관련블로그
- Back to the Mac
- 패킷분석입문
- PacketInside / 네트워크 패킷 분석 블로그
- 침해사고분석 :: 네이버 블로그
- 소프트웨어 기술자경력관리시스템
- JK.Moon
- 자바 온라인학습
- Ezbeat의 도서관
- Dreams of a Final Journey
- IT eBooks - Free Download - Bi…
- Index of /madchat/coding/rever…
- Security Insight
- Reversing war game
- 고길고기
- clamav
- zerowine
- FORENSIC-PROOOF
- jquery 예제
- 조대협의블로그
- 국가과학기술인력개발원 교육포털 사이트
- 빅데이터, splunk
- 지식을 연주하는 사람
- malware analysis system
- 건국대토익스피킹
- 소프트웨어개발 및 협업도구
kisoo
SERVICE PROCESS 에서 HKEY_CURRENT_USER 키 값을 QUERY 하는 방법 본문
SERVICE PROCESS 에서 HKEY_CURRENT_USER 키 값을 QUERY 하는 방법
JamesK78 2009. 7. 6. 17:47SERVICE PROCESS 에서 HKEY_CURRENT_USER 을 OPEN 하면 FAILED 가 발생 했다.
NT 이상 VISTA 까지 이 부분을 아래와 같이 처리 하였더니 되더라~~~방법은 CURRENT USER PROCESS 의
SID 값이다.
소스
우선 아래와 같이 현재 user 의 session id 를 통해서 user process 의 pid 를 구해야 한다.
user process 중에 항상 뜨는 프로세스가 무엇이 있을까>????
바로 explorer.exe 이다.
이 프로세스의 pid 를 통해서 SID 값을 구하여 레지스트리에 접근 하면 QUERY 가 가능하다.
@desc : vista / xp / nt 이상의 os 에서 service process 가 HKEY_CURRENT_USERS
키에 접근 할 수 없기 때문에 USER PROCESS 의 PID 로 SID 값을 구하여
HKEY_USERS 에 접근 하여 값을 가져 온다.
여기서 session 의 process id 는 user process 이어야 하므로 explorer.exe 의
pid 를 구해서 openprocess 한다.
CString CSafeHWCtrlImpl::GetUserSid()
{
CString strErr = _T("");
HINSTANCE hInst;
DWORD dwSessionId;
hInst = LoadLibrary("Kernel32.dll");
pActiveSessionId = (DWORD(__stdcall *)())::GetProcAddress(hInst, "WTSGetActiveConsoleSessionId");
dwSessionId = pActiveSessionId();
DWORD dwProcessID;
PROCESSENTRY32 procEntry;
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnap == INVALID_HANDLE_VALUE)
{
strErr.Format("ERROR hSnap Invalid Handle ErrCode %d",GetLastError());
return strErr;
}
procEntry.dwSize = sizeof(PROCESSENTRY32);
if (!Process32First(hSnap, &procEntry))
{
strErr.Format("ERROR Process32First False ErrCode %d",GetLastError());
return strErr;
}
do
{
if (_stricmp(procEntry.szExeFile, "explorer.exe") == 0)
{
//---------------------------------------------------------------------------------
// 현재 세션에서 동작 하는 explorer.exe process 를 찾았으므로 process id 를 구한다.
//---------------------------------------------------------------------------------
DWORD winlogonSessId = 0;
if (ProcessIdToSessionId(procEntry.th32ProcessID, &winlogonSessId) && winlogonSessId == dwSessionId)
{
dwProcessID = procEntry.th32ProcessID;
break;
}
}
} while (Process32Next(hSnap, &procEntry));
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ , FALSE, dwProcessID);
//---------------------------------------------------
// Process Handle이 NULL이면, Open Failed 에러
//---------------------------------------------------
if (hProcess == NULL)
{
strErr.Format("ERROR_OPEN PROCESS FAILED 1");
return strErr;
}
//-------------------------------------------------------------------------------------------
// 프로세서의 실행자 SID를 찾는다.
// 서비스 프로그램은 Local System 계정으로 로그인하였으므로, HKEY_CURRENT_USER로 레지스트리를
// Open할 경우 Application 와 다른 레지스트리 키로 접근이 된다.
// 그러므로, Process Token에서, SID를 확보해서 레지스트리를 직접 찾아 가야 한다.
//-------------------------------------------------------------------------------------------
HANDLE hTProcess;
DWORD dwSize;
//-------------------------------------------------------------------------------------------
// Process 핸들로 토큰을 얻는다.
//-------------------------------------------------------------------------------------------
if (OpenProcessToken(hProcess, TOKEN_QUERY, &hTProcess) == FALSE)
{
CloseHandle(hProcess);
strErr.Format("ERROR_OPEN TOKEN FAILED 2 ");
return strErr;
}
//-------------------------------------------------------------------------------------------
// 토큰 정보가 저장될 버퍼의 크기를 받아온다.
//-------------------------------------------------------------------------------------------
GetTokenInformation(hTProcess, TokenUser, NULL, 0, &dwSize);
TOKEN_USER *sidUser = (TOKEN_USER *)malloc(dwSize);
if (GetTokenInformation(hTProcess, TokenUser, sidUser, dwSize, &dwSize) == 0)
{
free(sidUser);
CloseHandle(hTProcess);
CloseHandle(hProcess);
strErr.Format("ERROR %d",GetLastError());
return strErr;
}
//----------------------------------------------------
// STRING SID로 변경한다.
//----------------------------------------------------
LPTSTR pszSid;
ConvertSidToStringSid(sidUser[0].User.Sid, &pszSid);
free(sidUser);
CloseHandle(hTProcess);
//----------------------------------------------------
// 문자열 더하고 빼고 등등 파싱을 할때
// 좀더 쉽게 프로그램 하려고, CString으로 변환 하였음.
//----------------------------------------------------
CString strUserSID = pszSid;
LocalFree(pszSid);
//----------------------------------------------------
// 레지스트리 오픈
//----------------------------------------------------
HKEY hKey = NULL;
LONG lRet = 0;
// HKEY_CURRENT_USER\\Software의 레지스트리 키 오픈
strUserSID +="\\";
strUserSID +=VOLUME_REGISTRY_PATH;
return strUserSID;
}
....THREAD 에서 아래와 같이 해주면 된다.
strUserSID = pSafeInstance->GetUserSid();
if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_USERS, strUserSID, 0, KEY_ALL_ACCESS, &hKey))
{
bRunning = FALSE;
}
else
{
bRunning = TRUE;
bStatus = FALSE;
if(hKey != NULL)
RegCloseKey(hKey);
break;
}
....쿼리 하고 싶은 키를 쿼리 하면 된다.....코드 생략