Run script as UIAccess with stealing token from system process.

Post your working scripts, libraries and tools for AHK v1.1 and older
malcev
Posts: 1769
Joined: 12 Aug 2014, 12:37

Run script as UIAccess with stealing token from system process.

10 Jul 2023, 01:05

Found interesting hack: how to execute script with UIAccess flag without using AutoHotkeyU64_UIA:, but with stealing token from system process.
https://www.autoitscript.com/forum/topic/210526-make-your-program-super-topmost-uiaccess-udf/
On ahk can be run like this (need to run script as admin):

Code: Select all

#SingleInstance Force
RunWithUiAccess()

; Your code here
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)
                  VarSetCapacity(name, 512, 0)
                  DllCall("advapi32\LookupAccountSid", "ptr", 0, "ptr", NumGet(TokenUser), "str", name, "uint*", 256, "str", "", "uint*", 256, "uint*", SID_NAME_USE)
                  if (name = "SYSTEM")
                     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
   }
}
User avatar
WAZAAAAA
Posts: 88
Joined: 13 Jan 2015, 19:48

Re: Run script as UIAccess with stealing token from system process.

06 Nov 2023, 14:55

Criminally underrated post, thank you for this.

Normally, the steps needed to give UIAccess to an AHK script are limited and painful.

But with this token trick the only """downside""" you have to endure is to simply let the script restart itself twice: once for admin rights, once for UIAccess.
It will work both compiled and uncompiled. No digital signature required. No need to force users to reinstall AHK with the "Add 'Run with UI Access' to context menus" option checked. No "running only from protected folder paths" bs. Just great. (tested on Win10 LTSC 2021)
YOU'RE NOT ALEXANDER

Return to “Scripts and Functions (v1)”

Who is online

Users browsing this forum: fiendhunter and 70 guests