mirror of https://github.com/BOINC/boinc.git
- WINSETUP: Copy the explorer primary token to get processes launched by the setup
process to launch with reduced permissions. win_build/installerv2/redist/Windows/src/boinccas/ boinccas.vcproj CALaunchBOINCManager.cpp launcher.cpp, .h win_build/installerv2/redist/Windows/Win32/ boinccas.dll boinccas95.dll win_build/installerv2/redist/Windows/x64/ boinccas.dll boinccas95.dll svn path=/trunk/boinc/; revision=24826
This commit is contained in:
parent
36ef681e28
commit
9d0553f7ea
|
@ -9130,3 +9130,18 @@ Rom 19 Dec 2011
|
|||
samples/vboxwrapper/
|
||||
vboxwrapper.cpp
|
||||
vbox.cpp, .h
|
||||
|
||||
Rom 19 Dec 2011
|
||||
- WINSETUP: Copy the explorer primary token to get processes launched by the setup
|
||||
process to launch with reduced permissions.
|
||||
|
||||
win_build/installerv2/redist/Windows/src/boinccas/
|
||||
boinccas.vcproj
|
||||
CALaunchBOINCManager.cpp
|
||||
launcher.cpp, .h
|
||||
win_build/installerv2/redist/Windows/Win32/
|
||||
boinccas.dll
|
||||
boinccas95.dll
|
||||
win_build/installerv2/redist/Windows/x64/
|
||||
boinccas.dll
|
||||
boinccas95.dll
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -20,28 +20,12 @@
|
|||
|
||||
#include "stdafx.h"
|
||||
#include "boinccas.h"
|
||||
#include "launcher.h"
|
||||
#include "CALaunchBOINCManager.h"
|
||||
|
||||
#define CUSTOMACTION_NAME _T("CALaunchBOINCManager")
|
||||
#define CUSTOMACTION_PROGRESSTITLE _T("Launching BOINC Manager")
|
||||
|
||||
#ifndef SECURITY_MANDATORY_LABEL_AUTHORITY
|
||||
|
||||
#define SECURITY_MANDATORY_LABEL_AUTHORITY {0,0,0,0,0,16}
|
||||
#define SECURITY_MANDATORY_MEDIUM_RID (0x00002000L)
|
||||
#define SE_GROUP_INTEGRITY (0x00000020L)
|
||||
|
||||
typedef struct _TOKEN_MANDATORY_LABEL {
|
||||
SID_AND_ATTRIBUTES Label;
|
||||
} TOKEN_MANDATORY_LABEL, *PTOKEN_MANDATORY_LABEL;
|
||||
|
||||
typedef enum MY_TOKEN_INFORMATION_CLASS {
|
||||
TokenVirtualizationEnabled = 24,
|
||||
TokenIntegrityLevel = 25
|
||||
} MY_TOKEN_INFORMATION_CLASS, *PMY_TOKEN_INFORMATION_CLASS;
|
||||
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function:
|
||||
|
@ -75,141 +59,29 @@ CALaunchBOINCManager::~CALaunchBOINCManager()
|
|||
//
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef BOOL (__stdcall *tSCREATEL)( IN DWORD, IN DWORD, IN DWORD, OUT SAFER_LEVEL_HANDLE*, OUT LPVOID );
|
||||
typedef BOOL (__stdcall *tSCTFL)( IN SAFER_LEVEL_HANDLE, IN HANDLE, OUT HANDLE*, IN DWORD, OUT LPVOID );
|
||||
typedef BOOL (__stdcall *tSCLOSEL)( IN SAFER_LEVEL_HANDLE );
|
||||
|
||||
UINT CALaunchBOINCManager::OnExecution()
|
||||
{
|
||||
static HMODULE advapi32lib = NULL;
|
||||
static tSCREATEL pSCREATEL = NULL;
|
||||
static tSCTFL pSCTFL = NULL;
|
||||
static tSCLOSEL pSCLOSEL = NULL;
|
||||
PROCESS_INFORMATION process_info;
|
||||
STARTUPINFO startup_info;
|
||||
SAFER_LEVEL_HANDLE hSaferHandle;
|
||||
HANDLE hRestrictedToken;
|
||||
SID_IDENTIFIER_AUTHORITY siaMLA = SECURITY_MANDATORY_LABEL_AUTHORITY;
|
||||
PSID pSidMedium = NULL;
|
||||
TOKEN_MANDATORY_LABEL TIL = {0};
|
||||
DWORD dwEnableVirtualization = 1;
|
||||
tstring strInstallDirectory;
|
||||
tstring strBuffer;
|
||||
UINT uiReturnValue = -1;
|
||||
FILE* f;
|
||||
|
||||
memset(&process_info, 0, sizeof(process_info));
|
||||
memset(&startup_info, 0, sizeof(startup_info));
|
||||
startup_info.cb = sizeof(startup_info);
|
||||
startup_info.dwFlags = STARTF_USESHOWWINDOW;
|
||||
startup_info.wShowWindow = SW_SHOW;
|
||||
|
||||
f = fopen("LaunchManager.txt", "w");
|
||||
|
||||
if (!advapi32lib) {
|
||||
advapi32lib = LoadLibraryA("advapi32.dll");
|
||||
if (advapi32lib) {
|
||||
pSCREATEL = (tSCREATEL)GetProcAddress(advapi32lib, "SaferCreateLevel");
|
||||
pSCTFL = (tSCTFL)GetProcAddress(advapi32lib, "SaferComputeTokenFromLevel");
|
||||
pSCLOSEL = (tSCLOSEL)GetProcAddress(advapi32lib, "SaferCloseLevel");
|
||||
}
|
||||
}
|
||||
|
||||
if (!pSCREATEL || !pSCTFL || !pSCLOSEL) {
|
||||
return ERROR_FILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
uiReturnValue = GetProperty( _T("INSTALLDIR"), strInstallDirectory );
|
||||
if ( uiReturnValue ) return uiReturnValue;
|
||||
|
||||
|
||||
// Calculate a restricted token from the current token.
|
||||
if (!pSCREATEL( SAFER_SCOPEID_USER, SAFER_LEVELID_NORMALUSER, SAFER_LEVEL_OPEN, &hSaferHandle, NULL ))
|
||||
{
|
||||
fwprintf(f, _T("SaferCreateLevel retval: '%d'\n"), GetLastError());
|
||||
}
|
||||
|
||||
if (!pSCTFL( hSaferHandle, NULL, &hRestrictedToken, NULL, NULL ))
|
||||
{
|
||||
fwprintf(f, _T("SaferComputeTokenFromLevel retval: '%d'\n"), GetLastError());
|
||||
}
|
||||
|
||||
AllocateAndInitializeSid(&siaMLA, 1, SECURITY_MANDATORY_MEDIUM_RID, 0, 0, 0, 0, 0, 0, 0, &pSidMedium);
|
||||
|
||||
TIL.Label.Attributes = SE_GROUP_INTEGRITY;
|
||||
TIL.Label.Sid = pSidMedium;
|
||||
|
||||
if (!SetTokenInformation(hRestrictedToken, (TOKEN_INFORMATION_CLASS)TokenIntegrityLevel, &TIL, sizeof(TOKEN_MANDATORY_LABEL)))
|
||||
{
|
||||
fwprintf(f, _T("SaferComputeTokenFromLevel (TokenIntegrityLevel) retval: '%d'\n"), GetLastError());
|
||||
}
|
||||
|
||||
if (!SetTokenInformation(hRestrictedToken, (TOKEN_INFORMATION_CLASS)TokenVirtualizationEnabled, &dwEnableVirtualization, sizeof(DWORD)))
|
||||
{
|
||||
fwprintf(f, _T("SaferComputeTokenFromLevel (TokenVirtualizationEnabled) retval: '%d'\n"), GetLastError());
|
||||
}
|
||||
|
||||
|
||||
strBuffer = tstring(_T("\"")) + strInstallDirectory + tstring(_T("boincmgr.exe\""));
|
||||
fwprintf(f, _T("Attempting to launch boincmgr.exe\n"));
|
||||
fwprintf(f, _T("Launching: '%s'\n"), strBuffer.c_str());
|
||||
if (CreateProcessAsUser( hRestrictedToken, NULL, (LPWSTR)strBuffer.c_str(), NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &startup_info, &process_info ))
|
||||
{
|
||||
fwprintf(f, _T("Success!!!\n"));
|
||||
CloseHandle( process_info.hProcess );
|
||||
CloseHandle( process_info.hThread );
|
||||
}
|
||||
else
|
||||
{
|
||||
fwprintf(f, _T("CreateProcessAsUser retval: '%d'\n"), GetLastError());
|
||||
}
|
||||
CreateProcessWithExplorerIL( (LPWSTR)strBuffer.c_str(), NULL );
|
||||
|
||||
strBuffer = tstring(_T("\"")) + strInstallDirectory + tstring(_T("gridrepublic.exe\""));
|
||||
fwprintf(f, _T("Attempting to launch gridrepublic.exe\n"));
|
||||
fwprintf(f, _T("Launching: '%s'\n"), strBuffer.c_str());
|
||||
if (CreateProcessAsUser( hRestrictedToken, NULL, (LPWSTR)strBuffer.c_str(), NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &startup_info, &process_info ))
|
||||
{
|
||||
fwprintf(f, _T("Success!!!\n"));
|
||||
CloseHandle( process_info.hProcess );
|
||||
CloseHandle( process_info.hThread );
|
||||
}
|
||||
else
|
||||
{
|
||||
fwprintf(f, _T("CreateProcessAsUser retval: '%d'\n"), GetLastError());
|
||||
}
|
||||
CreateProcessWithExplorerIL( (LPWSTR)strBuffer.c_str(), NULL );
|
||||
|
||||
strBuffer = tstring(_T("\"")) + strInstallDirectory + tstring(_T("charityengine.exe\""));
|
||||
fwprintf(f, _T("Attempting to launch charityengine.exe\n"));
|
||||
fwprintf(f, _T("Launching: '%s'\n"), strBuffer.c_str());
|
||||
if (CreateProcessAsUser( hRestrictedToken, NULL, (LPWSTR)strBuffer.c_str(), NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &startup_info, &process_info ))
|
||||
{
|
||||
fwprintf(f, _T("Success!!!\n"));
|
||||
CloseHandle( process_info.hProcess );
|
||||
CloseHandle( process_info.hThread );
|
||||
}
|
||||
else
|
||||
{
|
||||
fwprintf(f, _T("CreateProcessAsUser retval: '%d'\n"), GetLastError());
|
||||
}
|
||||
CreateProcessWithExplorerIL( (LPWSTR)strBuffer.c_str(), NULL );
|
||||
|
||||
strBuffer = tstring(_T("\"")) + strInstallDirectory + tstring(_T("progressthruprocessors.exe\""));
|
||||
fwprintf(f, _T("Attempting to launch progressthruprocessors.exe\n"));
|
||||
fwprintf(f, _T("Launching: '%s'\n"), strBuffer.c_str());
|
||||
if (CreateProcessAsUser( hRestrictedToken, NULL, (LPWSTR)strBuffer.c_str(), NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &startup_info, &process_info ))
|
||||
{
|
||||
fwprintf(f, _T("Success!!!\n"));
|
||||
CloseHandle( process_info.hProcess );
|
||||
CloseHandle( process_info.hThread );
|
||||
}
|
||||
else
|
||||
{
|
||||
fwprintf(f, _T("CreateProcessAsUser retval: '%d'\n"), GetLastError());
|
||||
}
|
||||
CreateProcessWithExplorerIL( (LPWSTR)strBuffer.c_str(), NULL );
|
||||
|
||||
|
||||
fclose(f);
|
||||
CloseHandle( hRestrictedToken );
|
||||
pSCLOSEL( hSaferHandle );
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -465,6 +465,10 @@
|
|||
RelativePath=".\dirops.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\launcher.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\lkuprid.cpp"
|
||||
>
|
||||
|
@ -618,6 +622,10 @@
|
|||
RelativePath=".\dirops.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\launcher.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\lkuprid.h"
|
||||
>
|
||||
|
|
|
@ -0,0 +1,298 @@
|
|||
|
||||
#include "stdafx.h"
|
||||
#include "boinccas.h"
|
||||
#include "launcher.h"
|
||||
|
||||
|
||||
#ifndef SECURITY_MANDATORY_UNTRUSTED_RID
|
||||
|
||||
#define SECURITY_MANDATORY_UNTRUSTED_RID (0x00000000L)
|
||||
#define SECURITY_MANDATORY_LOW_RID (0x00001000L)
|
||||
#define SECURITY_MANDATORY_MEDIUM_RID (0x00002000L)
|
||||
#define SECURITY_MANDATORY_HIGH_RID (0x00003000L)
|
||||
#define SECURITY_MANDATORY_SYSTEM_RID (0x00004000L)
|
||||
#define SECURITY_MANDATORY_PROTECTED_PROCESS_RID (0x00005000L)
|
||||
|
||||
typedef struct _TOKEN_MANDATORY_LABEL {
|
||||
SID_AND_ATTRIBUTES Label;
|
||||
} TOKEN_MANDATORY_LABEL, *PTOKEN_MANDATORY_LABEL;
|
||||
|
||||
typedef enum _MANDATORY_LEVEL {
|
||||
MandatoryLevelUntrusted = 0,
|
||||
MandatoryLevelLow,
|
||||
MandatoryLevelMedium,
|
||||
MandatoryLevelHigh,
|
||||
MandatoryLevelSystem,
|
||||
MandatoryLevelSecureProcess,
|
||||
MandatoryLevelCount
|
||||
} MANDATORY_LEVEL, *PMANDATORY_LEVEL;
|
||||
|
||||
#define TokenIntegrityLevel ((TOKEN_INFORMATION_CLASS)25)
|
||||
#endif //!SECURITY_MANDATORY_UNTRUSTED_RID
|
||||
|
||||
/*!
|
||||
@brief Function enables/disables/removes a privelege associated with the given token
|
||||
@detailed Calls LookupPrivilegeValue() and AdjustTokenPrivileges()
|
||||
@param[in] hToken - access token handle
|
||||
@param[in] lpszPrivilege - name of privilege to enable/disable
|
||||
@param[in] dwAttributes - (SE_PRIVILEGE_ENABLED) to enable or (0) disable or (SE_PRIVILEGE_REMOVED) to remove privilege
|
||||
@return HRESULT code
|
||||
@todo Removing was checked. To check enabling and disabling.
|
||||
*/
|
||||
inline HRESULT SetPrivilege(
|
||||
HANDLE hToken,
|
||||
LPCTSTR lpszPrivilege,
|
||||
DWORD dwAttributes=SE_PRIVILEGE_ENABLED
|
||||
)
|
||||
{
|
||||
HRESULT hr=S_OK;
|
||||
LUID luid;
|
||||
|
||||
if ( LookupPrivilegeValue(
|
||||
NULL, // lookup privilege on local system
|
||||
lpszPrivilege, // privilege to lookup
|
||||
&luid ) ) // receives LUID of privilege
|
||||
{
|
||||
TOKEN_PRIVILEGES tp;
|
||||
tp.PrivilegeCount = 1;
|
||||
tp.Privileges[0].Luid = luid;
|
||||
tp.Privileges[0].Attributes = dwAttributes;
|
||||
|
||||
// Enable the privilege or disable all privileges.
|
||||
|
||||
if ( !AdjustTokenPrivileges(
|
||||
hToken,
|
||||
FALSE,
|
||||
&tp,
|
||||
sizeof(TOKEN_PRIVILEGES),
|
||||
(PTOKEN_PRIVILEGES) NULL,
|
||||
(PDWORD) NULL) )
|
||||
hr=HRESULT_FROM_WIN32(GetLastError());
|
||||
}//if(LookupPrivilegeValue(...))
|
||||
else
|
||||
hr=HRESULT_FROM_WIN32(GetLastError());
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
/*!
|
||||
Function removes the priveleges which are not associated by default with explorer.exe at Medium Integration Level in Vista
|
||||
@returns HRESULT of the operation on SE_CREATE_GLOBAL_NAME (="SeCreateGlobalPrivilege")
|
||||
*/
|
||||
inline HRESULT ReducePrivilegesForMediumIL(HANDLE hToken)
|
||||
{
|
||||
HRESULT hr=S_OK;
|
||||
hr=SetPrivilege(hToken, SE_CREATE_GLOBAL_NAME, SE_PRIVILEGE_REMOVED);
|
||||
|
||||
SetPrivilege(hToken, SE_BACKUP_NAME, SE_PRIVILEGE_REMOVED);
|
||||
SetPrivilege(hToken, SE_CREATE_PAGEFILE_NAME, SE_PRIVILEGE_REMOVED);
|
||||
SetPrivilege(hToken, TEXT("SeCreateSymbolicLinkPrivilege"), SE_PRIVILEGE_REMOVED);
|
||||
SetPrivilege(hToken, SE_DEBUG_NAME, SE_PRIVILEGE_REMOVED);
|
||||
SetPrivilege(hToken, SE_IMPERSONATE_NAME, SE_PRIVILEGE_REMOVED);
|
||||
SetPrivilege(hToken, SE_INC_BASE_PRIORITY_NAME, SE_PRIVILEGE_REMOVED);
|
||||
SetPrivilege(hToken, SE_INCREASE_QUOTA_NAME, SE_PRIVILEGE_REMOVED);
|
||||
SetPrivilege(hToken, SE_LOAD_DRIVER_NAME, SE_PRIVILEGE_REMOVED);
|
||||
SetPrivilege(hToken, SE_MANAGE_VOLUME_NAME, SE_PRIVILEGE_REMOVED);
|
||||
SetPrivilege(hToken, SE_PROF_SINGLE_PROCESS_NAME, SE_PRIVILEGE_REMOVED);
|
||||
SetPrivilege(hToken, SE_REMOTE_SHUTDOWN_NAME, SE_PRIVILEGE_REMOVED);
|
||||
SetPrivilege(hToken, SE_RESTORE_NAME, SE_PRIVILEGE_REMOVED);
|
||||
SetPrivilege(hToken, SE_SECURITY_NAME, SE_PRIVILEGE_REMOVED);
|
||||
SetPrivilege(hToken, SE_SYSTEM_ENVIRONMENT_NAME, SE_PRIVILEGE_REMOVED);
|
||||
SetPrivilege(hToken, SE_SYSTEM_PROFILE_NAME, SE_PRIVILEGE_REMOVED);
|
||||
SetPrivilege(hToken, SE_SYSTEMTIME_NAME, SE_PRIVILEGE_REMOVED);
|
||||
SetPrivilege(hToken, SE_TAKE_OWNERSHIP_NAME, SE_PRIVILEGE_REMOVED);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
#define TraceLN(Function, Line) OutputDebugStringA(Function " line:" #Line "\n")
|
||||
|
||||
/*!
|
||||
@brief Gets Integration level of the given process in Vista.
|
||||
In the older OS assumes the integration level is equal to SECURITY_MANDATORY_HIGH_RID
|
||||
|
||||
The function opens the process for all access and opens its token for all access.
|
||||
Then it extracts token information and closes the handles.
|
||||
@param[in] dwProcessId ID of the process to operate
|
||||
@param[out] pdwProcessIL pointer to write the value
|
||||
@return HRESULT
|
||||
@retval <return value> { description }
|
||||
@remarks Function check for OS version by querying the presence of Kernel32.GetProductInfo function.
|
||||
This way is used due to the function is called from InstallShield12 script, so GetVersionEx returns incorrect value.
|
||||
@todo restrict access rights when quering for tokens
|
||||
*/
|
||||
inline HRESULT GetProcessIL(DWORD dwProcessId, LPDWORD pdwProcessIL)
|
||||
{
|
||||
HRESULT hr=S_OK;
|
||||
if(!pdwProcessIL)
|
||||
hr=E_INVALIDARG;
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
bool bVista=false;
|
||||
{
|
||||
// When the function is called from IS12, GetVersionEx returns dwMajorVersion=5 on Vista!
|
||||
HMODULE hmodKernel32=LoadLibrary(L"Kernel32");
|
||||
if(hmodKernel32 && GetProcAddress(hmodKernel32, "GetProductInfo"))
|
||||
bVista=true;
|
||||
if(hmodKernel32) FreeLibrary(hmodKernel32);
|
||||
}
|
||||
|
||||
DWORD dwIL=SECURITY_MANDATORY_HIGH_RID;
|
||||
if(bVista)
|
||||
{//Vista
|
||||
HANDLE hToken=NULL;
|
||||
HANDLE hProcess=OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
|
||||
if(hProcess)
|
||||
{
|
||||
if(OpenProcessToken(hProcess, TOKEN_ALL_ACCESS, &hToken))
|
||||
{
|
||||
PTOKEN_MANDATORY_LABEL pTIL=NULL;
|
||||
DWORD dwSize=0;
|
||||
if (!GetTokenInformation(hToken, TokenIntegrityLevel, NULL, 0, &dwSize)
|
||||
&& ERROR_INSUFFICIENT_BUFFER==GetLastError() && dwSize)
|
||||
pTIL=(PTOKEN_MANDATORY_LABEL)HeapAlloc(GetProcessHeap(), 0, dwSize);
|
||||
|
||||
if(pTIL && GetTokenInformation(hToken, TokenIntegrityLevel, pTIL, dwSize, &dwSize))
|
||||
{
|
||||
LPBYTE lpb=GetSidSubAuthorityCount(pTIL->Label.Sid);
|
||||
if(lpb)
|
||||
dwIL = *GetSidSubAuthority(pTIL->Label.Sid, *lpb-1);
|
||||
else
|
||||
hr=E_UNEXPECTED;
|
||||
}
|
||||
if(pTIL)
|
||||
HeapFree(GetProcessHeap(), 0, pTIL);
|
||||
CloseHandle(hToken);
|
||||
}//if(OpenProcessToken(...))
|
||||
CloseHandle(hProcess);
|
||||
}//if(hProcess)
|
||||
}//if(bVista)
|
||||
if(SUCCEEDED(hr))
|
||||
*pdwProcessIL=dwIL;
|
||||
}//if(SUCCEEDED(hr))
|
||||
return hr;
|
||||
}
|
||||
|
||||
/*!
|
||||
@brief Function launches process with the integration level of Explorer on Vista. On the previous OS, simply creates the process.
|
||||
|
||||
Function gets the integration level of the current process and Explorer, then launches the new process.
|
||||
If the integration levels are equal, CreateProcess is called.
|
||||
If Explorer has Medium IL, and the current process has High IL, new token is created, its rights are adjusted
|
||||
and CreateProcessWithTokenW is called.
|
||||
If Explorer has Medium IL, and the current process has High IL, error is returned.
|
||||
@param[in] szProcessName - the name of exe file (see CreatePorcess())
|
||||
@param[in] szCmdLine - the name of exe file (see CreatePorcess())
|
||||
@return HRESULT code
|
||||
@note The function cannot be used in services, due to if uses USER32.FindWindow() to get the proper instance of Explorer.
|
||||
The parent of new process in taskmgr.exe, but not the current process.
|
||||
@sa ReducePrivilegesForMediumIL()
|
||||
*/
|
||||
HRESULT CreateProcessWithExplorerIL(LPWSTR szProcessName, LPWSTR szCmdLine)
|
||||
{
|
||||
HRESULT hr=S_OK;
|
||||
|
||||
BOOL bRet;
|
||||
HANDLE hToken;
|
||||
HANDLE hNewToken;
|
||||
|
||||
bool bVista=false;
|
||||
{ // When the function is called from IS12, GetVersionEx returns dwMajorVersion=5 on Vista!
|
||||
HMODULE hmodKernel32=LoadLibrary(L"Kernel32");
|
||||
if(hmodKernel32 && GetProcAddress(hmodKernel32, "GetProductInfo"))
|
||||
bVista=true;
|
||||
if(hmodKernel32) FreeLibrary(hmodKernel32);
|
||||
}
|
||||
|
||||
PROCESS_INFORMATION ProcInfo = {0};
|
||||
STARTUPINFO StartupInfo = {0};
|
||||
|
||||
if(bVista)
|
||||
{
|
||||
DWORD dwCurIL=SECURITY_MANDATORY_HIGH_RID;
|
||||
DWORD dwExplorerID=0, dwExplorerIL=SECURITY_MANDATORY_HIGH_RID;
|
||||
|
||||
HWND hwndShell=::FindWindow( _T("Progman"), NULL);
|
||||
if(hwndShell)
|
||||
GetWindowThreadProcessId(hwndShell, &dwExplorerID);
|
||||
|
||||
hr=GetProcessIL(dwExplorerID, &dwExplorerIL);
|
||||
if(SUCCEEDED(hr))
|
||||
hr=GetProcessIL(GetCurrentProcessId(), &dwCurIL);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
if(dwCurIL==SECURITY_MANDATORY_HIGH_RID && dwExplorerIL==SECURITY_MANDATORY_MEDIUM_RID)
|
||||
{
|
||||
HANDLE hProcess=OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwExplorerID);
|
||||
if(hProcess)
|
||||
{
|
||||
if(OpenProcessToken(hProcess, TOKEN_ALL_ACCESS, &hToken))
|
||||
{
|
||||
if(!DuplicateTokenEx(hToken, TOKEN_ALL_ACCESS, NULL,
|
||||
SecurityImpersonation, TokenPrimary, &hNewToken))
|
||||
hr=HRESULT_FROM_WIN32(GetLastError());
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
if(dwCurIL==SECURITY_MANDATORY_MEDIUM_RID && dwExplorerIL==SECURITY_MANDATORY_MEDIUM_RID)
|
||||
{
|
||||
hr=ReducePrivilegesForMediumIL(hNewToken);
|
||||
}//if(dwCurIL==...)
|
||||
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
typedef BOOL (WINAPI *LPFN_CreateProcessWithTokenW)(
|
||||
HANDLE hToken,
|
||||
DWORD dwLogonFlags,
|
||||
LPCWSTR lpApplicationName,
|
||||
LPWSTR lpCommandLine,
|
||||
DWORD dwCreationFlags,
|
||||
LPVOID lpEnvironment,
|
||||
LPCWSTR lpCurrentDirectory,
|
||||
LPSTARTUPINFOW lpStartupInfo,
|
||||
LPPROCESS_INFORMATION lpProcessInfo
|
||||
);
|
||||
LPFN_CreateProcessWithTokenW fnCreateProcessWithTokenW=NULL;
|
||||
HINSTANCE hmodAdvApi32=LoadLibraryA("AdvApi32");
|
||||
if(hmodAdvApi32)
|
||||
fnCreateProcessWithTokenW=(LPFN_CreateProcessWithTokenW)GetProcAddress(hmodAdvApi32, "CreateProcessWithTokenW");
|
||||
if(fnCreateProcessWithTokenW)
|
||||
{
|
||||
bRet=fnCreateProcessWithTokenW(hNewToken, 0,
|
||||
szProcessName, szCmdLine,
|
||||
0, NULL, NULL, &StartupInfo, &ProcInfo);
|
||||
if(!bRet)
|
||||
hr=HRESULT_FROM_WIN32(GetLastError());
|
||||
}
|
||||
else
|
||||
hr=E_UNEXPECTED;
|
||||
if(hmodAdvApi32)
|
||||
FreeLibrary(hmodAdvApi32);
|
||||
}//if(SUCCEEDED(hr))
|
||||
CloseHandle(hNewToken);
|
||||
}//if (DuplicateTokenEx(...)
|
||||
else
|
||||
hr=HRESULT_FROM_WIN32(GetLastError());
|
||||
CloseHandle(hToken);
|
||||
}//if(OpenProcessToken(...))
|
||||
else
|
||||
hr=HRESULT_FROM_WIN32(GetLastError());
|
||||
CloseHandle(hProcess);
|
||||
}//if(hProcess)
|
||||
}//if(dwCurIL==SECURITY_MANDATORY_HIGH_RID && dwExplorerIL==SECURITY_MANDATORY_MEDIUM_RID)
|
||||
else if(dwCurIL==SECURITY_MANDATORY_MEDIUM_RID && dwExplorerIL==SECURITY_MANDATORY_HIGH_RID)
|
||||
hr=E_ACCESSDENIED;
|
||||
}//if(SUCCEEDED(hr))
|
||||
}//if(bVista)
|
||||
|
||||
if(SUCCEEDED(hr) && !ProcInfo.dwProcessId)
|
||||
{// 2K | XP | Vista & !UAC
|
||||
bRet = CreateProcess(szProcessName, szCmdLine,
|
||||
NULL, NULL, FALSE, 0, NULL, NULL, &StartupInfo, &ProcInfo);
|
||||
if(!bRet)
|
||||
hr=HRESULT_FROM_WIN32(GetLastError());
|
||||
}// 2K | XP | Vista & !UAC
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
HRESULT CreateProcessWithExplorerIL(LPWSTR szProcessName, LPWSTR szCmdLine);
|
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue