由于是脚本中剥离
1.把debug 的相关语句注释掉.
2.几个常量里面没有包含必需的常量,添加几个包含文件即可.
3.可能需要你自己改造一下,几个API不懂的话,可以百度一下它的用途.
4.如果没有system权限,搜索我的另一作品,ExecRunAs
#include <WindowsConstants.au3>
#include <ProcessConstants.au3>
#include-once
#cs ----------------------------------------------------------------------------
必须运行在服务(system)权限下,用于系统服务程序启动第三方程序与用户桌面进行交互
Opt('MustDeclareVars', 1)
RunOnDesktop(@ComSpec, False)
#ce ----------------------------------------------------------------------------
#include <winapi.au3>
#include <array.au3>
#include <security.au3>
#include <StructureConstants.au3>
#include <WinAPISys.au3>
#CS
$NULL = 0
$WTS_CURRENT_SERVER_HANDLE = $NULL
$WTSActive = 0
$WTSShadow = 1
$WTSConnectQuery = 2
$CREATE_UNICODE_ENVIRONMENT = 0x00000400
$DETACHED_PROCESS = 0x00000008
$MAX_PATH = 260
$PROCESS_ALL_ACCESS = 0x001F0FFF
;~ $TOKEN_ALL_ACCESS = 0xf01ff
$ERROR_SUCCESS = 0
Global Const $tagWTS_SESSION_INFO = 'dword SessionId;ptr WinStationName;uint State'
$NORMAL_PRIORITY_CLASS = 0x20
#CE
RunOnDesktop(StringFormat('"%s" /k whoami /all', @ComSpec), False) ;这是测试命令,编译后用system权限运行
Func RunOnDesktop($app_path, $UseSystemRights = False)
;~ Local $bReturn = False
Local $hToken = 0
Local $env = 0
Local $iConsoleID = 0
Local $iProcessPID = 0
Local $hCur = 0
Local $hCurToken = 0
Local $CREATE_NEW_CONSOLE = 0x00000010
Local $CREATE_UNICODE_ENVIRONMENT = 0x00000400
Local $NORMAL_PRIORITY_CLASS = 0x20
;Get active Desktop ID
$iConsoleID = WTSGetActiveConsoleSessionId()
$hToken = WTSQueryUserToken($iConsoleID)
CreateEnvironmentBlock($env, $hToken, False) ;设定所有帐户运行在当前桌面用户环境变量
If $UseSystemRights Then
;~ Local $iWinlogonPID = 0
;~ Local $hWinlogon = 0
;~ Local $PROCESS_ALL_ACCESS = 0x001F0FFF
;~ $iWinlogonPID = _GetWinLogonPID($iConsoleID)
;~ $hWinlogon = _WinAPI_OpenProcess($PROCESS_ALL_ACCESS, False, $iWinlogonPID) ;_ProcessGetHandle($iWinlogonPID)
;~ Local $hWinLogonToken = _Security__OpenProcessToken($hWinlogon, $TOKEN_ALL_ACCESS) ;_OpenProcessToken($hWinlogon)
;~ $hToken = _Security__DuplicateTokenEx($hWinLogonToken, $TOKEN_ALL_ACCESS, $SECURITYIMPERSONATION, $TOKENPRIMARY) ;_DuplicateToken($hToken)
;~ _WinAPI_CloseHandle($hWinLogonToken) ;
;~ _WinAPI_CloseHandle($hWinlogon) ;
$hCur = _WinAPI_GetCurrentProcess()
$hCurToken = _Security__OpenProcessToken($hCur, $TOKEN_ALL_ACCESS)
$hToken = _Security__DuplicateTokenEx($hCurToken, $TOKEN_ALL_ACCESS, $SECURITYIMPERSONATION, $TOKENPRIMARY)
Local $tTOKENSESSIONID = DllStructCreate("DWORD")
DllStructSetData($tTOKENSESSIONID, 1, $iConsoleID)
Local $ret = _Security__SetTokenInformation($hToken, $TOKENSESSIONID, $tTOKENSESSIONID, DllStructGetSize($tTOKENSESSIONID))
;~ If $bDebug Then _DebugPrint('_Security__SetTokenInformation:' & $ret) ;debug
_WinAPI_CloseHandle($hCurToken) ;
EndIf
Local $si = DllStructCreate($tagSTARTUPINFO)
Local $pi = DllStructCreate($tagPROCESS_INFORMATION)
Local $lpProcessAttributes = DllStructCreate($tagSECURITY_ATTRIBUTES)
Local $lpThreadAttributes = DllStructCreate($tagSECURITY_ATTRIBUTES)
DllStructSetData($lpThreadAttributes, "Descriptor", "")
Local $ta_size = DllStructGetSize($lpThreadAttributes)
DllStructSetData($lpThreadAttributes, "Length", $ta_size)
DllStructSetData($lpProcessAttributes, "Descriptor", "")
Local $pa_size = DllStructGetSize($lpProcessAttributes)
DllStructSetData($lpProcessAttributes, "Length", $pa_size)
DllStructSetData($si, "Desktop", "Winsta0//Default")
DllStructSetData($si, "Flags", $STARTF_USESHOWWINDOW)
DllStructSetData($si, "ShowWindow", @SW_SHOW)
Local $pi_size = DllStructGetSize($pi)
Local $si_size = DllStructGetSize($si)
DllStructSetData($pi, "Size", $pi_size)
DllStructSetData($si, "Size", $si_size)
;~ Local $ret = CreateProcessAsUser($hToken, 0, $app_path, DllStructGetPtr($lpProcessAttributes), DllStructGetPtr($lpThreadAttributes), 0, $NORMAL_PRIORITY_CLASS + $CREATE_NEW_CONSOLE, $env, "", DllStructGetPtr($si), DllStructGetPtr($pi))
Local $ret = CreateProcessAsUser($hToken, 0, $app_path, DllStructGetPtr($lpProcessAttributes), DllStructGetPtr($lpThreadAttributes), 0, $NORMAL_PRIORITY_CLASS + $CREATE_NEW_CONSOLE + $CREATE_UNICODE_ENVIRONMENT, $env, 0, DllStructGetPtr($si), DllStructGetPtr($pi))
$iProcessPID = DllStructGetData($pi, "ProcessID")
_WinAPI_CloseHandle(DllStructGetData($pi, "hProcess")) ;
_WinAPI_CloseHandle(DllStructGetData($pi, "hThread")) ;
_WinAPI_CloseHandle($hToken) ;
Return $iProcessPID
EndFunc ;==>RunOnDesktop
Func SetTBCPrivileges()
$dwPID = @AutoItPID
$hToken = 0
$hProcess = 0
$tpDebug = DllStructCreate($tagTOKEN_PRIVILEGES)
$hProcess = _WinAPI_OpenProcess($PROCESS_ALL_ACCESS, False, $dwPID)
If Not $hProcess Then Return False
;If not _WinAPI_OpenProcessToken($hProcess,$TOKEN_ALL_ACCESS,$hToken) Then return False
$hToken = _Security__OpenProcessToken($hProcess, $TOKEN_ALL_ACCESS)
If @error Then Return False
$LUID = _Security__LookupPrivilegeValue("", $SE_DEBUG_NAME)
If $LUID == 0 Then Return False
DllStructSetData($tpDebug, "Count", 1)
DllStructSetData($tpDebug, "LUID", $LUID, 1)
DllStructSetData($tpDebug, "Attributes", $SE_PRIVILEGE_ENABLED, 1)
If _Security__AdjustTokenPrivileges($hToken, False, DllStructGetPtr($tpDebug), DllStructGetSize($tpDebug), 0, 0) = False Then Return False
If _WinAPI_GetLastError() <> 0 Then Return False
_WinAPI_CloseHandle($hToken) ;
_WinAPI_CloseHandle($hProcess) ;
Return True
EndFunc ;==>SetTBCPrivileges
Func CreateEnvironmentBlock(ByRef $lpEnvironment, $hToken, $bInherit)
Local $struct = DllStructCreate("ptr")
Local $ret = DllCall('Userenv.dll', 'bool', 'CreateEnvironmentBlock', _
'ptr', DllStructGetPtr($struct), _
'HANDLE', $hToken, _
'bool', $bInherit)
$lpEnvironment = DllStructGetData($struct, 1)
Return $ret[0]
EndFunc ;==>CreateEnvironmentBlock
Func WTSGetActiveConsoleSessionId()
Local $ret = DllCall('Kernel32.dll', 'dword', 'WTSGetActiveConsoleSessionId')
Return $ret[0]
EndFunc ;==>WTSGetActiveConsoleSessionId
Func WTSQueryUserToken($SessionId)
Local $struct = DllStructCreate("HANDLE")
Local $ret = DllCall('wtsapi32.dll', 'bool', 'WTSQueryUserToken', _
'ULONG', $SessionId, _
'ptr*', DllStructGetPtr($struct))
Return $ret[2]
EndFunc ;==>WTSQueryUserToken
Func ImpersonateLoggedOnUser(ByRef $hToken)
Local $aResult = DllCall("advapi32.dll", "int", "ImpersonateLoggedOnUser", "hwnd", $hToken)
If @error Then Return SetError(@error, @extended, 0)
Return SetError(0, 0, $aResult[0] <> 0)
EndFunc
Func _TSSendConsoleMessage($ButtonSet, $TitleText, $MessageText, $Timeout = 10, $Wait = False)
$TitleText = StringToBinary($TitleText, 1)
Local $pTitle = DllStructCreate('byte Title[' & BinaryLen($TitleText) + 1 & ']')
DllStructSetData($pTitle, 'Title', $TitleText)
$MessageText = StringToBinary($MessageText, 1)
Local $pMessage = DllStructCreate('byte Message[' & BinaryLen($MessageText) + 1 & ']')
DllStructSetData($pMessage, 'Message', $MessageText)
Local $pResponse = DllStructCreate("DWORD Response")
Local $SessionId = WTSGetActiveConsoleSessionId()
DllStructSetData($pTitle, "Title", $TitleText)
DllStructSetData($pMessage, "Message", $MessageText)
Local $Res = DllCall("Wtsapi32.dll", "BOOL", "WTSSendMessageA", "HANDLE", "WTS_CURRENT_SERVER_HANDLE", "DWORD", $SessionId, "ptr", DllStructGetPtr($pTitle), "DWORD", DllStructGetSize($pTitle), "ptr", DllStructGetPtr($pMessage), "DWORD", DllStructGetSize($pMessage), "DWORD", $ButtonSet, "DWORD", $Timeout, "DWORD", DllStructGetPtr($pResponse), "BOOL", $Wait)
Return $Res[0]
EndFunc ;==>_TSSendConsoleMessage
Func CreateProcessAsUser($hToken, $lpApplicationName, $lpCommandline, $lpProcessAttributes, $lpThreadAttributes, $bInheritHandles, $dwCreationFlags, $lpEnvironment, $lpCurrentDirectory, $lpStartupInfo, $lpProcessInformation)
Local $ret = DllCall("advapi32.dll", "bool", "CreateProcessAsUserW", _ ; W is better
"handle", $hToken, _
"ptr", $lpApplicationName, _ ;$lpApplicationName, _
"wstr", $lpCommandline, _ ; wstr for CreateProcessAsUserW
"ptr", $lpProcessAttributes, _
"ptr", $lpThreadAttributes, _
"bool", $bInheritHandles, _ ;$bInheritHandles, _
"dword", $dwCreationFlags, _
"ptr", $lpEnvironment, _
"ptr", $lpCurrentDirectory, _
"ptr", $lpStartupInfo, _
"ptr", $lpProcessInformation)
;If $ret[0] = 0 Then _MsgBox(16, "proc e "&@error&" "&$hToken, _WinAPI_GetLastErrorMessage())
If $ret[0] = 0 Then Return SetError(_WinAPI_GetLastError(), 0, _WinAPI_GetLastErrorMessage())
Return $ret[0]
EndFunc ;==>CreateProcessAsUser
Func _GetWinLogonPID($iActiveSession)
Local $aWinlogon, $i
$aWinlogon = ProcessList("winlogon.exe")
For $i = 1 To $aWinlogon[0][0]
If $iActiveSession = _ProcessGetSessionID($aWinlogon[$i][1]) Then
Return $aWinlogon[$i][1]
EndIf
Next
Return 0
EndFunc ;==>_GetWinLogonPID
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 _GetUserName()
Local $aDLL = DllCall("Advapi32.dll", "int", "GetUserNameW", "wstr", "", "dword*", 255)
If @error Then Return SetError(@error, 0, '')
Return $aDLL[1]
EndFunc ;==>_GetUserName
Func _ProcessListOWNER_WTS($PID = 0)
;~ $temp[0][0]="Process"
;~ $temp[0][1]="ProcessId"
;~ $temp[0][2]="SessionId"
;~ $temp[0][3]="ProcessOWNER"
Local $tag_WTS_PROCESS_INFO = _
"DWORD SessionId;" & _
"DWORD ProcessId;" & _
"PTR pProcessName;" & _
"PTR pUserSid"
Local $i, $ret, $ret1, $mem, $string
$ret = DllCall("WTSApi32.dll", "int", "WTSEnumerateProcesses", "int", 0, "int", 0, "int", 1, "ptr*", 0, "int*", 0)
Local $array[$ret[5]][4]
$mem = DllStructCreate($tag_WTS_PROCESS_INFO, $ret[4])
For $i = 0 To $ret[5] - 1
$mem = DllStructCreate($tag_WTS_PROCESS_INFO, $ret[4] + ($i * DllStructGetSize($mem)))
;if DllStructGetData($mem, "pProcessName") Then
$string = DllStructCreate("char[256]", DllStructGetData($mem, "pProcessName"))
$array[$i][0] = DllStructGetData($string, 1)
;EndIf
$array[$i][1] = DllStructGetData($mem, "ProcessId")
$array[$i][2] = DllStructGetData($mem, "SessionId")
;if DllStructGetData($mem, "pUserSid") Then
$ret1 = _Security__LookupAccountSid(DllStructGetData($mem, "pUserSid"))
If IsArray($ret1) Then $array[$i][3] = $ret1[0]
;EndIf
Next
DllCall("WTSApi32.dll", "int", "WTSFreeMemory", "int", $ret[4])
If $PID Then
For $i = 0 To UBound($array, 1) - 1
If $array[$i][1] = $PID Then
Return $array[$i][2] & '|' & $array[$i][3]
EndIf
Next
EndIf
Return $array
EndFunc ;==>_ProcessListOWNER_WTS
|