INT_PTR ExcuteAsUser(TCHAR* szCmd)
{
BOOL bRet;
INT_PTR hr;
HANDLE processToken = NULL;
TOKEN_PRIVILEGES oldTokenPrivileges = { 0 };
TOKEN_PRIVILEGES oldTokenPrivileges = { 0 };
HANDLE impersonationToken = NULL;
HANDLE userToken = NULL;
HANDLE userToken = NULL;
LPVOID pEnvironment = NULL;
PROCESS_INFORMATION processInformation = { 0 };
PROCESS_INFORMATION processInformation = { 0 };
__try {
bRet = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &processToken);
if (!bRet) {
hr = GetLastError();
return hr;
}
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, SE_TCB_NAME, &luid);
if (!bRet) {
hr = GetLastError();
return hr;
}
LUID luid;
bRet = LookupPrivilegeValue(NULL, SE_TCB_NAME, &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;
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;
}
//WTSGetActiveConsoleSessionId, WTSQueryUserToken 함수를 Kernel32.dll에서 직접가져오는 이유는
//원래 함수가 XP이상 지원이라서..
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;
}
//WTSGetActiveConsoleSessionId, WTSQueryUserToken 함수를 Kernel32.dll에서 직접가져오는 이유는
//원래 함수가 XP이상 지원이라서..
HMODULE hInstKernel32 = NULL;
HMODULE hInstWtsapi32 = NULL;
HMODULE hInstWtsapi32 = NULL;
typedef DWORD (WINAPI *WTSGetActiveConsoleSessionIdPROC)();
WTSGetActiveConsoleSessionIdPROC WTSGetActiveConsoleSessionId = NULL;
WTSGetActiveConsoleSessionIdPROC WTSGetActiveConsoleSessionId = NULL;
hInstKernel32 = LoadLibrary("Kernel32.dll");
if (!hInstKernel32)
{
return -1;
}
if (!hInstKernel32)
{
return -1;
}
WTSGetActiveConsoleSessionId = (WTSGetActiveConsoleSessionIdPROC)GetProcAddress(hInstKernel32,"WTSGetActiveConsoleSessionId");
DWORD conSessId = WTSGetActiveConsoleSessionId();
if (conSessId == 0xFFFFFFFF) {
// There is no session attached to the console
return ERROR_SUCCESS;
}
typedef BOOL (WINAPI *WTSQueryUserTokenPROC)(ULONG SessionId, PHANDLE phToken );
WTSQueryUserTokenPROC WTSQueryUserToken = NULL;
hInstWtsapi32 = LoadLibrary("Wtsapi32.dll");
if (!hInstWtsapi32)
{
return -1;
}
{
return -1;
}
WTSQueryUserToken = (WTSQueryUserTokenPROC)GetProcAddress(hInstWtsapi32,"WTSQueryUserToken");
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;
}
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,
szCmd,
NULL,
NULL,
NULL,
FALSE,
CREATE_UNICODE_ENVIRONMENT,
pEnvironment,
NULL,
&si,
&processInformation
);
if (!bRet) {
hr = GetLastError();
return hr;
}
}
__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);
}
}
return 0;
}
si.cb = sizeof(STARTUPINFO);
si.lpDesktop = _T("winsta0\\default");
bRet = CreateEnvironmentBlock(&pEnvironment, userToken, TRUE);
if (!bRet) {
hr = GetLastError();
return hr;
}
bRet = CreateProcessAsUser(
userToken,
szCmd,
NULL,
NULL,
NULL,
FALSE,
CREATE_UNICODE_ENVIRONMENT,
pEnvironment,
NULL,
&si,
&processInformation
);
if (!bRet) {
hr = GetLastError();
return hr;
}
}
__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);
}
}
return 0;
}
댓글 없음:
댓글 쓰기