├── .gitignore ├── README.md ├── ReadMe.txt ├── RunAsSystem.cpp ├── RunAsSystem.h ├── RunAsSystem.sln ├── RunAsSystem.vcproj ├── RunAsSystem.vcxproj ├── main.cpp ├── stdafx.cpp ├── stdafx.h └── targetver.h /.gitignore: -------------------------------------------------------------------------------- 1 | Release 2 | Debug 3 | RunAsSystem.ncb 4 | RunAsSystem.suo 5 | RunAsSystem.vcproj.WIN-JNBDPQE2AJ8.Mixer.user 6 | RunAsSystem.sln.old 7 | RunAsSystem.suo.old 8 | RunAsSystem.v12.suo 9 | RunAsSystem.vcxproj 10 | RunAsSystem.vcxproj.user 11 | UpgradeLog.XML 12 | _UpgradeReport_Files/UpgradeReport.css 13 | _UpgradeReport_Files/UpgradeReport.xslt 14 | _UpgradeReport_Files/UpgradeReport_Minus.gif 15 | _UpgradeReport_Files/UpgradeReport_Plus.gif 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RunAsSystem 2 | # RunAsSystem 3 | -------------------------------------------------------------------------------- /ReadMe.txt: -------------------------------------------------------------------------------- 1 | ======================================================================== 2 | CONSOLE APPLICATION : RunAsSystem Project Overview 3 | ======================================================================== 4 | 5 | AppWizard has created this RunAsSystem application for you. 6 | 7 | This file contains a summary of what you will find in each of the files that 8 | make up your RunAsSystem application. 9 | 10 | 11 | RunAsSystem.vcproj 12 | This is the main project file for VC++ projects generated using an Application Wizard. 13 | It contains information about the version of Visual C++ that generated the file, and 14 | information about the platforms, configurations, and project features selected with the 15 | Application Wizard. 16 | 17 | RunAsSystem.cpp 18 | This is the main application source file. 19 | 20 | ///////////////////////////////////////////////////////////////////////////// 21 | Other standard files: 22 | 23 | StdAfx.h, StdAfx.cpp 24 | These files are used to build a precompiled header (PCH) file 25 | named RunAsSystem.pch and a precompiled types file named StdAfx.obj. 26 | 27 | ///////////////////////////////////////////////////////////////////////////// 28 | Other notes: 29 | 30 | AppWizard uses "TODO:" comments to indicate parts of the source code you 31 | should add to or customize. 32 | 33 | ///////////////////////////////////////////////////////////////////////////// 34 | -------------------------------------------------------------------------------- /RunAsSystem.cpp: -------------------------------------------------------------------------------- 1 | 2 | // RunAsSystem - RunAsSystem.cpp - by Michael Badichi 3 | 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #pragma comment (lib, "advapi32") 17 | #pragma comment (lib, "Psapi") 18 | #pragma comment (lib, "UserEnv") 19 | #pragma comment (lib, "Shlwapi") 20 | 21 | template< typename T > std::wstring toString( const T& value ) 22 | { 23 | std::wstringstream oss; 24 | oss << value; 25 | return oss.str(); 26 | } 27 | typedef std::auto_ptr< SID > SidPtr_t; 28 | 29 | SidPtr_t _LookupAccountName( std::wstring sName, std::wstring sSystem ) 30 | { 31 | DWORD cbSid = 0; 32 | DWORD cbDomain = 0; 33 | SID_NAME_USE tSid; 34 | LookupAccountName( sSystem.c_str(), sName.c_str(), NULL, &cbSid, NULL, &cbDomain, &tSid ); 35 | if( cbSid != 0 ) 36 | { 37 | SID * pSid = (SID *)new char[ cbSid ]; 38 | std::vector domain( cbDomain ); 39 | if( LookupAccountName( sSystem.c_str(), sName.c_str(), pSid, &cbSid, &domain[0], &cbDomain, &tSid ) ) 40 | { 41 | return SidPtr_t( pSid ); 42 | } 43 | } 44 | 45 | return SidPtr_t(NULL); 46 | } 47 | 48 | LSA_HANDLE _LsaOpenPolicy( ACCESS_MASK iAccess ) 49 | { 50 | LSA_OBJECT_ATTRIBUTES lsaAttr = {0}; 51 | LSA_HANDLE hPolicy; 52 | if( SUCCEEDED( LsaOpenPolicy( NULL, &lsaAttr, iAccess, &hPolicy ) ) ) 53 | { 54 | return hPolicy; 55 | } 56 | return INVALID_HANDLE_VALUE; 57 | } 58 | 59 | bool _LsaAddAccountRights( std::wstring sName, std::wstring sRight ) 60 | { 61 | bool retCode = false; 62 | std::wstring domain; 63 | SidPtr_t sid = _LookupAccountName( sName, L"" ); 64 | SID * pSid = sid.get(); 65 | if( IsValidSid( pSid ) ) 66 | { 67 | LSA_HANDLE hPolicy = _LsaOpenPolicy( 0x811 ); 68 | if( hPolicy != INVALID_HANDLE_VALUE ) 69 | { 70 | int iLen = sRight.length() * 2; 71 | std::vector< WCHAR > tRight( iLen ); 72 | wcscpy_s( &tRight[0], iLen, sRight.c_str() ); 73 | LSA_UNICODE_STRING unicode; 74 | unicode.Length = iLen; 75 | unicode.MaximumLength = iLen + 2; 76 | unicode.Buffer = &tRight[0]; 77 | if( SUCCEEDED( LsaAddAccountRights( hPolicy, pSid, &unicode, 1 ) ) ) 78 | { 79 | retCode = true; 80 | } 81 | LsaClose( hPolicy ); 82 | } 83 | retCode = true; 84 | } 85 | return retCode; 86 | } 87 | 88 | bool _SetPrivilege( std::wstring Privilege ) 89 | { 90 | bool retCode = false; 91 | HANDLE curProc = GetCurrentProcess(); 92 | HANDLE hToken; 93 | if( OpenProcessToken( curProc, TOKEN_ALL_ACCESS, &hToken ) ) 94 | { 95 | TOKEN_PRIVILEGES tp; 96 | tp.PrivilegeCount = 1; 97 | tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 98 | LookupPrivilegeValue( L"", Privilege.c_str(), &tp.Privileges[0].Luid ); 99 | TOKEN_PRIVILEGES tpout; 100 | DWORD retLen = 0; 101 | BOOL stat = AdjustTokenPrivileges( hToken, FALSE, &tp, sizeof(tpout), &tpout, &retLen ); 102 | DWORD lasterr = GetLastError(); 103 | if( lasterr != 0) 104 | { 105 | //OutputDebugString( (std::wstring(L"AdjustTokenPrivilefes(")+Privilege+L") :"+toString(lasterr)).c_str() ); 106 | if( lasterr == ERROR_NOT_ALL_ASSIGNED ) 107 | { 108 | WCHAR uname[ UNLEN+1 ]; 109 | DWORD cbUname = sizeof( uname ) / sizeof( uname[0] ); 110 | if( GetUserName( uname, &cbUname ) ) 111 | { 112 | if( _LsaAddAccountRights( uname, Privilege ) ) 113 | { 114 | OutputDebugString( (std::wstring(L"Reboot required for changes to take effect: ")+Privilege).c_str() ); 115 | stat = TRUE; 116 | } 117 | else 118 | { 119 | OutputDebugString( (std::wstring(L"Error: The right was probably not added correctly to your account: ")+Privilege).c_str() ); 120 | stat = FALSE; 121 | } 122 | } 123 | } 124 | } 125 | CloseHandle( hToken ); 126 | retCode = ( stat == TRUE ); 127 | } 128 | return retCode; 129 | } 130 | 131 | bool IsProcessIdMatchingName( DWORD processID, std::wstring name ) 132 | { 133 | bool retCode = false; 134 | WCHAR szProcessName[ MAX_PATH ] = L""; 135 | HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID ); 136 | if ( hProcess ) 137 | { 138 | WCHAR path[ MAX_PATH + FILENAME_MAX + 1]; 139 | if( GetProcessImageFileName( hProcess, path, sizeof( path ) / sizeof( path[0] ) ) ) 140 | { 141 | WCHAR * fname = StrRChr( path, NULL, L'\\' ); 142 | if( fname ) 143 | { 144 | fname++; 145 | //OutputDebugString( (std::wstring(L"Testing process name ")+fname).c_str() ); 146 | retCode = ( _wcsicmp( fname, name.c_str() ) == 0 ); 147 | } 148 | } 149 | CloseHandle( hProcess ); 150 | } 151 | else 152 | { 153 | //OutputDebugString((std::wstring(L"Error opening process ID ")+toString(processID)).c_str()); 154 | } 155 | return retCode; 156 | } 157 | 158 | DWORD GetProcessIdByName( std::wstring name, DWORD sessionID ) 159 | { 160 | DWORD retCode = 0; 161 | DWORD aProcesses[16*1024]; 162 | DWORD cbNeeded; 163 | unsigned int i; 164 | if ( EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) ) 165 | { 166 | DWORD cProcesses = cbNeeded / sizeof(DWORD); 167 | for ( i = 0; i < cProcesses; i++ ) 168 | { 169 | if( aProcesses[i] != 0 ) 170 | { 171 | //OutputDebugString( (std::wstring(L"Testing process ID ")+toString(aProcesses[i])).c_str() ); 172 | if( IsProcessIdMatchingName( aProcesses[i], name ) ) 173 | { 174 | DWORD sesID = 0; 175 | if( ProcessIdToSessionId( aProcesses[i], &sesID ) ) 176 | { 177 | if( sesID == sessionID ) 178 | { 179 | //found it 180 | retCode = aProcesses[i]; 181 | break; 182 | } 183 | } 184 | } 185 | } 186 | } 187 | } 188 | return retCode; 189 | } 190 | 191 | VOID * _GetEnvironmentBlock( DWORD processID ) 192 | { 193 | VOID * retCode = NULL; 194 | 195 | HANDLE hProc = OpenProcess( 0x02000000, FALSE, processID ); 196 | if( hProc ) 197 | { 198 | HANDLE hToken; 199 | if( OpenProcessToken( hProc, TOKEN_DUPLICATE | TOKEN_QUERY, &hToken ) ) 200 | { 201 | if( CreateEnvironmentBlock( &retCode, hToken, TRUE ) ) 202 | { 203 | //yey 204 | } 205 | CloseHandle( hToken ); 206 | } 207 | CloseHandle( hProc ); 208 | } 209 | return retCode; 210 | } 211 | 212 | 213 | 214 | bool RunAsSystem( const WCHAR * cmd_, const WCHAR * runFromDir_, DWORD * procDoneRetCode_ = NULL ) 215 | { 216 | std::wstring cmd = cmd_ ? cmd_ : L""; 217 | std::wstring runFromDir = runFromDir_ ? runFromDir_ : L""; 218 | bool retCode = false; 219 | WCHAR * winlogon = L"winlogon.exe"; 220 | WCHAR * privileges[] = { 221 | L"SeDebugPrivilege", 222 | L"SeAssignPrimaryTokenPrivilege", 223 | L"SeIncreaseQuotaPrivilege" 224 | }; 225 | for( int i=0; i 6 | 7 | bool RunAsSystem( const WCHAR * cmd, const WCHAR * runFromDir, DWORD * procDoneRetCode_ = NULL ); 8 | -------------------------------------------------------------------------------- /RunAsSystem.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 11.00 3 | # Visual Studio 2010 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RunAsSystem", "RunAsSystem.vcxproj", "{6037894A-BAB5-45FA-8E6F-701375015B51}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win32 = Debug|Win32 9 | Release|Win32 = Release|Win32 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {6037894A-BAB5-45FA-8E6F-701375015B51}.Debug|Win32.ActiveCfg = Debug|Win32 13 | {6037894A-BAB5-45FA-8E6F-701375015B51}.Debug|Win32.Build.0 = Debug|Win32 14 | {6037894A-BAB5-45FA-8E6F-701375015B51}.Release|Win32.ActiveCfg = Release|Win32 15 | {6037894A-BAB5-45FA-8E6F-701375015B51}.Release|Win32.Build.0 = Release|Win32 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /RunAsSystem.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 15 | 16 | 17 | 18 | 19 | 26 | 29 | 32 | 35 | 38 | 41 | 52 | 55 | 58 | 61 | 69 | 72 | 75 | 78 | 81 | 84 | 87 | 90 | 91 | 99 | 102 | 105 | 108 | 111 | 114 | 125 | 128 | 131 | 134 | 144 | 147 | 150 | 153 | 156 | 159 | 162 | 165 | 166 | 167 | 168 | 169 | 170 | 175 | 178 | 179 | 182 | 183 | 186 | 187 | 188 | 193 | 196 | 197 | 200 | 201 | 204 | 205 | 206 | 211 | 212 | 215 | 216 | 217 | 218 | 219 | 220 | -------------------------------------------------------------------------------- /RunAsSystem.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {6037894A-BAB5-45FA-8E6F-701375015B51} 15 | RunAsSystem 16 | Win32Proj 17 | 18 | 19 | 20 | Application 21 | Unicode 22 | true 23 | 24 | 25 | Application 26 | Unicode 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | <_ProjectFileVersion>10.0.40219.1 40 | $(SolutionDir)$(Configuration)\ 41 | $(Configuration)\ 42 | true 43 | $(SolutionDir)$(Configuration)\ 44 | $(Configuration)\ 45 | false 46 | 47 | 48 | 49 | Disabled 50 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 51 | true 52 | EnableFastChecks 53 | MultiThreadedDebugDLL 54 | 55 | 56 | Level3 57 | EditAndContinue 58 | 59 | 60 | true 61 | Console 62 | MachineX86 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | MaxSpeed 72 | true 73 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 74 | MultiThreaded 75 | true 76 | 77 | 78 | Level3 79 | ProgramDatabase 80 | 81 | 82 | true 83 | Console 84 | true 85 | true 86 | MachineX86 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | 2 | // RunAsSystem - main.cpp - by Michael Badichi 3 | 4 | #include "stdafx.h" 5 | #include "RunAsSystem.h" 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #define DLOG 0 13 | 14 | #define SSTR( x ) dynamic_cast< std::wostringstream & >( ( std::wostringstream() << std::dec << x ) ).str() 15 | 16 | #pragma warning (disable:4996) 17 | 18 | std::wstring AsWideString( const std::string& s ) 19 | { 20 | size_t mbSize = s.size() + 1; 21 | size_t wcSize = mbstowcs( 0, s.c_str(), mbSize ) + 1; 22 | std::vector< wchar_t > w( wcSize, 0 ); 23 | mbstowcs( &w[0], s.c_str(), mbSize ); 24 | return std::wstring( &w[0] ); 25 | } 26 | 27 | int __stdcall WinMain( __in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in_opt LPSTR lpCmdLine, __in int nShowCmd ) 28 | { 29 | DWORD retCode = 0; 30 | //skip whitespace 31 | while( lpCmdLine[0]==' ') lpCmdLine++; 32 | if( strlen( lpCmdLine ) == 0 ) 33 | { 34 | MessageBox( NULL, L"usage: RunAsSystem [--block] ", L"RunAsSystem", MB_OK ); 35 | MessageBeep( MB_ICONWARNING ); 36 | } 37 | else 38 | { 39 | DWORD * pRetcode = NULL; 40 | if( strstr( lpCmdLine, "--block" ) == lpCmdLine ) { 41 | lpCmdLine += 8; 42 | pRetcode = &retCode; 43 | while( lpCmdLine[0]==' ') lpCmdLine++; 44 | } 45 | 46 | std::wstring cmd = AsWideString( std::string( lpCmdLine ) ); 47 | const WCHAR * runFromDir = NULL; //can be empty - in which case - use my dir 48 | 49 | bool ok = RunAsSystem( cmd.c_str(), runFromDir, pRetcode ); //if we dont provide retCode pointer, function dont wait for process to finish 50 | 51 | #if DLOG 52 | std::wstring log = L"RunAsSystem --> '"; 53 | log += cmd; 54 | log += L"' --> "; 55 | log += (ok ? L"ok" : L"FAIL" ); 56 | if( ok ) 57 | { 58 | log += SSTR( " ==> " << retCode ); 59 | } 60 | OutputDebugString( log.c_str() ); 61 | #endif 62 | } 63 | return (int)retCode; 64 | } 65 | 66 | #ifdef _CONSOLE 67 | 68 | int main( int argc, char ** argv ) 69 | { 70 | HINSTANCE hInstance = GetModuleHandle(NULL); 71 | LPSTR lpCmdLine = GetCommandLineA(); 72 | LPSTR pCmdLine = lpCmdLine; 73 | if( *pCmdLine == '"' ) { 74 | char * p = strstr( pCmdLine+1, "\"" ); 75 | if( p ) { 76 | p++; 77 | while( *p == ' ' ) p++; 78 | pCmdLine = p; 79 | } 80 | } 81 | else 82 | { 83 | while( char * p = strstr( pCmdLine, " " ) ) { 84 | if( p > pCmdLine && *(p-1) != '\\' ) { 85 | pCmdLine = p+1; 86 | break; 87 | } 88 | pCmdLine = p+1; 89 | } 90 | } 91 | if( pCmdLine == lpCmdLine ) pCmdLine = ""; 92 | return WinMain( hInstance, NULL, pCmdLine, SW_SHOWNORMAL ); 93 | } 94 | 95 | #endif 96 | -------------------------------------------------------------------------------- /stdafx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // RunAsSystem.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | 7 | // TODO: reference any additional headers you need in STDAFX.H 8 | // and not in this file 9 | -------------------------------------------------------------------------------- /stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | 6 | #pragma once 7 | #define WIN32_LEAN_AND_MEAN 8 | #include 9 | #include "targetver.h" 10 | 11 | #include 12 | #include 13 | 14 | 15 | 16 | // TODO: reference additional headers your program requires here 17 | -------------------------------------------------------------------------------- /targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // The following macros define the minimum required platform. The minimum required platform 4 | // is the earliest version of Windows, Internet Explorer etc. that has the necessary features to run 5 | // your application. The macros work by enabling all features available on platform versions up to and 6 | // including the version specified. 7 | 8 | // Modify the following defines if you have to target a platform prior to the ones specified below. 9 | // Refer to MSDN for the latest info on corresponding values for different platforms. 10 | #ifndef _WIN32_WINNT // Specifies that the minimum required platform is Windows Vista. 11 | #define _WIN32_WINNT 0x0600 // Change this to the appropriate value to target other versions of Windows. 12 | #endif 13 | 14 | --------------------------------------------------------------------------------