CreateProcessAsUser를 사용해서 해당 유저권한으로 프로세스를 실행시키고 싶은데 자꾸 SYSTEM으로 올라와서 정리.
작업했던 내용은 Service에서 사용하고 싶은 것이었는데......
찾은 몇가지 코드들은 여전히 SYSTEM으로 올라와서 찾다가
Service에서 실행되는 코드 발견..
둘의 차이가 뭔지 좀 보려고 우선 올려둠..
언젠간 보겠지.. (먼산)
# 응용 프로그램 코드
BOOL LaunchAppIntoDifferentSession(TCHAR* lpszProcessName, TCHAR* lpszCommendLine)
{
PROCESS_INFORMATION pi;
STARTUPINFO si;
BOOL bResult = FALSE;
DWORD dwSessionId, winlogonPid;
HANDLE hUserToken, hUserTokenDup, hPToken, hProcess;
DWORD dwCreationFlags;
// Log the client on to the local computer.
dwSessionId = WTSGetActiveConsoleSessionId();
//////////////////////////////////////////
// Find the winlogon process
////////////////////////////////////////
PROCESSENTRY32 procEntry;
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnap == INVALID_HANDLE_VALUE)
{
return 1;
}
procEntry.dwSize = sizeof(PROCESSENTRY32);
if (!Process32First(hSnap, &procEntry))
{
return 1;
}
do
{
if (_tcsicmp(procEntry.szExeFile, _T("winlogon.exe")) == 0)
{
// We found a winlogon process...
// make sure it's running in the console session
DWORD winlogonSessId = 0;
if (ProcessIdToSessionId(procEntry.th32ProcessID, &winlogonSessId)
&& winlogonSessId == dwSessionId)
{
winlogonPid = procEntry.th32ProcessID;
break;
}
}
} while (Process32Next(hSnap, &procEntry));
////////////////////////////////////////////////////////////////////////
WTSQueryUserToken(dwSessionId, &hUserToken);
dwCreationFlags = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE;
ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
si.lpDesktop = _T("winsta0\\default");
si.wShowWindow = SW_HIDE;
ZeroMemory(&pi, sizeof(pi));
TOKEN_PRIVILEGES tp;
LUID luid;
hProcess = OpenProcess(MAXIMUM_ALLOWED, FALSE, winlogonPid);
if (!::OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY
| TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY | TOKEN_ADJUST_SESSIONID
| TOKEN_READ | TOKEN_WRITE, &hPToken))
{
int abcd = GetLastError();
printf("Process token open Error: %u\n", GetLastError());
}
if (!LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &luid))
{
printf("Lookup Privilege value Error: %u\n", GetLastError());
}
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
DuplicateTokenEx(hPToken, MAXIMUM_ALLOWED, NULL,
SecurityIdentification, TokenPrimary, &hUserTokenDup);
int dup = GetLastError();
//Adjust Token privilege
SetTokenInformation(hUserTokenDup,
TokenSessionId, (void*)dwSessionId, sizeof(DWORD));
if (!AdjustTokenPrivileges(hUserTokenDup, FALSE, &tp, sizeof(TOKEN_PRIVILEGES),
(PTOKEN_PRIVILEGES)NULL, NULL))
{
int abc = GetLastError();
printf("Adjust Privilege value Error: %u\n", GetLastError());
}
if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
{
printf("Token does not have the provilege\n");
}
LPVOID pEnv = NULL;
if (CreateEnvironmentBlock(&pEnv, hUserTokenDup, TRUE))
{
dwCreationFlags |= CREATE_UNICODE_ENVIRONMENT;
}
else
pEnv = NULL;
// Launch the process in the client's logon session.
bResult = CreateProcessAsUser(
hUserTokenDup, // client's access token
lpszProcessName, // file to execute
lpszCommendLine, // command line
NULL, // pointer to process SECURITY_ATTRIBUTES
NULL, // pointer to thread SECURITY_ATTRIBUTES
FALSE, // handles are not inheritable
dwCreationFlags, // creation flags
pEnv, // pointer to new environment block
NULL, // name of current directory
&si, // pointer to STARTUPINFO structure
&pi // receives information about new process
);
// End impersonation of client.
//GetLastError Shud be 0
int iResultOfCreateProcessAsUser = GetLastError();
//Perform All the Close Handles tasks
CloseHandle(hProcess);
CloseHandle(hUserToken);
CloseHandle(hUserTokenDup);
CloseHandle(hPToken);
return 0;
}
# Service 에서의 코드
HRESULT RunAsInteractiveUser(TCHAR* lpszProcessName, TCHAR* lpszCommendLine)
{
BOOL bRet;
HRESULT hr;
HANDLE processToken = NULL;
TOKEN_PRIVILEGES oldTokenPrivileges = { 0 };
HANDLE impersonationToken = NULL;
HANDLE userToken = NULL;
LPVOID pEnvironment = NULL;
PROCESS_INFORMATION processInformation = { 0 };
__try {
bRet = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &processToken);
if (!bRet) {
hr = GetLastError();
return hr;
}
// This step might not be necessary because SeTcbPrivilege is enabled by default for Local System
LUID luid;
bRet = LookupPrivilegeValue(NULL, _T("SeTcbPrivilege"), &luid);
if (!bRet) {
hr = GetLastError();
return hr;
}
TOKEN_PRIVILEGES adjTokenPrivileges = { 0 };
adjTokenPrivileges.PrivilegeCount = 1;
adjTokenPrivileges.Privileges[0].Luid = luid;
adjTokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
DWORD dwOldTPLen;
bRet = AdjustTokenPrivileges(processToken, FALSE, &adjTokenPrivileges, sizeof(TOKEN_PRIVILEGES), &oldTokenPrivileges, &dwOldTPLen);
if (bRet) {
hr = GetLastError();
if (hr == ERROR_SUCCESS);
else if (hr == ERROR_NOT_ALL_ASSIGNED) {
// Enabled by default
}
}
else {
hr = GetLastError();
return hr;
}
DWORD conSessId = WTSGetActiveConsoleSessionId();
if (conSessId == 0xFFFFFFFF) {
// There is no session attached to the console
return ERROR_SUCCESS;
}
bRet = WTSQueryUserToken(conSessId, &impersonationToken);
if (!bRet) {
hr = GetLastError();
return hr;
}
bRet = DuplicateTokenEx(impersonationToken, MAXIMUM_ALLOWED, NULL, SecurityIdentification, TokenPrimary, &userToken);
if (!bRet) {
hr = GetLastError();
return hr;
}
STARTUPINFO si = { 0 };
si.cb = sizeof(STARTUPINFO);
si.lpDesktop = _T("winsta0\\default");
bRet = CreateEnvironmentBlock(&pEnvironment, userToken, TRUE);
if (!bRet) {
hr = GetLastError();
return hr;
}
bRet = CreateProcessAsUser(userToken, lpszProcessName,
lpszCommendLine, NULL, NULL, FALSE, CREATE_UNICODE_ENVIRONMENT,
pEnvironment, NULL, &si, &processInformation);
if (!bRet) {
hr = GetLastError();
return hr;
}
else
{
bRet = WaitForSingleObject(processInformation.hProcess, INFINITE);
DWORD retVal = NULL;
GetExitCodeProcess(processInformation.hProcess, &retVal);
if (1 == (int)retVal)
{
return ERROR_SUCCESS;
}
return E_FAIL;
}
}
__finally {
if (processInformation.hThread) {
CloseHandle(processInformation.hThread);
}
if (processInformation.hProcess) {
CloseHandle(processInformation.hProcess);
}
if (pEnvironment) {
bRet = DestroyEnvironmentBlock(pEnvironment);
}
if (userToken) {
CloseHandle(userToken);
}
if (impersonationToken) {
CloseHandle(impersonationToken);
}
if (processToken) {
bRet = AdjustTokenPrivileges(processToken, FALSE, &oldTokenPrivileges, sizeof(TOKEN_PRIVILEGES), NULL, NULL);
CloseHandle(processToken);
}
}
}
'Programmer의 텅빈 공간 > C/C++' 카테고리의 다른 글
VS 2013 확장 기능 (0) | 2016.04.22 |
---|---|
visual studio 단축키 정리 (0) | 2015.08.04 |
singleton (0) | 2014.05.06 |
non-mfc에서 TRACE, ASSERT 사용 (0) | 2014.05.06 |
메모리 풀을 왜 사용해야 하는가 ? (0) | 2014.05.06 |