⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 createprocessasuser.cpp

📁 这是一本学习 window编程的很好的参考教材
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/////////////////////////////////////////////////////////////
// CreateProcessAsUser.cpp
// 
// Written by Valery Pryamikov (1999)
// 
// Command line utility that executes a command under specified user identity 
// by temporarily installing itself as a service.
//
// Based on Keith Brown's AsLocalSystem utility (http://www.develop.com/kbrown)
// Uses some code from Mike Nelson's dcomperm sample utility 
//   and from tlist sample (Microsoft Source Code Samples)
//
// Use:
//	CreateProcessAsUser.exe [-i[nteractive]]|[-s[ystem]]|
//       [-u"UserName" -d"DomainName" -p"Password"]|[-a"AppID"] command
//  Command must begin with the process (path to the exe file) to launch
//  -i        process will be launched under credentials of the 
//            "Interactive User" (retrieved from winlogon\shell process)
//  -a        process will be launched under credentials of the user 
//            specified in "RunAs" parameter of AppID.
//  -s        process will be launched as local system
//  -u -d -p  process will be launched on the result token of the 
//            LogonUser(userName,domainName,password,LOGON32_LOGON_BATCH...)
//
// either (-s) or (-i) or (-a) or (-u -d -p) parameters must supplied
// 
// Examples:
// CreateProcessAsUser -s cmd.exe
// CreateProcessAsUser -a"{731A63AF-2990-11D1-B12E-00C04FC2F56F}" winfile.exe
//
/////////////////////////////////////////////////////////////

#define _WIN32_WINNT 0x400
#include <windows.h>
#include <stdio.h>
#include "common.h" 
#include <ntsecapi.h>

#pragma comment( lib, "advapi32.lib" )

#define E_OBJ_IS_A_SERVICE			0x80040500
#define E_NO_RUN_AS_DATA			0x80040501
#define E_RUN_AS_INTERACTIVE		0x80040502
#define E_NO_INTERACTIVE_SESSION	0x80040503
#define E_SHELL_NOT_FOUND			0x80040504

#define GUIDSTR_MAX				38
#define MAX_TASKS           256 
#define MAX_CMD_LEN 8192

HRESULT GrantDesktopAccess(HANDLE hToken);

HRESULT GetProcessToken(DWORD dwProcessID, LPHANDLE token, DWORD nUserNameMax, LPWSTR szwUserName, DWORD nUserDomainMax, LPWSTR szwUserDomain)
{
	HANDLE hProcess=OpenProcess(PROCESS_DUP_HANDLE|PROCESS_QUERY_INFORMATION,TRUE,dwProcessID); 
	HRESULT retval = S_OK;
	if(hProcess) { 
		HANDLE hToken = INVALID_HANDLE_VALUE;
		if (!OpenProcessToken(hProcess, TOKEN_DUPLICATE | TOKEN_QUERY, &hToken)) retval = HRESULT_FROM_WIN32(GetLastError());
		else {
			BYTE buf[MAX_PATH]; DWORD dwRead = 0;
			if (!GetTokenInformation(hToken, TokenUser, buf, MAX_PATH, &dwRead)) retval = HRESULT_FROM_WIN32(GetLastError());
			else {
				TOKEN_USER *puser = reinterpret_cast<TOKEN_USER*>(buf);
				SID_NAME_USE eUse;
				if (!LookupAccountSid(NULL, puser->User.Sid, szwUserName, &nUserNameMax, szwUserDomain, &nUserDomainMax, &eUse))
					retval = HRESULT_FROM_WIN32(GetLastError());
			}
			if (FAILED(retval)) return retval;
			if (!DuplicateTokenEx(hToken, 
				TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE, 
				NULL, SecurityImpersonation, TokenPrimary,token))
				retval = HRESULT_FROM_WIN32(GetLastError());
			else  retval = S_OK;
			CloseHandle(hToken);
		}
		CloseHandle(hProcess);
	} else retval = HRESULT_FROM_WIN32(GetLastError());
	return retval;
}

HRESULT GetInteractiveUserToken(LPHANDLE token, DWORD nUserNameMax, LPWSTR szwUserName, DWORD nUserDomainMax, LPWSTR szwUserDomain)
{
    HKEY                  registryKey;
    ULONG returnValue = RegOpenKeyEx (HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", 0, KEY_READ, &registryKey);
    if (returnValue != ERROR_SUCCESS) return HRESULT_FROM_WIN32(returnValue);

	DWORD valueType;
	DWORD valueSize = (MAX_PATH+1)*sizeof(WCHAR);
    WCHAR process[MAX_PATH+1];
	memset(process,0,sizeof(process));
    returnValue = RegQueryValueEx(registryKey, L"Shell", NULL, &valueType, (BYTE*)process, &valueSize);
	RegCloseKey(registryKey);
	if (returnValue != ERROR_SUCCESS) return E_NO_INTERACTIVE_SESSION;
	if (wcslen(process)==0) return E_NO_INTERACTIVE_SESSION;

	WCHAR *p = wcsrchr( process , L'.' ); 
    if (p) { 
        p[0] = L'\0'; 
    } 
	for (p = process; *p!=L'\0'; p++) *p = _totupper(*p);

	TASK_LIST   tlist[MAX_TASKS]; 
	memset(tlist,0, sizeof(tlist));
	DWORD numTasks = GetTaskListNT( tlist, MAX_TASKS ); 
	WCHAR tname[MAX_PATH+1];
	memset(tname,0,sizeof(tname));
    for (DWORD i=0; i<numTasks; i++) { 
        tname[0] = 0; 
        wcscpy( tname, tlist[i].ProcessName ); 
        p = wcsrchr( tname, L'.' ); 
        if (p) { 
            p[0] = L'\0'; 
        } 
        if (MatchPattern( tname, process)) { 
			return GetProcessToken(tlist[i].dwProcessId, token, nUserNameMax, szwUserName, nUserDomainMax, szwUserDomain);
        } else if (MatchPattern( tlist[i].ProcessName, process )) { 
			return GetProcessToken(tlist[i].dwProcessId, token, nUserNameMax, szwUserName, nUserDomainMax, szwUserDomain);
        } else if (MatchPattern(tlist[i].WindowTitle, process)) { 
			return GetProcessToken(tlist[i].dwProcessId, token, nUserNameMax, szwUserName, nUserDomainMax, szwUserDomain);
        } 
    } 

	return E_SHELL_NOT_FOUND;
}

HRESULT GetRunAsPassword (LPWSTR AppID, int nPasswordMax, LPWSTR szwPassword, int nUserNameMax, LPWSTR szwUserName, int nUserDomainMax, LPWSTR szwUserDomain)
{
    LSA_OBJECT_ATTRIBUTES objectAttributes;
    HANDLE                policyHandle = NULL;
    LSA_UNICODE_STRING    lsaKeyString;
    PLSA_UNICODE_STRING   lsaPasswordString;
    WCHAR                 key [4 + GUIDSTR_MAX + 1];
    ULONG                 returnValue;
    WCHAR                 keyName [MAX_PATH+1];
    HKEY                  registryKey;

    wsprintf (keyName, L"AppID\\%s", AppID);
    returnValue = RegOpenKeyEx (HKEY_CLASSES_ROOT, keyName, 0, KEY_READ, &registryKey);
    if (returnValue == ERROR_SUCCESS) {
		DWORD valueType;
		DWORD valueSize = 0;
        returnValue = RegQueryValueEx (registryKey, L"LocalService", NULL, &valueType, NULL, &valueSize);

        if (returnValue == ERROR_SUCCESS || returnValue == ERROR_MORE_DATA) return RegCloseKey (registryKey), E_OBJ_IS_A_SERVICE;
		
	    WCHAR principal[MAX_PATH+1];
		valueSize = (MAX_PATH+1)*sizeof(WCHAR);
        returnValue = RegQueryValueEx(registryKey, L"RunAs", NULL, &valueType, (BYTE*)principal, &valueSize);
        RegCloseKey (registryKey);
        if (returnValue != ERROR_SUCCESS) return E_NO_RUN_AS_DATA;
		if (_wcsicmp(principal, L"Interactive User") == 0) return E_RUN_AS_INTERACTIVE;
		LPCOLESTR ptmp = wcschr(principal, L'\\');
		if (ptmp == 0) {
			memset(szwUserDomain, 0, nUserDomainMax);
			wcsncpy(szwUserName, principal, nUserNameMax);
		} else {
			memset(szwUserDomain, 0, nUserDomainMax);
			wcsncpy(szwUserDomain, principal, min(nUserDomainMax, ptmp-principal));
			wcsncpy(szwUserName, ptmp+1, nUserNameMax);
		}
    } else return E_NO_RUN_AS_DATA;

    wcscpy (key, L"SCM:");
    wcscat (key, AppID);

    lsaKeyString.Length = (USHORT) ((wcslen (key) + 1) * sizeof (WCHAR));
    lsaKeyString.MaximumLength = (GUIDSTR_MAX + 5) * sizeof (WCHAR);
    lsaKeyString.Buffer = key;

    //
    // Open the local security policy
    //

    memset (&objectAttributes, 0x00, sizeof (LSA_OBJECT_ATTRIBUTES));
    objectAttributes.Length = sizeof (LSA_OBJECT_ATTRIBUTES);

    returnValue = LsaOpenPolicy (NULL,
                                 &objectAttributes,
                                 POLICY_GET_PRIVATE_INFORMATION,
                                 &policyHandle);

    if (returnValue != ERROR_SUCCESS)
        return returnValue;

    //
    // Read the user's password
    //

    returnValue = LsaRetrievePrivateData (policyHandle,
                                          &lsaKeyString,
                                          &lsaPasswordString);

    if (returnValue != ERROR_SUCCESS)
    {
        LsaClose (policyHandle);
        return returnValue;
    }

    LsaClose (policyHandle);
    wcsncpy (szwPassword, lsaPasswordString->Buffer, nPasswordMax);
	LsaFreeMemory(lsaPasswordString->Buffer);

    return ERROR_SUCCESS;
}

void Quit( const wchar_t* pszMsg, int nExitCode = 1 )
{
	wprintf( L"%s\n", pszMsg );
	exit( nExitCode );
}

void Err( const wchar_t* pszFcn, DWORD nErr = GetLastError() )
{
	wchar_t szErrMsg[256];
	wchar_t szMsg[512];
	if ( FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, 0, nErr, 0, szErrMsg, sizeof szErrMsg / sizeof *szErrMsg, 0 ) )
		 swprintf( szMsg, L"%s failed: %s", szErrMsg );
	else swprintf( szMsg, L"%s failed: 0x%08X", nErr );
	Quit( szMsg );
}

void PrintUsageAndQuit()
{
	Quit( L"Use:\n"
		  L"CreateProcessAsUser.exe [-i[nteractive]]|[-s[ystem]]|\n[-u\"UserName\" -d\"DomainName\" -p\"Password\"]|[-a\"AppID\"] Command\n\n"
		  L"Command must begin with the process (path to the exe file) to launch\n"
		  L"-i        process will be launched under credentials of the\n"
		  L"          \"Interactive User\" (retrieved from winlogon\\shell process)\n"
		  L"-a        process will be launched under credentials of the user\n"
		  L"          specified in \"RunAs\" parameter of AppID\n"
		  L"-s        process will be launched as local system\n"
		  L"-u -d -p  process will be launched on the result token of the\n"
		  L"          LogonUser(userName,domainName,password,LOGON32_LOGON_BATCH...)\n"
		  L"\nEither -s or -i or -a or -u -d -p parameters must supplied\n"
		  L"\nExamples:\nCreateProcessAsUser -s cmd.exe\n"
		  L"CreateProcessAsUser -a\"{731A63AF-2990-11D1-B12E-00C04FC2F56F}\" winfile.exe\n"
		  L"\nWritten by Valery Pryamikov (1999)\n");
}

void* GetAdminSid()
{
	SID_IDENTIFIER_AUTHORITY ntauth = SECURITY_NT_AUTHORITY;
	void* psid = 0;
	if ( !AllocateAndInitializeSid( &ntauth, 2,
			SECURITY_BUILTIN_DOMAIN_RID,
			DOMAIN_ALIAS_RID_ADMINS,
			0, 0, 0, 0, 0, 0, &psid ) )
		Err( L"AllocateAndInitializeSid" );
	return psid;
}

void* GetLocalSystemSid()
{
	SID_IDENTIFIER_AUTHORITY ntauth = SECURITY_NT_AUTHORITY;
	void* psid = 0;
	if ( !AllocateAndInitializeSid( &ntauth, 1,
			SECURITY_LOCAL_SYSTEM_RID,
			0, 0, 0, 0, 0, 0, 0, &psid ) )
		Err( L"AllocateAndInitializeSid" );
	return psid;
}


bool IsAdmin()
{
	bool bIsAdmin = false;
	HANDLE htok = 0;
	if ( !OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &htok ) )
		Err( L"OpenProcessToken" );

	DWORD cb = 0;
	GetTokenInformation( htok, TokenGroups, 0, 0, &cb );
	TOKEN_GROUPS* ptg = (TOKEN_GROUPS*)malloc( cb );
	if ( !ptg )
		Err( L"malloc" );
	if ( !GetTokenInformation( htok, TokenGroups, ptg, cb, &cb ) )
		Err( L"GetTokenInformation" );

	void* pAdminSid = GetAdminSid();

	SID_AND_ATTRIBUTES* const end = ptg->Groups + ptg->GroupCount;
	for ( SID_AND_ATTRIBUTES* it = ptg->Groups; end != it; ++it )
		if ( EqualSid( it->Sid, pAdminSid ) )
			break;

	bIsAdmin = end != it;

	FreeSid( pAdminSid );
	free( ptg );
	CloseHandle( htok );

	return bIsAdmin;
}

bool IsLocalSystem()
{
	bool bIsLocalSystem = false;
	HANDLE htok = 0;
	if ( !OpenProcessToken( GetCurrentProcess(), TOKEN_QUERY, &htok ) )
		Err( L"OpenProcessToken" );

	BYTE userSid[256];
	DWORD cb = sizeof userSid;
	if ( !GetTokenInformation( htok, TokenUser, userSid, cb, &cb ) )
		Err( L"GetTokenInformation" );
	TOKEN_USER* ptu = (TOKEN_USER*)userSid;

	void* pLocalSystemSid = GetLocalSystemSid();

	bIsLocalSystem = EqualSid( pLocalSystemSid, ptu->User.Sid ) ? true : false;

	FreeSid( pLocalSystemSid );
	CloseHandle( htok );

	return bIsLocalSystem;
}

void StartAsService( int argc, const wchar_t* argv[] )
{
	wchar_t szModuleFileName[MAX_PATH];
	GetModuleFileName( 0, szModuleFileName, sizeof szModuleFileName / sizeof *szModuleFileName );

	// come up with unique name for this service
	SC_HANDLE hscm = OpenSCManager( 0, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CREATE_SERVICE );
	if ( !hscm )
		Err( L"OpenSCManager" );

	SC_HANDLE hsvc = 0;
	for ( int nRetry = 0; nRetry < 2; ++nRetry )
	{
		hsvc = CreateService(	hscm,
								L"AsPrincipal",
								L"AsPrincipal service",
								SERVICE_START | SERVICE_QUERY_STATUS | DELETE,
								SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
								SERVICE_DEMAND_START,
								SERVICE_ERROR_NORMAL,
								szModuleFileName,
								0, 0,
								0,
								0, 0 );
		if ( hsvc )
			break;
		else if ( ERROR_SERVICE_EXISTS == GetLastError() )
		{
			SC_HANDLE hsvc = OpenService( hscm, L"AsPrincipal", DELETE );
			DeleteService( hsvc );
			CloseServiceHandle( hsvc );
			hsvc = 0;
			// try again
		}
		else break;
	}		

	if ( !hsvc )
		Err( L"CreateService" );

	if ( !StartService( hsvc, argc, argv ) )
		Err( L"StartService" );

	DeleteService( hsvc );
	CloseServiceHandle( hsvc );
	CloseServiceHandle( hscm );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -