Тема: AHK: Запуск скрипта с UIAccess с токеном от системного процесса.
Нашел интересный хак: как запустить скрипт с флагом UIAccess без использования AutoHotkeyU64_UIA, а с присваиванием токена из системного процесса.
https://www.autoitscript.com/forum/topi … ccess-udf/
На ahk будет как-то так (нужно запускать скрипт от имени администратора):
#SingleInstance Force
RunWithUiAccess()
Gui, +HWNDhGui +AlwaysOnTop
DllCall("GetWindowBand", "uptr", hGui, "uint*", band)
msgbox % band
return
RunWithUiAccess()
{
Gui, +HWNDhGui +AlwaysOnTop
DllCall("GetWindowBand", "uptr", hGui, "uint*", band)
Gui, Destroy
hGui := ""
if (band = 1)
{
if !DllCall("advapi32\LookupPrivilegeValueW", "ptr", 0, "str", "SeTcbPrivilege", "int64*", luid)
{
msgbox LookupPrivilegeValueW error`n%A_LastError%
exitapp
}
VarSetCapacity(PRIVILEGE_SET, 20, 0)
NumPut(1, PRIVILEGE_SET, 0, "uint")
NumPut(PRIVILEGE_SET_ALL_NECESSARY := 1, PRIVILEGE_SET, 4, "uint")
NumPut(luid, PRIVILEGE_SET, 8, "int64")
DllCall("advapi32\OpenProcessToken", "ptr", DllCall("GetCurrentProcess", "ptr"), "uint", 0x0008|0x0002, "ptr*", hTokenSelf) ; TOKEN_QUERY|TOKEN_DUPLICATE
DllCall("advapi32\GetTokenInformation", "ptr", hTokenSelf, "uint", 12, "uint*", TokenSelfSessionId, "uint", 4, "uint*", ReturnLength)
hSnapshot := DllCall("CreateToolhelp32Snapshot", "uint", TH32CS_SNAPPROCESS := 0x00000002, "uint", 0, "ptr")
VarSetCapacity(PROCESSENTRY32, A_PtrSize*3 + 544, 0)
NumPut(A_PtrSize*3 + 544, PROCESSENTRY32, 0, "uint")
loop
{
if (A_Index = 1)
hr := DllCall("Process32FirstW", "ptr", hSnapshot, "ptr", &PROCESSENTRY32)
else
hr := DllCall("Process32NextW", "ptr", hSnapshot, "ptr", &PROCESSENTRY32)
if !hr
break
if (StrGet(&PROCESSENTRY32 + A_PtrSize*2 + 28, "utf-16") = "winlogon.exe")
{
hProcess := DllCall("OpenProcess", "uint", PROCESS_QUERY_LIMITED_INFORMATION := 0x1000, "int", false, "uint", NumGet(PROCESSENTRY32, 8, "uint"), "ptr")
DllCall("advapi32\OpenProcessToken", "ptr", hProcess, "uint", 0x0008|0x0002, "ptr*", hToken) ; TOKEN_QUERY|TOKEN_DUPLICATE
DllCall("advapi32\PrivilegeCheck", "ptr", hToken, "ptr", &PRIVILEGE_SET, "int*", pfResult)
if pfResult
{
DllCall("advapi32\GetTokenInformation", "ptr", hToken, "uint", 12, "uint*", TokenSessionId, "uint", 4, "uint*", ReturnLength)
if (TokenSessionId = TokenSelfSessionId)
{
DllCall("advapi32\GetTokenInformation", "ptr", hToken, "uint", 1, "ptr", 0, "uint", 0, "uint*", ReturnLength)
VarSetCapacity(TokenUser, ReturnLength, 0)
DllCall("advapi32\GetTokenInformation", "ptr", hToken, "uint", 1, "ptr", &TokenUser, "uint", ReturnLength, "uint*", ReturnLength)
if DllCall("advapi32\IsWellKnownSid", "ptr", NumGet(TokenUser), "uint", WinLocalSystemSid := 22)
DllCall("advapi32\DuplicateTokenEx", "ptr", hToken, "uint", TOKEN_IMPERSONATE := 0x0004, "ptr", 0, "int", SecurityImpersonation := 2, "int", TokenImpersonation := 2, "ptr*", hTokenSystem)
}
}
DllCall("CloseHandle", "ptr", hProcess)
DllCall("CloseHandle", "ptr", hToken)
if hTokenSystem
{
DllCall("CloseHandle", "ptr", hSnapshot)
break
}
}
}
if !hTokenSystem
{
msgbox RunWithUiAccess error
exitapp
}
DllCall("advapi32\SetThreadToken", "ptr", 0, "ptr", hTokenSystem)
DllCall("advapi32\DuplicateTokenEx", "ptr", hTokenSelf, "uint", 0x0008|0x0002|0x0001|0x0080, "ptr", 0, "int", SecurityAnonymous := 0, "int", TokenPrimary := 1, "ptr*", hTokenUIAccess) ; TOKEN_QUERY|TOKEN_DUPLICATE|TOKEN_ASSIGN_PRIMARY|TOKEN_ADJUST_DEFAULT
DllCall("advapi32\SetTokenInformation", "ptr", hTokenUIAccess, "uint", TokenUIAccess := 26, "uint*", true, "uint", 4)
DllCall("advapi32\RevertToSelf")
DllCall("CloseHandle", "ptr", hTokenSystem)
DllCall("CloseHandle", "ptr", hTokenSelf)
VarSetCapacity(PROCESS_INFORMATION, A_PtrSize*2 + 8, 0)
VarSetCapacity(STARTUPINFO, A_PtrSize*9 + 32, 0)
NumPut(A_PtrSize*9 + 32, STARTUPINFO, 0, "uint")
DllCall("GetStartupInfo", "ptr", &STARTUPINFO)
DllCall("advapi32\CreateProcessAsUserW", "ptr", hTokenUIAccess, "ptr", 0, "wstr", DllCall("GetCommandLineW", "wstr"), "ptr", 0, "ptr", 0, "int", 0, "uint", 0, "ptr", 0, "wstr", A_ScriptDir, "ptr", &STARTUPINFO, "ptr", &PROCESS_INFORMATION)
DllCall("CloseHandle", "ptr", NumGet(PROCESS_INFORMATION, 0, "ptr"))
DllCall("CloseHandle", "ptr", NumGet(PROCESS_INFORMATION, A_PtrSize, "ptr"))
sleep 1000
}
}