Тема: AHK: Process is admin
Как возможно определить запущен ли сторонний процесс с правами администратора?
Win10x64 AhkSpy, Hotkey, ClockGui
Вы не вошли. Пожалуйста, войдите или зарегистрируйтесь.
Страницы 1
Чтобы отправить ответ, вы должны войти или зарегистрироваться
Как возможно определить запущен ли сторонний процесс с правами администратора?
; ===============================================================================================================================
; Check if a process is elevated
; ===============================================================================================================================
IsProcessElevated(ProcessID)
{
if !(hProcess := DllCall("OpenProcess", "uint", 0x0400, "int", 0, "uint", ProcessID, "ptr"))
throw Exception("OpenProcess failed", -1)
if !(DllCall("advapi32\OpenProcessToken", "ptr", hProcess, "uint", 0x0008, "ptr*", hToken))
throw Exception("OpenProcessToken failed", -1), DllCall("CloseHandle", "ptr", hProcess)
if !(DllCall("advapi32\GetTokenInformation", "ptr", hToken, "int", 20, "uint*", IsElevated, "uint", 4, "uint*", size))
throw Exception("GetTokenInformation failed", -1), DllCall("CloseHandle", "ptr", hToken) && DllCall("CloseHandle", "ptr", hProcess)
return IsElevated, DllCall("CloseHandle", "ptr", hToken) && DllCall("CloseHandle", "ptr", hProcess)
}
; ===============================================================================================================================
MsgBox % IsProcessElevated(DllCall("GetCurrentProcessId"))
; 0 => Process is not elevated
; 1 => Process is elevated
На WIN10x64 может кто посмотреть, вроде не работает.
На админе всё равно ноль выдаёт.
Или такое сочетание PROCESS_QUERY_INFORMATION|PROCESS_VM_READ может помешать.
PROCESS_QUERY_INFORMATION := 0x400, PROCESS_VM_READ := 0x10
У меня единицу выдаёт.
serzh82saratov, У меня на WIN10x64 всё работает.
Спасибо за тесты. Я добавил это в ахкспай, отдельную функцию делать не хочу.
Так работает?
SeDebugPrivilege()
GetCommandLineProc(DllCall("GetCurrentProcessId"),Cmd, Bit, IsAdmin)
MsgBox % IsAdmin
GetCommandLineProc(PID, ByRef Cmd, ByRef Bit, ByRef IsAdmin) {
Static PROCESS_QUERY_INFORMATION := 0x400, PROCESS_VM_READ := 0x10, STATUS_SUCCESS := 0
hProc := DllCall("OpenProcess", UInt, PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, Int, 0, UInt, PID, Ptr)
if A_Is64bitOS
DllCall("IsWow64Process", Ptr, hProc, UIntP, IsWow64), Bit := (IsWow64 ? "32" : "64") " bit" _DP
if (!A_Is64bitOS || IsWow64)
PtrSize := 4, PtrType := "UInt", pPtr := "UIntP", offsetCMD := 0x40
else
PtrSize := 8, PtrType := "Int64", pPtr := "Int64P", offsetCMD := 0x70
hModule := DllCall("GetModuleHandle", "str", "Ntdll", Ptr)
if (A_PtrSize < PtrSize) { ; скрипт 32, целевой процесс 64
if !QueryInformationProcess := DllCall("GetProcAddress", Ptr, hModule, AStr, "NtWow64QueryInformationProcess64", Ptr)
failed := "NtWow64QueryInformationProcess64"
if !ReadProcessMemory := DllCall("GetProcAddress", Ptr, hModule, AStr, "NtWow64ReadVirtualMemory64", Ptr)
failed := "NtWow64ReadVirtualMemory64"
info := 0, szPBI := 48, offsetPEB := 8
}
else {
if !QueryInformationProcess := DllCall("GetProcAddress", Ptr, hModule, AStr, "NtQueryInformationProcess", Ptr)
failed := "NtQueryInformationProcess"
ReadProcessMemory := "ReadProcessMemory"
if (A_PtrSize > PtrSize) ; скрипт 64, целевой процесс 32
info := 26, szPBI := 8, offsetPEB := 0
else ; скрипт и целевой процесс одной битности
info := 0, szPBI := PtrSize * 6, offsetPEB := PtrSize
}
if failed {
DllCall("CloseHandle", Ptr, hProc)
Return
}
VarSetCapacity(PBI, 48, 0)
if DllCall(QueryInformationProcess, Ptr, hProc, UInt, info, Ptr, &PBI, UInt, szPBI, UIntP, bytes) != STATUS_SUCCESS {
DllCall("CloseHandle", Ptr, hProc)
Return
}
pPEB := NumGet(&PBI + offsetPEB, PtrType)
DllCall(ReadProcessMemory, Ptr, hProc, PtrType, pPEB + PtrSize * 4, pPtr, pRUPP, PtrType, PtrSize, UIntP, bytes)
DllCall(ReadProcessMemory, Ptr, hProc, PtrType, pRUPP + offsetCMD, UShortP, szCMD, PtrType, 2, UIntP, bytes)
DllCall(ReadProcessMemory, Ptr, hProc, PtrType, pRUPP + offsetCMD + PtrSize, pPtr, pCMD, PtrType, PtrSize, UIntP, bytes)
VarSetCapacity(buff, szCMD, 0)
DllCall(ReadProcessMemory, Ptr, hProc, PtrType, pCMD, Ptr, &buff, PtrType, szCMD, UIntP, bytes)
Cmd := StrGet(&buff, "UTF-16")
DllCall("advapi32\OpenProcessToken", "ptr", hProc, "uint", 0x0008, "ptr*", hToken)
DllCall("advapi32\GetTokenInformation", "ptr", hToken, "int", 20, "uint*", IsAdmin, "uint", 4, "uint*", size)
DllCall("CloseHandle", "ptr", hToken)
IsAdmin := (IsAdmin ? "Admin" _DP : "")
DllCall("CloseHandle", Ptr, hProc)
}
SeDebugPrivilege() {
Static PROCESS_QUERY_INFORMATION := 0x400, TOKEN_ADJUST_PRIVILEGES := 0x20, SE_PRIVILEGE_ENABLED := 0x2
hProc := DllCall("OpenProcess", UInt, PROCESS_QUERY_INFORMATION, Int, false, UInt, DllCall("GetCurrentProcessId"), Ptr)
DllCall("Advapi32\OpenProcessToken", Ptr, hProc, UInt, TOKEN_ADJUST_PRIVILEGES, PtrP, token)
DllCall("Advapi32\LookupPrivilegeValue", Ptr, 0, Str, "SeDebugPrivilege", Int64P, luid)
VarSetCapacity(TOKEN_PRIVILEGES, 16, 0)
NumPut(1, TOKEN_PRIVILEGES, "UInt")
NumPut(luid, TOKEN_PRIVILEGES, 4, "Int64")
NumPut(SE_PRIVILEGE_ENABLED, TOKEN_PRIVILEGES, 12, "UInt")
DllCall("Advapi32\AdjustTokenPrivileges", Ptr, token, Int, false, Ptr, &TOKEN_PRIVILEGES, UInt, 0, Ptr, 0, Ptr, 0)
res := A_LastError
DllCall("CloseHandle", Ptr, token)
DllCall("CloseHandle", Ptr, hProc)
Return res ; в случае удачи 0
}
Работает.
Странно, у 1 человека не работает. А в AhkSpy 3.06 можете глянуть, это в Window где PID: 4656 ▪ 64 bit ▪ Admin.
Если AhkSpy запущен тоже от администратора, то показывает, что другой скрипт от админа. Иначе нет.
Не совсем понял, можете перефразировать.
Если запустить не от админа, то оно не работает. Дело в AhkSpy, или в функции из 2 поста.
И при обнаружении упомянутой проблемы, AhkSpy был запущен из админской учётки.
Я имею в виду не учётку, а права администратора. Т.е. пункт в контестном меню файла .ahk. Код из 6-го поста запускаю с правами админа, он показывает окошко со словом Admin. Его нужно было смотреть в AhkSpy? Навожу на него AhkSpy и в строке PID он показывает Admin только если сам тоже запущен с правами админа.
Или что нужно было делать?
Я имею в виду не учётку, а права администратора.
Так если зашёл под админской учёткой, у меня же всё запускаемое должно быть с правами админа, или я что то путаю?
Т.е. пункт в контестном меню файла .ahk
Это не понял про что.
он показывает Admin только если сам тоже запущен с правами админа.
Так и должно работать?
А как?
Только тогда у меня скрипт запустится с правами администратора, хотя учётная запись у меня и админская. Это же с Семёрки ещё так было (если не с Висты, но ею я не пользовался). Может, у вас UAC отключен, а без него этой фишки нет?
Так и должно работать?
Точно не знаю, не исследовал этот вопрос.
а без него этой фишки нет?
Дело в UAC, с отключенным, всегда с правами администратора, с включенным надо или в меню выбирать, или в свойства - совместимость - установить админа для ехе.
Можно ещё в манифесте указать, но это для экзешника.
<requestedExecutionLevel level="asInvoker" uiAccess="false"></requestedExecutionLevel>
asInvoker: The application will run with the same permissions as the process that started it. The application can be elevated to a higher permission level by selecting Run as Administrator.
highestAvailable: The application will run with the highest permission level that it can. If the user who starts the application is a member of the Administrators group, this option is the same as requireAdministrator. If the highest available permission level is higher than the level of the opening process, the system will prompt for credentials.
requireAdministrator: The application will run with administrator permissions. The user who starts the application must be a member of the Administrators group. If the opening process is not running with administrative permissions, the system will prompt for credentials.
Это перезапускает скрипт с правами админа. По вашему это должно работать при любых условиях, или есть какие то ещё настройки безопасности, которые могут не дать запустить скрипт с правами админа.
RunAsAdmin() {
Global 0
IfEqual, A_IsAdmin, 1, Return 0
Loop, %0%
params .= A_Space . %A_Index%
DllCall("shell32\ShellExecute" (A_IsUnicode ? "":"A"),uint,0,str,"RunAs",str,(A_IsCompiled ? A_ScriptFullPath
: A_AhkPath),str,(A_IsCompiled ? "": """" . A_ScriptFullPath . """" . A_Space) params,str,A_WorkingDir,int,1)
ExitApp
}
Тут я не компенгаген. Может, и есть. Но, кстати, тут ведь тоже запрос от UAC во весь экран вылазит. Чтобы без него, это надо через планировщик задач запускать. Но потому там и без запроса, что программно туда не влезть (по кр. мере так я читал).
тут ведь тоже запрос от UAC во весь экран вылазит
Где?
Если я запускаю скрипт не от админа, то RunAsAdmin() перезапускает его с правами админа без запроса.
У меня. "Не от админа" — это если вы вошли в систему не как админ?
Нет, если как админ, но UAC включен.
А вы как входили?
Так же. Если UAC включен, то естественно, что он отреагировал.
Значит на 7 с UAC это неестественно?
На Семёрке не пробовал. Но думаю, что было бы так же. Чудес не свете не бывает.
Ну кто его знает, что за чудеса, может политика UAC изменена, но за что купил... RunAsAdmin() при включенном UAC запрос у меня не выводит.
Страницы 1
Чтобы отправить ответ, вы должны войти или зарегистрироваться