Всем привет! Хочу создать event в сервисе (т.е. из-под пользователя SYSTEM) и открыть его для установки (SetEvent) в юзере/администраторе. Как это можно сделать? Разумеется, если создать event в сервисе обычным образом, то в юзере/админе его открыть не получится. Желательно поподробнее, в этих всяких security descriptor'ах и пр. не шарю совсем...
значит нужно повысить свою привилегию, через "Access_Token" (маркер доступа). Из юзера сразу в System наврядли получится (тем более на системах 7/10), но можно попробовать вырасти до "SeDebugPrivilege" - должно сработать. Функция AdjustTokenPrivileges() включает или отключает привилегии в указанном маркере доступа. --- Сообщение объединено, 19 мар 2019 --- посмотри в отладчике, что вернут эти функции (нуль = ошибка) если больше нуля, значит привилегию можно повысить: Код (ASM): include 'win32ax.inc' .data hToken dd 0 SeDebugNameValue dd 0,0 tName db 'SeDebugPrivilege',0 ;--------------------------------- .code start: invoke OpenProcessToken,-1,00101000b,hToken xor eax,eax invoke LookupPrivilegeValue,0,tName,SeDebugNameValue invoke ExitProcess,0 .end start
Коцит, к сожалению, это не работает. Права получить удаётся (там ещё AdjustTokenPrivileges должен быть в конце), а вот открыть – нет. OpenEvent(EVENT_MODIFY_STATE) выдаёт 0 и GetLastError = ERROR_ACCESS_DENIED Даже из-под админа.
system не пробовал подставлять? админ по-умолчанию может дебажить - это для юзверя нужно. почитай линки на rsdn: https://rsdn.org/article/baseserv/privileges.xml https://rsdn.org/article/qna/baseserv/privedit.xml возможные варианты описываются в хидере "winnt.h": Спойлер: Se_Privilege Код (Text): //////////////////////////////////////////////////////////////////////// // NT Defined Privileges // //////////////////////////////////////////////////////////////////////// #define SE_CREATE_TOKEN_NAME TEXT("SeCreateTokenPrivilege") #define SE_ASSIGNPRIMARYTOKEN_NAME TEXT("SeAssignPrimaryTokenPrivilege") #define SE_LOCK_MEMORY_NAME TEXT("SeLockMemoryPrivilege") #define SE_INCREASE_QUOTA_NAME TEXT("SeIncreaseQuotaPrivilege") #define SE_UNSOLICITED_INPUT_NAME TEXT("SeUnsolicitedInputPrivilege") #define SE_MACHINE_ACCOUNT_NAME TEXT("SeMachineAccountPrivilege") #define SE_TCB_NAME TEXT("SeTcbPrivilege") #define SE_SECURITY_NAME TEXT("SeSecurityPrivilege") #define SE_TAKE_OWNERSHIP_NAME TEXT("SeTakeOwnershipPrivilege") #define SE_LOAD_DRIVER_NAME TEXT("SeLoadDriverPrivilege") #define SE_SYSTEM_PROFILE_NAME TEXT("SeSystemProfilePrivilege") #define SE_SYSTEMTIME_NAME TEXT("SeSystemtimePrivilege") #define SE_PROF_SINGLE_PROCESS_NAME TEXT("SeProfileSingleProcessPrivilege") #define SE_INC_BASE_PRIORITY_NAME TEXT("SeIncreaseBasePriorityPrivilege") #define SE_CREATE_PAGEFILE_NAME TEXT("SeCreatePagefilePrivilege") #define SE_CREATE_PERMANENT_NAME TEXT("SeCreatePermanentPrivilege") #define SE_BACKUP_NAME TEXT("SeBackupPrivilege") #define SE_RESTORE_NAME TEXT("SeRestorePrivilege") #define SE_SHUTDOWN_NAME TEXT("SeShutdownPrivilege") #define SE_DEBUG_NAME TEXT("SeDebugPrivilege") #define SE_AUDIT_NAME TEXT("SeAuditPrivilege") #define SE_SYSTEM_ENVIRONMENT_NAME TEXT("SeSystemEnvironmentPrivilege") #define SE_CHANGE_NOTIFY_NAME TEXT("SeChangeNotifyPrivilege") #define SE_REMOTE_SHUTDOWN_NAME TEXT("SeRemoteShutdownPrivilege") #define SE_UNDOCK_NAME TEXT("SeUndockPrivilege") #define SE_SYNC_AGENT_NAME TEXT("SeSyncAgentPrivilege") #define SE_ENABLE_DELEGATION_NAME TEXT("SeEnableDelegationPrivilege") #define SE_MANAGE_VOLUME_NAME TEXT("SeManageVolumePrivilege") #define SE_IMPERSONATE_NAME TEXT("SeImpersonatePrivilege") #define SE_CREATE_GLOBAL_NAME TEXT("SeCreateGlobalPrivilege") #define SE_TRUSTED_CREDMAN_ACCESS_NAME TEXT("SeTrustedCredManAccessPrivilege") #define SE_RELABEL_NAME TEXT("SeRelabelPrivilege") #define SE_INC_WORKING_SET_NAME TEXT("SeIncreaseWorkingSetPrivilege") #define SE_TIME_ZONE_NAME TEXT("SeTimeZonePrivilege") #define SE_CREATE_SYMBOLIC_LINK_NAME TEXT("SeCreateSymbolicLinkPrivilege") --- Сообщение объединено, 21 мар 2019 --- вообще-то, если знаешь имя своего Event'a в сервисе, есть ещё варианты (правда я их не пробовал) - но чем чёрт не шутит.. 1. Создать в своём/юзерском процессе событие с таким-же именем. В доках CreateEvent() можно найти такое замечание: 2. Взять копию эвента через DuplicateHandle(). Опять из доков..
Нашёл пример на Delphi. Проверил – работает! Код (Text): var SA: TSecurityAttributes; SD: TSecurityDescriptor; H: THandle; begin // Создаем дескриптор безопасности if InitializeSecurityDescriptor(@SD, SECURITY_DESCRIPTOR_REVISION) and // DACL не установлен, объект не защищён SetSecurityDescriptorDacl(@SD, True, nil, False) then begin // Настраиваем атрибуты безопасности, передавая указатель на дескриптор безопасности SA.nLength := SizeOf(SA); SA.lpSecurityDescriptor := @SD; SA.bInheritHandle := False; // Создаём событие H := CreateEvent(@SA, True, False, 'Global\MyTestEvent'); end; ... После создания такого объекта его можно спокойно открыть кем угодно с EVENT_ALL_ACCESS