Func _RunSystemFile($File = "")
If $File = "" Then Return 0
Local $tProcessInfo = _SeCreateHighSystemProcess($File)
Local $iError = @error
Local $iExtended = @extended
If IsDllStruct($tProcessInfo) Then
;MsgBox(48, "OK", "Done", 2)
Local $hProcess = DllStructGetData($tProcessInfo, "hProcess") ; 进程句柄。
Local $hThread = DllStructGetData($tProcessInfo, "hThread") ; 主线程句柄。
Local $iProcessID = DllStructGetData($tProcessInfo, "ProcessID") ; 进程ID。
Local $iThreadID = DllStructGetData($tProcessInfo, "ThreadID") ; 主线程ID。
;TODO: do something...
;关闭进、线程句柄。
DllCall("Kernel32.dll", "bool", "CloseHandle", "handle", $hProcess)
DllCall("Kernel32.dll", "bool", "CloseHandle", "handle", $hThread)
Return $iProcessID
Else
;MsgBox(16, "Error", StringFormat("error=%d, extended=%d\n", $iError, $iExtended))
Return 0
EndIf
EndFunc
Func _SeImpersonateHighSystemContext($iImpersonationLevel, $iDesiredAccess)
Local $iResult
; get system id.
; =========================================================================================================================
$iResult = DllCall("Ntdll.dll", "ulong", "CsrGetProcessId")
Local $iProcessID = $iResult[0]
If $iProcessID == 0 Then Return SetError(1359, 1, 0) ; 1359=ERROR_INTERNAL_ERROR
$iResult = DllCall("Ntdll.dll", "long", "NtQuerySystemInformation", "ulong", 5, "ptr", 0, "ulong", 0, "ulong*", 0)
If $iResult[4] == 0 Then Return SetError($iResult[0], 2, 0)
Local $tBuffer = DllStructCreate("ubyte Data[" & $iResult[4] & "]")
Local $pBuffer = DllStructGetPtr($tBuffer)
$iResult = DllCall("Ntdll.dll", "long", "NtQuerySystemInformation", "ulong", 5, "ptr", $pBuffer, "ulong", $iResult[4], "ulong*", 0)
If $iResult[0] < 0 Then Return SetError($iResult[0], 3, 0)
Local $iOffset, $tProcessInfo, $iSystemID
Local Const $tagVM_COUNTERS = "ULONG_PTR PeakVirtualSize;ULONG_PTR VirtualSize;DWORD PageFaultCount;ULONG_PTR PeakWorkingSetSize;ULONG_PTR WorkingSetSize;ULONG_PTR QuotaPeakPagedPoolUsage;ULONG_PTR QuotaPagedPoolUsage;ULONG_PTR QuotaPeakNonPagedPoolUsage;ULONG_PTR QuotaNonPagedUsage;ULONG_PTR PagefileUsage;ULONG_PTR PeakPagefileUsage;"
Local Const $tagIO_COUNTERS = "INT64 ReadOperationCount;INT64 WriteOperationCount;INT64 OtherOperationCount;INT64 ReadTransferCount;INT64 WriteTransferCount;INT64 OtherTransferCount;"
If @AutoItX64 Then
Local $tagSYSTEM_THREAD = "INT64 KernelTime;INT64 UserTime;INT64 CreateTime;ULONG WaitTime;ULONG_PTR Reserved3;PTR StartAddress;ULONG_PTR UniqueProcessId;ULONG_PTR UniqueThreadId;ULONG Priority;ULONG BasePriority;ULONG ContextSwitchCount;ULONG State;ULONG WaitReason;"
Else
Local $tagSYSTEM_THREAD = "INT64 KernelTime;INT64 UserTime;INT64 CreateTime;ULONG WaitTime;PTR StartAddress;ULONG_PTR UniqueProcessId;ULONG_PTR UniqueThreadId;ULONG Priority;ULONG BasePriority;ULONG ContextSwitchCount;ULONG State;ULONG WaitReason;"
EndIf
Local Const $tagSYSTEM_PROCESS_INFORMATION = "ULONG NextEntryOffset;ULONG NumberOfThreads;INT64 Reserved[3];INT64 CreateTime;INT64 UserTime;INT64 KernelTime;WORD Length;WORD MaximumLength;PTR ImageName;ULONG BasePriority;ULONG_PTR ProcessId;ULONG_PTR InheritedFromProcessId;ULONG HandleCount;ULONG Reserved[2];ULONG PrivatePageCount;" & $tagVM_COUNTERS & $tagIO_COUNTERS & $tagSYSTEM_THREAD
While 1
$tProcessInfo = DllStructCreate($tagSYSTEM_PROCESS_INFORMATION, $pBuffer)
$iOffset = DllStructGetData($tProcessInfo, "NextEntryOffset")
If DllStructGetData($tProcessInfo, "ProcessId") == $iProcessID Then
$iSystemID = DllStructGetData($tProcessInfo, "UniqueThreadId")
ExitLoop
Else
If $iOffset Then
$pBuffer += $iOffset
Else
ExitLoop
EndIf
EndIf
WEnd
If $iSystemID = 0 Then Return SetError(1359, 4, 0)
; =========================================================================================================================
; enable Debug privilege.
; =========================================================================================================================
$iResult = DllCall("Advapi32.dll", "bool", "OpenProcessToken", "handle", -1, "dword", 0x0020, "handle*", 0)
Local $hToken = $iResult[3]
If $hToken = 0 Then Return SetError(_s2er(0), 5, 0)
Local $tTokenPrivileges = DllStructCreate("DWORD PrivilegeCount;DWORD LowPart;LONG HighPart;DWORD Attributes")
Local $pTokenPrivileges = DllStructGetPtr($tTokenPrivileges)
DllStructSetData($tTokenPrivileges, "PrivilegeCount", 1)
DllStructSetData($tTokenPrivileges, "Attributes", 2) ; 2=SE_PRIVILEGE_ENABLED
$iResult = DllCall("Advapi32.dll", "bool", "LookupPrivilegeValueW", "ptr", 0, "wstr", "SeDebugPrivilege", "ptr", DllStructGetPtr($tTokenPrivileges, "LowPart"))
If Not $iResult[0] Then
; handle error
EndIf
DllCall("Kernel32.dll", "none", "SetLastError", "dword", 0)
DllCall("Advapi32.dll", "bool", "AdjustTokenPrivileges", "handle", $hToken, "bool", 0, "ptr", $pTokenPrivileges, "dword", 0, "ptr", 0, "ptr", 0)
$iResult = DllCall("Kernel32.dll", "dword", "GetLastError")
If $iResult[0] = 1300 Then ; 1300=ERROR_NOT_ALL_ASSIGNED
; not all privileges are assigned.
EndIf
DllCall("Kernel32.dll", "bool", "CloseHandle", "handle", $hToken)
; =========================================================================================================================
; impersonate security context.
; =========================================================================================================================
$iResult = DllCall("Kernel32.dll", "handle", "OpenThread", "dword", 0x0200, "bool", 0, "dword", $iSystemID)
Local $hThread = $iResult[0]
If $hThread = 0 Then Return SetError(_s2er(0), 6, 0)
Local $tSecurityQos = DllStructCreate("DWORD Length;DWORD ImpersonationLevel;BOOLEAN ContextTrackingMode;BOOLEAN EffectiveOnly")
Local $pSecurityQos = DllStructGetPtr($tSecurityQos)
DllStructSetData($tSecurityQos, "Length", DllStructGetSize($tSecurityQos))
DllStructSetData($tSecurityQos, "ImpersonationLevel", $iImpersonationLevel)
DllStructSetData($tSecurityQos, "ContextTrackingMode", 0)
DllStructSetData($tSecurityQos, "EffectiveOnly", 0)
$iResult = DllCall("Ntdll.dll", "long", "NtImpersonateThread", "handle", -2, "handle", $hThread, "ptr", $pSecurityQos)
DllCall("Kernel32.dll", "bool", "CloseHandle", "handle", $hThread)
If $iResult[0] < 0 Then Return SetError($iResult[0], 7, 0)
; =========================================================================================================================
; open impersonation token.
$iResult = DllCall("Advapi32.dll", "bool", "OpenThreadToken", "handle", -2, "dword", $iDesiredAccess, "boolean", 0, "handle*", 0)
If $iResult[0] Then
Return $iResult[4]
Else
Return SetError(_s2er(0), 8, 0)
EndIf
EndFunc ;==>_SeImpersonateSystemContext
Func _SeCreateHighSystemProcess($sCommandLine, $sWorkingDir = @WorkingDir, $iShowCmd = @SW_SHOWNORMAL) ;与Service.au3的函数重名,改名处理
Local $hImpersonationToken = _SeImpersonateHighSystemContext(2, 0x0F01FF)
If $hImpersonationToken = 0 Then Return SetError(@error, @extended, 0)
Local $iResult
; enable privileges
; =========================================================================================================================
Local $tTokenPrivileges = DllStructCreate("DWORD;DWORD;LONG;DWORD;DWORD;LONG;DWORD")
Local $pTokenPrivileges = DllStructGetPtr($tTokenPrivileges)
DllStructSetData($tTokenPrivileges, 1, 1)
DllStructSetData($tTokenPrivileges, 4, 2) ; 2=SE_PRIVILEGE_ENABLED
DllStructSetData($tTokenPrivileges, 7, 2) ; 2=SE_PRIVILEGE_ENABLED
$iResult = DllCall("Advapi32.dll", "bool", "LookupPrivilegeValueW", "ptr", 0, "wstr", "SeAssignPrimaryTokenPrivilege", "ptr", DllStructGetPtr($tTokenPrivileges, 2))
$iResult = DllCall("Advapi32.dll", "bool", "LookupPrivilegeValueW", "ptr", 0, "wstr", "SeTcbPrivilege", "ptr", DllStructGetPtr($tTokenPrivileges, 5))
If Not $iResult[0] Then
; handle error
EndIf
DllCall("Kernel32.dll", "none", "SetLastError", "dword", 0)
DllCall("Advapi32.dll", "bool", "AdjustTokenPrivileges", "handle", $hImpersonationToken, "bool", 0, "ptr", $pTokenPrivileges, "dword", 0, "ptr", 0, "ptr", 0)
$iResult = DllCall("Kernel32.dll", "dword", "GetLastError")
If $iResult[0] = 1300 Then ; 1300=ERROR_NOT_ALL_ASSIGNED
; not all privileges are assigned.
EndIf
; =========================================================================================================================
; adjust session ID
; =========================================================================================================================
$iResult = DllCall("Kernel32.dll", "dword", "WTSGetActiveConsoleSessionId")
$iResult = DllCall("Advapi32.dll", "bool", "SetTokenInformation", "handle", $hImpersonationToken, "ulong", 12, "dword*", $iResult[0], "dword", 4)
If Not $iResult[0] Then
; handle error
EndIf
; =========================================================================================================================
$iResult = DllCall("Advapi32.dll", "bool", "GetTokenInformation", "handle", $hImpersonationToken, "ulong", 9, "dword*", 0, "dword", 4, "dword*", 0)
If $iResult[3] <> 2 Then ; 2=SecurityImpersonation
; handle error
EndIf
$iResult = DllCall("Advapi32.dll", "bool", "DuplicateTokenEx", "handle", $hImpersonationToken, "dword", 0x0F01FF, "ptr", 0, "dword", 0, "dword", 1, "handle*", 0)
Local $hPrimaryToken = $iResult[6]
If $hPrimaryToken = 0 Then Return SetError(_s2er(0), 9, 0)
If $sWorkingDir == "" Then $sWorkingDir = @WorkingDir
Local Const $tagPROCESS_INFORMATION = "HANDLE hProcess;HANDLE hThread;DWORD ProcessID;DWORD ThreadID"
Local Const $tagSTARTUPINFO = "DWORD Length;PTR Reserved;PTR Desktop;PTR Title;DWORD X;DWORD Y;DWORD XSize;DWORD YSize;DWORD XCountChars;DWORD YCountChars;DWORD FillAttributes;DWORD Flags;WORD ShowWindow;WORD Reserved2;PTR Reserved3;HANDLE StdInput;HANDLE StdOutput;HANDLE StdError"
Local $tProcessInfo = DllStructCreate($tagPROCESS_INFORMATION)
Local $pProcessInfo = DllStructGetPtr($tProcessInfo)
Local $tStartupInfo = DllStructCreate($tagSTARTUPINFO)
Local $pStartupInfo = DllStructGetPtr($tStartupInfo)
DllStructSetData($tStartupInfo, "Length", DllStructGetSize($tStartupInfo))
If @NumParams > 2 Then
If IsKeyword($iShowCmd) Then $iShowCmd = @SW_SHOWNORMAL
DllStructSetData($tStartupInfo, "ShowWindow", $iShowCmd)
DllStructSetData($tStartupInfo, "Flags", 1)
EndIf
$iResult = DllCall("Advapi32.dll", "bool", "CreateProcessAsUserW", "handle", $hPrimaryToken, "ptr", 0, "wstr", $sCommandLine, "ptr", 0, "ptr", 0, "bool", 0, "dword", 0, "ptr", 0, "wstr", $sWorkingDir, "ptr", $pStartupInfo, "ptr", $pProcessInfo)
Local $iError = _s2er($iResult[0])
DllCall("Advapi32.dll", "bool", "RevertToSelf")
DllCall("Kernel32.dll", "bool", "CloseHandle", "handle", $hImpersonationToken)
DllCall("Kernel32.dll", "bool", "CloseHandle", "handle", $hPrimaryToken)
If $iResult[0] Then
Return $tProcessInfo
Else
Return SetError($iError, 10, 0)
EndIf
EndFunc ;==>_SeCreateSystemProcess
Func _s2er($iResult)
If $iResult Then
Return 0
Else
$iResult = DllCall("Kernel32.dll", "long", "GetLastError")
Return $iResult[0]
EndIf
EndFunc ;==>s2er