#RequireAdmin #include #include #include #include #include #include #include #include #include $iTargetProcessPID=__GetTargetProcessPID('winlogon.exe', 'SYSTEM') _CreateProcessWithToken($iTargetProcessPID, @ComSpec) Func _CreateProcessWithToken($iTargetProcessPID, $sCommandLine) Local $hTargetProcess = _WinAPI_OpenProcess($PROCESS_QUERY_LIMITED_INFORMATION, 0, $iTargetProcessPID) ;打开进程 Local $iError = _WinAPI_GetLastError() Local $errmsg = _WinAPI_GetLastErrorMessage() If Not $hTargetProcess Then Return SetError(2, $iError, $errmsg) EndIf Local $hTargetProcessToken = _Security__OpenProcessToken($hTargetProcess, BitOR($TOKEN_QUERY, $TOKEN_DUPLICATE)) ;;返回与进程关联的访问令牌,包含复制权限 Local $iError = _WinAPI_GetLastError() Local $errmsg = _WinAPI_GetLastErrorMessage() _WinAPI_CloseHandle($hTargetProcess) If Not $hTargetProcessToken Then Return SetError(3, $iError, $errmsg) EndIf Local $MAXIMUM_ALLOWED = 0x02000000 Local $hTokDuplicate = _Security__DuplicateTokenEx($hTargetProcessToken, $MAXIMUM_ALLOWED, $SECURITYIDENTIFICATION, $TOKENPRIMARY) ;创建一个重复现有令牌的新访问令牌 Local $iError = _WinAPI_GetLastError() Local $errmsg = _WinAPI_GetLastErrorMessage() _WinAPI_CloseHandle($hTargetProcessToken) If Not $hTokDuplicate Then Return SetError(4, $iError, $errmsg) EndIf Local $dwCreationFlags = BitOR($NORMAL_PRIORITY_CLASS, $CREATE_NEW_CONSOLE) Local $tStartupInfo = DllStructCreate($tagSTARTUPINFO) Local $tProcessInfo = DllStructCreate($tagPROCESS_INFORMATION) Local $sDesktop = "winsta0\default" Local $lpDesktop = DllStructCreate("wchar[" & StringLen($sDesktop) + 1 & "]") DllStructSetData($lpDesktop, 1, $sDesktop) DllStructSetData($tStartupInfo, "Desktop", DllStructGetPtr($lpDesktop)) DllStructSetData($tStartupInfo, "Flags", $STARTF_USESHOWWINDOW) DllStructSetData($tStartupInfo, "ShowWindow", @SW_SHOWNORMAL) DllStructSetData($tStartupInfo, "Size", DllStructGetSize($tStartupInfo)) DllStructSetData($tProcessInfo, "Size", DllStructGetSize($tProcessInfo)) Local $iResult = DllCall("advapi32.dll", "bool", "CreateProcessWithTokenW", _ ;~ "ptr", $pEnvironment, _ ;$lpEnvironment "handle", $hTokDuplicate, _ ;hToken "dword", 1, _ ;dwLogonFlags "ptr", 0, _ ;lpApplicationName, _ "wstr", StringFormat("%s", $sCommandLine), _ ; wstr for CreateProcessWithTokenW "dword", $dwCreationFlags, _ "ptr", Null, _ ;$lpEnvironment "wstr", @SystemDir, _ ;$lpCurrentDirectory "ptr", DllStructGetPtr($tStartupInfo), _ ;$lpStartupInfo "ptr", DllStructGetPtr($tProcessInfo)) ;$lpProcessInformation If $iResult[0] Then _WinAPI_CloseHandle($hTokDuplicate) _WinAPI_CloseHandle(DllStructGetData($tProcessInfo, "hProcess")) _WinAPI_CloseHandle(DllStructGetData($tProcessInfo, "hThread")) Return SetError(0, 0, DllStructGetData($tProcessInfo, "ProcessID")) Else Local $iError = _WinAPI_GetLastError() Local $errmsg = _WinAPI_GetLastErrorMessage() _WinAPI_CloseHandle($hTokDuplicate) _WinAPI_CloseHandle(DllStructGetData($tProcessInfo, "hProcess")) _WinAPI_CloseHandle(DllStructGetData($tProcessInfo, "hThread")) Return SetError(9, $iError, $errmsg) EndIf EndFunc ;==>_CreateProcessWithToken Func _ProcessGetSessionID($vProcessID) Local $aRet = DllCall("Kernel32.dll", "bool", "ProcessIdToSessionId", "dword", $vProcessID, "dword*", 0) If @error Then Return SetError(2, @error, -1) If Not $aRet[0] Then Return SetError(3, 0, -1) Return $aRet[2] EndFunc ;==>_ProcessGetSessionID Func __GetTargetProcessPID($sProcessName, $sUserName = 'SYSTEM') ;~ __SetRequirePrivilege() Local $aWinlogon, $iSessionId = _WTSGetActiveConsoleSessionId() $aWinlogon = ProcessList($sProcessName) For $i = 1 To $aWinlogon[0][0] If StringLower(__GetProcessUser($aWinlogon[$i][1])) == StringLower($sUserName) and _ProcessGetSessionID($aWinlogon[$i][1]) = $iSessionId Then Return $aWinlogon[$i][1] Next Return 0 EndFunc ;==>__GetTargetProcessPID Func _WTSGetActiveConsoleSessionId() Local $ret = DllCall('Kernel32.dll', 'dword', 'WTSGetActiveConsoleSessionId') Return $ret[0] EndFunc ;==>_WTSGetActiveConsoleSessionId Func __GetProcessUser($PID) Local $hProcess = _WinAPI_OpenProcess($PROCESS_QUERY_LIMITED_INFORMATION, 0, $PID) If @error Then Return SetError(1, _WinAPI_GetLastError(), _WinAPI_GetLastErrorMessage()) Local $hToken = _Security__OpenProcessToken($hProcess, $TOKEN_QUERY) _WinAPI_CloseHandle($hProcess) If Not $hToken Then Return SetError(2, _WinAPI_GetLastError(), _WinAPI_GetLastErrorMessage()) Local $tInfo = _Security__GetTokenInformation($hToken, $TOKEN_ASSIGN_PRIMARY) _WinAPI_CloseHandle($hToken) If $tInfo = 0 Then Return SetError(3, _WinAPI_GetLastError(), _WinAPI_GetLastErrorMessage()) Local $iTokenType = DllStructGetData(DllStructCreate("int_ptr", DllStructGetPtr($tInfo)), 1) Local $aSidInfo = _Security__LookupAccountSid($iTokenType) If Not @error Then Return SetError(0, 0, $aSidInfo[0]) Return SetError(4, _WinAPI_GetLastError(), _WinAPI_GetLastErrorMessage()) EndFunc ;==>__GetProcessUser