function RunAs(User, Password, Command: String): Integer; var dwSize: DWORD; hToken: THandle; lpvEnv: Pointer; pi: TProcessInformation; si: TStartupInfo; szPath: Array [0..MAX_PATH] of WideChar; begin ZeroMemory(@szPath, SizeOf(szPath)); ZeroMemory(@pi, SizeOf(pi)); ZeroMemory(@si, SizeOf(si)); si.cb:=SizeOf(TStartupInfo);
if LogonUser(PChar(User), nil, PChar(Password), LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, hToken) then begin if CreateEnvironmentBlock(lpvEnv, hToken, True) then begin dwSize:=SizeOf(szPath) div SizeOf(WCHAR); if (GetCurrentDirectoryW(dwSize, @szPath) > 0) then begin if (CreateProcessWithLogon(PWideChar(WideString(User)), nil, PWideChar(WideString(Password)), LOGON_WITH_PROFILE, nil, PWideChar(WideString(Command)), CREATE_UNICODE_ENVIRONMENT, lpvEnv, szPath, si, pi)) then begin result:=ERROR_SUCCESS; CloseHandle(pi.hProcess); CloseHandle(pi.hThread); end else result:=GetLastError; end else result:=GetLastError; DestroyEnvironmentBlock(lpvEnv); end else result:=GetLastError; CloseHandle(hToken); end else result:=GetLastError; end;
function CreateLowIntegrityProcess(const ExeName: string; const Params: string = ”; TimeOut: DWORD = 0): HResult; function GetIntegrityLevel(): DWORD;
implementation
type PTokenMandatoryLabel = ^TTokenMandatoryLabel;
TTokenMandatoryLabel = packed record Label_: TSidAndAttributes; end;
function GetIntegrityLevel(): DWORD; var hProcess, hToken: THandle; pTIL: PTokenMandatoryLabel; dwReturnLength: DWORD; dwTokenUserLength: DWORD; psaCount: PUCHAR; SubAuthority: DWORD; begin Result := 0; dwReturnLength := 0; dwTokenUserLength := 0; pTIL := nil;
hProcess := GetCurrentProcess(); OpenProcessToken(hProcess, TOKEN_QUERY or TOKEN_QUERY_SOURCE, hToken); if hToken = 0 then Exit; if not GetTokenInformation(hToken, WinApi.Windows.TTokenInformationClass (TokenIntegrityLevel), pTIL, dwTokenUserLength, dwReturnLength) then begin if GetLastError = ERROR_INSUFFICIENT_BUFFER then Begin pTIL := Pointer(LocalAlloc(0, dwReturnLength)); if pTIL = nil then Exit; dwTokenUserLength := dwReturnLength; dwReturnLength := 0;
if GetTokenInformation(hToken, WinApi.Windows.TTokenInformationClass (TokenIntegrityLevel), pTIL, dwTokenUserLength, dwReturnLength) and IsValidSid((pTIL.Label_).Sid) then begin psaCount := GetSidSubAuthorityCount((pTIL.Label_).Sid); SubAuthority := psaCount^; SubAuthority := SubAuthority – 1; Result := GetSidSubAuthority((pTIL.Label_).Sid, SubAuthority)^; end; LocalFree(Cardinal(pTIL)); End; end;
CloseHandle(hToken); end;
const userenvlib = ‘userenv.dll’;
function CreateEnvironmentBlock(lpEnvironment: PPointer; hToken: THandle; bInherit: BOOL): BOOL; stdcall; external userenvlib; function DestroyEnvironmentBlock(lpEnvironment: Pointer): BOOL; stdcall; external userenvlib;
function CreateLowIntegrityProcess(const ExeName, Params: string; TimeOut: DWORD): HResult; type _TOKEN_MANDATORY_LABEL = Record Label_: SID_AND_ATTRIBUTES; End;
try // 从自己获取一个令牌 if (not OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE or TOKEN_QUERY or TOKEN_ADJUST_DEFAULT or TOKEN_ASSIGN_PRIMARY, hToken)) then begin Result := GetLastError(); Exit; end;
// 复制令牌 if (not DuplicateTokenEx(hToken, 0, nil, SecurityImpersonation, TokenPrimary, hNewToken)) then begin Result := GetLastError(); Exit; end;
// 创建一个低权限的SID if (not AllocateAndInitializeSid(MLAuthority, 1, SECURITY_MANDATORY_LOW_RID, 0, 0, 0, 0, 0, 0, 0, pIntegritySid)) then begin Result := GetLastError(); Exit; end;
// 设置这个低权限SID到令牌 if (not SetTokenInformation(hNewToken, TokenIntegrityLevel, @tml, (sizeof(tml) + GetLengthSid(pIntegritySid)))) then begin Result := GetLastError(); Exit; end;
// 创建一个环境变量 if (CreateEnvironmentBlock(@pEnvironment, hToken, FALSE)) then dwCreationFlag := dwCreationFlag or CREATE_UNICODE_ENVIRONMENT else pEnvironment := nil;
// 创建一个低权限的进程 if (not CreateProcessAsUser(hNewToken, nil, PChar(pszCommandLine), nil, nil, FALSE, dwCreationFlag, pEnvironment, nil, si, pi)) then begin Result := GetLastError(); Exit; end;
WaitForSingleObject(pi.hProcess, TimeOut); finally // 清理现场 if pEnvironment <> nil then begin DestroyEnvironmentBlock(pEnvironment); pEnvironment := nil; end;
if (hToken <> 0) then begin CloseHandle(hToken); hToken := 0; end; if (hNewToken <> 0) then begin CloseHandle(hNewToken); hNewToken := 0; end; if (pIntegritySid <> nil) then begin FreeSid(pIntegritySid); pIntegritySid := nil; end; if (pi.hProcess <> 0) then begin CloseHandle(pi.hProcess); pi.hProcess := 0; end; if (pi.hThread <> 0) then begin CloseHandle(pi.hThread); pi.hThread := 0; end;
if (ERROR_SUCCESS <> Result) then begin SetLastError(Result); end else begin Result := ERROR_SUCCESS; end; end; end;
function GetProcessByName(const szFileName: String): THANDLE; var dwProcessIds: array[0..MAXWORD] of DWORD; cbNeeded: DWORD; nIndex, nCount: Integer; hProcess, hModule: THANDLE; pszProcessName: array[0..MAXWORD] of Char; begin if (not EnumProcesses(@dwProcessIds[0], SizeOf(dwProcessIds), cbNeeded)) then Exit(0);
nCount := cbNeeded div SizeOf(DWORD); for nIndex := 0 to nCount - 1 do begin hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, FALSE, dwProcessIds[nIndex]); if (0 = hProcess) then Continue;
pszProcessName[0] := #0; if (EnumProcessModules(hProcess, @hModule, SizeOf(hModule), cbNeeded)) then begin GetModuleBaseName(hProcess, hModule, pszProcessName, SizeOf(pszProcessName) div SizeOf(Char));
if SameText(ExtractFileName(pszProcessName), szFileName) then Exit(hProcess); end;
CloseHandle(hProcess); end;
Exit(0); end;
function GetTokenByName(const szFileName: String): THANDLE; var hProcess: THANDLE; begin hProcess := GetProcessByName(szFileName); if (0 = hProcess) then Exit(0);
if (not OpenProcessToken(hProcess, TOKEN_ALL_ACCESS, Result)) then Result := 0;
CloseHandle(hProcess); end;
function CreateProcessAsExplorer(const szAppName: String; const szParameters: String = ''): BOOL; var pStartupInfo: TStartupInfo; pProcessInfo: TProcessInformation; pszAppName, pszParameters: PChar; hToken: THANDLE; begin GetStartupInfo(pStartupInfo); if ('' = szAppName) then pszAppName := nil else pszAppName := PChar(szAppName);
if ('' = szParameters) then pszParameters := nil else pszParameters := PChar(szParameters);
if (0 <> pProcessInfo.hProcess) then begin CloseHandle(pProcessInfo.hThread); CloseHandle(pProcessInfo.hProcess); Exit(TRUE); end else begin ShowMessage(SysErrorMessage(GetLastError())); Exit(FALSE); end; end;
----------------------------------------------
--