Blog. Just Blog

Работа с сервисами Windows на Ассемблере

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Образ мышления: Assembler | Автор: ManHunter
Работа с сервисами Windows на Ассемблере
Работа с сервисами Windows на Ассемблере

Давно хотел поэкспериментировать с сервисами Windows, наконец дошли руки. Еще со времен Windows XP я пользуюсь программой Service Tree от А.Н.Гусарова, но в ней имеются досадные косяки, поэтому есть большое желание написать что-нибудь подобное. А в этой статье будут складироваться все наработки по теме сервисов.

Начинаем с описания констант и структур, которых нет в FASM, но которые нам будут нужны для дальнейшей работы с сервисами.
  1. SC_MANAGER_ALL_ACCESS = 0xF003F
  2. SERVICE_ALL_ACCESS    = 0xF01FF
  3. SERVICE_QUERY_CONFIG  = 0x0001
  4. SERVICE_QUERY_STATUS  = 0x0004
  5. SERVICE_CHANGE_CONFIG = 0x0002
  6. SERVICE_ENUMERATE_DEPENDENTS = 0x0008
  7. SERVICE_START         = 0x0010
  8. SERVICE_STOP          = 0x0020
  9. DELETE                = 0x10000
  10. SERVICE_NO_CHANGE     = 0xFFFFFFFF
  11. SERVICE_CONTROL_STOP  = 0x00000001
  12. SERVICE_WIN32_OWN_PROCESS   = 0x00000010
  13. SERVICE_WIN32_SHARE_PROCESS = 0x00000020
  14. SERVICE_ACTIVE        = 0x00000001
  15. SERVICE_INACTIVE      = 0x00000002
  16. SERVICE_STATE_ALL     = 0x00000003
  17.  
  18. SERVICE_STOPPED          = 0x00000001
  19. SERVICE_START_PENDING    = 0x00000002
  20. SERVICE_STOP_PENDING     = 0x00000003
  21. SERVICE_RUNNING          = 0x00000004
  22. SERVICE_CONTINUE_PENDING = 0x00000005
  23. SERVICE_PAUSE_PENDING    = 0x00000006
  24. SERVICE_PAUSED           = 0x00000007
  25.  
  26. SERVICE_BOOT_START   = 0x00000000
  27. SERVICE_SYSTEM_START = 0x00000001
  28. SERVICE_AUTO_START   = 0x00000002
  29. SERVICE_DEMAND_START = 0x00000003
  30. SERVICE_DISABLED     = 0x00000004
  31.  
  32. struct SERVICE_STATUS
  33.         dwServiceType      dd ?
  34.         dwCurrentState     dd ?
  35.         dwControlsAccepted dd ?
  36.         dwWin32ExitCode    dd ?
  37.         dwServiceSpecificExitCode dd ?
  38.         dwCheckPoint       dd ?
  39.         dwWaitHint         dd ?
  40. ends
  41.  
  42. struct ENUM_SERVICE_STATUS
  43.         lpServiceName dd ?
  44.         lpDisplayName dd ?
  45.         ServiceStatus SERVICE_STATUS
  46. ends
  47.  
  48. struct QUERY_SERVICE_CONFIG
  49.         dwServiceType      dd ?
  50.         dwStartType        dd ?
  51.         dwErrorControl     dd ?
  52.         lpBinaryPathName   dd ?
  53.         lpLoadOrderGroup   dd ?
  54.         dwTagId            dd ?
  55.         lpDependencies     dd ?
  56.         lpServiceStartName dd ?
  57.         lpDisplayName      dd ?
  58. ends
  59.  
  60. struct QUERY_SERVICE_LOCK_STATUS
  61.         fIsLocked      dd ?
  62.         lpLockOwner    dd ?
  63.         dwLockDuration dd ?
  64. ends
Работа с сервисами начинается с подключения к менеджеру сервисов, это может быть база на локальном или удаленном компьютере. Подключение выполняется при помощи функции OpenSCManager. Для перечисления всех сервисов, которые установлены на выбранной системе, есть функция EnumServicesStatus, но вызывать ее надо два раза. Первым проходом определяем размер памяти, необходимый для получения данных по всем сервисам, выделяем эту память, а затем вторым проходом заполняем массив структур ENUM_SERVICE_STATUS. Поочередно перебирая эти структуры, получаем имя, описание и текущее состояние каждого сервиса. Закончив обработку, закрываем хэндл менеджера сервисов при помощи функции CloseServiceHandle.
  1.         ; Открыть менеджер сервисов
  2.         invoke  OpenSCManager,NULL,NULL,SC_MANAGER_ALL_ACCESS
  3.         or      eax,eax
  4.         jz      loc_exit
  5.  
  6.         mov     [scm],eax
  7.  
  8.         ; ResumeHandle перед вызовом должен быть обнулен
  9.         mov     [ResumeHandle],0
  10.  
  11.         ; Определить необходимый размер памяти
  12.         invoke  EnumServicesStatus,[scm],\
  13.                 SERVICE_WIN32_OWN_PROCESS+SERVICE_WIN32_SHARE_PROCESS,\
  14.                 SERVICE_ACTIVE+SERVICE_INACTIVE,tmp,0,\
  15.                 BytesNeeded,ServicesReturned,ResumeHandle
  16.  
  17.         ; Выделить память
  18.         invoke  GlobalAlloc,GMEM_FIXED+GMEM_ZEROINIT,[BytesNeeded]
  19.         mov     [mem],eax
  20.         invoke  GlobalLock,eax
  21.         mov     [Services],eax
  22.  
  23.         ; ResumeHandle перед вызовом должен быть обнулен
  24.         mov     [ResumeHandle],0
  25.  
  26.         ; Получить список сервисов
  27.         invoke  EnumServicesStatus,[scm],\
  28.                 SERVICE_WIN32_OWN_PROCESS+SERVICE_WIN32_SHARE_PROCESS,\
  29.                 SERVICE_ACTIVE+SERVICE_INACTIVE,[Services],[BytesNeeded],\
  30.                 BytesNeeded,ServicesReturned,ResumeHandle
  31.  
  32.         ; Получить данные каждого сервиса
  33.         mov     ebx,[Services]
  34. loc_enum_services:
  35.         ; Открыть сервис
  36.         invoke  OpenService,[scm],[ebx+ENUM_SERVICE_STATUS.lpServiceName],\
  37.                 SERVICE_QUERY_CONFIG
  38.         or      eax,eax
  39.         jz      loc_next_service
  40.  
  41.         mov     [hService],eax
  42.  
  43.         ; Определить необходимый размер памяти
  44.         invoke  QueryServiceConfig,[hService],qsc,0,BytesNeeded
  45.  
  46.         ; Выделить память
  47.         invoke  GlobalAlloc,GMEM_FIXED+GMEM_ZEROINIT,[BytesNeeded]
  48.         mov     [mem2],eax
  49.         invoke  GlobalLock,eax
  50.         mov     [Service],eax
  51.  
  52.         ; Получить данные сервиса
  53.         invoke  QueryServiceConfig,[hService],[Service],[BytesNeeded],BytesNeeded
  54.  
  55.         mov     ecx,[Service]
  56.  
  57.         ; ECX -> указатель на структуру QUERY_SERVICE_CONFIG
  58.         ; EBX -> указатель на структуру ENUM_SERVICE_STATUS
  59.  
  60.         ...
  61.         ; Какие-то действия с сервисом
  62.         ...
  63.  
  64.         ; Освободить память
  65.         invoke  GlobalUnlock,[Service]
  66.         invoke  GlobalFree,[mem2]
  67.  
  68.         ; Закрыть сервис
  69.         invoke  CloseServiceHandle,[hService]
  70. loc_next_service:
  71.         ; Следующий сервис
  72.         add     ebx,sizeof.ENUM_SERVICE_STATUS
  73.  
  74.         ; Все сервисы отработали?
  75.         dec     [ServicesReturned]
  76.         cmp     [ServicesReturned],0
  77.         ja      loc_enum_services
  78.  
  79.         ; Освободить память
  80.         invoke  GlobalUnlock,[Services]
  81.         invoke  GlobalFree,[mem]
  82.  
  83.         ; Закрыть менеджер сервисов
  84.         invoke  CloseServiceHandle,[scm]
Для получения подробной информации о конкретном сервисе его надо предварительно открыть по имени с помощью функции OpenService, имя сервиса можно взять из поля ServiceName структуры ENUM_SERVICE_STATUS или использовать какое-то фиксированное имя, если оно известно. Обычно для запроса информации достаточно прав доступа SERVICE_QUERY_CONFIG, так как для некоторых критичных сервисов полный доступ SERVICE_ALL_ACCESS недоступен даже под учетной записью Администратора. Имея хэндл открытого сервиса, при помощи функции QueryServiceConfig получаем заполненную структуру QUERY_SERVICE_CONFIG, в которой содержится подробная информация об этом сервисе. Это имя файла сервиса, параметры командной строки, тип запуска, инициатор запуска, зависимые сервисы и т.д. Как и в случае с получением списка сервисов, функцию QueryServiceConfig также надо вызывать дважды: первый раз для получения объема необходимой памяти, второй раз для получения данных, естественно, после выделения памяти. Получив данные, не забываем закрывать хэндл сервиса функцией CloseServiceHandle.

Отдельно хочу остановиться на зависимых сервисах, то есть прочих сервисах, от которых зависит работоспособность выбранного сервиса или наоборот, работоспособность которых зависит от выбранного сервиса. При получении конфигурации сервиса в поле lpDependencies структуры QUERY_SERVICE_CONFIG содержится указатель на список имен сервисов, от которых зависит работоспособность выбранного сервиса. Список хранится в виде строк, разделенных нулевым символом и заканчивается двойным нулевым символом. Для получения названия сервисов можно воспользоваться функцией GetServiceDisplayName.
  1.         ; EBX -> указатель на структуру QUERY_SERVICE_CONFIG
  2.  
  3.         ; Первый сервис, от которого зависит выбранный
  4.         mov     esi,[ebx+QUERY_SERVICE_CONFIG.lpDependencies]
  5. loc_enum_depends:
  6.         cmp     word [esi],0
  7.         je      loc_no_more_depends
  8.  
  9.         ; Получить название сервиса
  10.         mov     [tmp],100h
  11.         invoke  GetServiceDisplayName,[scm],esi,depend,tmp
  12.  
  13.         ...
  14.         ...
  15.  
  16.         ; Следующий сервис
  17.         invoke  lstrlen,esi
  18.         inc     eax
  19.         shl     eax,1
  20.         add     esi,eax
  21.  
  22.         jmp     loc_enum_depends
  23.  
  24. loc_no_more_depends:
Для получения списка зависимых сервисов есть специальная функция EnumDependentServices. Чтобы у приложения был доступ к ее вызову, родительский сервис должен быть открыт как минимум с правами SERVICE_ENUMERATE_DEPENDENTS.
  1.         ; Определить необходимый размер памяти
  2.         invoke  EnumDependentServices,[hService],\
  3.                 SERVICE_STATE_ALL,0,[BytesNeeded],\
  4.                 BytesNeeded,DServicesReturned
  5.  
  6.         cmp     [BytesNeeded],0
  7.         je      loc_no_depends
  8.  
  9.         ; Выделить память
  10.         invoke  GlobalAlloc,GMEM_FIXED+GMEM_ZEROINIT,[BytesNeeded]
  11.         mov     [mem],eax
  12.         invoke  GlobalLock,eax
  13.         mov     [Depends],eax
  14.  
  15.         ; Получить список зависимостей
  16.         invoke  EnumDependentServices,[hService],\
  17.                 SERVICE_STATE_ALL,[Depends],[BytesNeeded],\
  18.                 BytesNeeded,ServicesReturned
  19.  
  20.         mov     ebx,[Depends]
  21. loc_depends:
  22.         ; EBX -> указатель на структуру ENUM_SERVICE_STATUS
  23.         ...
  24.         ...
  25.  
  26.         ; Следующий сервис
  27.         add     ebx,sizeof.ENUM_SERVICE_STATUS
  28.  
  29.         ; Все сервисы отработали?
  30.         dec     [ServicesReturned]
  31.         cmp     [ServicesReturned],0
  32.         ja      loc_depends
  33.  
  34.         ; Освободить память
  35.         invoke  GlobalUnlock,[Depends]
  36.         invoke  GlobalFree,[mem]
  37. loc_no_depends:
Тут все практически то же самое, что и при работе с обычными сервисами. Сперва определяем размер памяти, необходимый для получения данных, выделяем эту память, а затем при повторном вызове заполняем массив структур ENUM_SERVICE_STATUS. Поочередно перебирая эти структуры, получаем имя, описание и прочие данные каждого зависимого сервиса.

Приостановить или возобновить работу сервиса, а также полностью остановить его можно при помощи функции ControlService. Сервис должен быть предварительно открыт с правами SERVICE_PAUSE_CONTINUE и/или SERVICE_STOP в зависимости от задачи.
  1.         ; Открыть сервис
  2.         invoke  OpenService,[scm],sname,SERVICE_STOP
  3.         or      eax,eax
  4.         jz      loc_error
  5.  
  6.         mov     [hService],eax
  7.  
  8.         ; Остановить сервис
  9.         invoke  ControlService,[hService],SERVICE_CONTROL_STOP
  10.         or      eax,eax
  11.         jz      loc_error
  12.  
  13.         ; Закрыть сервис
  14.         invoke  CloseServiceHandle,[hService]
Запуск сервиса вынесен в отдельную функцию StartService. До запуска сервис должен быть открыт с правами SERVICE_START.
  1.         ; Открыть сервис
  2.         invoke  OpenService,[scm],sname,SERVICE_START
  3.         or      eax,eax
  4.         jz      loc_error
  5.  
  6.         mov     [hService],eax
  7.  
  8.         ; Запустить сервис
  9.         invoke  StartService,[hService],0,NULL
  10.         or      eax,eax
  11.         jz      loc_error
  12.  
  13.         ; Закрыть сервис
  14.         invoke  CloseServiceHandle,[hService]
После запуска сервису может потребоваться некоторое время, чтобы прийти в боевую готовность. Для того, чтобы корректно отработать запуск сервиса, надо циклически проверить его статус и затем дождаться момента, когда статус изменится с SERVICE_START_PENDING на SERVICE_RUNNING. Для ожидания остановки сервиса код точно такой же, только статус должен смениться с SERVICE_STOP_PENDING на SERVICE_STOPPED.
  1.         ; Выделить память
  2.         invoke  GlobalAlloc,GMEM_FIXED+GMEM_ZEROINIT,sizeof.SERVICE_STATUS
  3.         mov     [mem],eax
  4.         invoke  GlobalLock,eax
  5.         mov     [Status],eax
  6.  
  7.         ; Получить статус сервиса после запуска
  8.         invoke  QueryServiceStatus,[hService],[Status]
  9.         or      eax,eax
  10.         jz      loc_error
  11.  
  12.         mov     ebx,[Status]
  13.  
  14.         ; Получить текущее время и контрольную точку сервиса
  15.         invoke  GetTickCount
  16.         mov     [TickCount],eax
  17.  
  18.         mov     eax,[ebx+SERVICE_STATUS.dwCheckPoint]
  19.         mov     [CheckPoint],eax
  20.  
  21. start_service_wait:
  22.         ; Сервис в процессе запуска?
  23.         cmp     [ebx+SERVICE_STATUS.dwCurrentState],SERVICE_START_PENDING
  24.         jne     start_service_done
  25.  
  26.         ; Сервису требуется время для запуска
  27.         mov     eax,[ebx+SERVICE_STATUS.dwWaitHint]
  28.         xor     edx,edx
  29.         mov     ecx,10
  30.         div     ecx
  31.         ; Берем 1/10 часть от запрошенного времени, но не менее
  32.         ; 1 секунды и не более 10 секунд
  33.         cmp     eax,1000
  34.         ja      @f
  35.         mov     eax,1000
  36. @@:
  37.         cmp     eax,10000
  38.         jb      @f
  39.         mov     eax,10000
  40. @@:
  41.         invoke  Sleep,eax
  42.  
  43.         ; Получить статус сервиса
  44.         invoke  QueryServiceStatus,[hService],[Status]
  45.  
  46.         ; Контрольная точка изменилась?
  47.         mov     eax,[ebx+SERVICE_STATUS.dwCheckPoint]
  48.         cmp     eax,[CheckPoint]
  49.         jbe     @f
  50.  
  51.         ; Да, обновить таймер и сохраненную контрольную точку
  52.         invoke  GetTickCount
  53.         mov     [TickCount],eax
  54.  
  55.         mov     eax,[ebx+SERVICE_STATUS.dwCheckPoint]
  56.         mov     [CheckPoint],eax
  57.         jmp     start_service_wait
  58. @@:
  59.         ; Время ожидания превысило запрошенный сервисом таймаут?
  60.         invoke  GetTickCount
  61.         sub     eax,[TickCount]
  62.         cmp     eax,[ebx+SERVICE_STATUS.dwWaitHint]
  63.         jb      start_service_wait
  64.  
  65. start_service_done:
  66.         ; Сервис запущен?
  67.         cmp     [ebx+SERVICE_STATUS.dwCurrentState],SERVICE_RUNNING
  68.         jne     loc_error
Удаление сервиса. Открываем сервис с нужными правами, то есть как минимум DELETE, затем вызываем DeleteService. Сервис помечается на удаление, но фактически он будет удален из базы только когда будут закрыты все его хэндлы, а сам сервис будет остановлен. Если по какой-то причине сервис остановить прямо сейчас нельзя, он будет удален после перезагрузки системы.
  1.         ; Открыть сервис
  2.         invoke  OpenService,[scm],sname,DELETE
  3.         or      eax,eax
  4.         jz      loc_error
  5.  
  6.         mov     [hService],eax
  7.  
  8.         ; Отметить сервис на удаление
  9.         invoke  DeleteService,[hService]
  10.  
  11.         ; Закрыть сервис
  12.         invoke  CloseServiceHandle,[hService]
Для изменения настроек сервиса, например, параметров его запуска, названия или чего-то другого, воспользуйтесь функцией ChangeServiceConfig. Если какой-то параметр менять не надо, то передавайте значение SERVICE_NO_CHANGE для числовых значений и NULL для строковых. Подразумевается, что сервис был открыт с правами SERVICE_CHANGE_CONFIG. Перед внесением изменений обязательно надо заблокировать базу сервисов функцией LockServiceDatabase. Это позволит безопасно изменить настройки, так как гарантирует, что сервис не будет запущен в момент выполнения операции. Особенно важно блокировать базу, если сервис имеет зависимости от других сервисов в системе. После применения изменений базу надо сразу же разблокировать командой UnlockServiceDatabase.
  1.         ; Открыть сервис
  2.         invoke  OpenService,[scm],sname,SERVICE_CHANGE_CONFIG
  3.         or      eax,eax
  4.         jz      loc_error
  5.  
  6.         mov     [hService],eax
  7.  
  8.         ; Заблокировать базу
  9.         invoke  LockServiceDatabase,[scm]
  10.         mov     [ScLock],eax
  11.  
  12.         ; Отключить сервис
  13.         invoke  ChangeServiceConfig,[hService],SERVICE_NO_CHANGE,\
  14.                 SERVICE_DISABLED,SERVICE_NO_CHANGE,\
  15.                 NULL,NULL,NULL,NULL,NULL,NULL,NULL
  16.  
  17.         ; Закрыть сервис
  18.         invoke  CloseServiceHandle,[hService]
  19.  
  20.         ; Разблокировать базу
  21.         invoke  UnlockServiceDatabase,[ScLock]
Немного о блокировке базы. В любой момент времени только один процесс может владеть блокировкой, поэтому перед блокировкой надо обязательно проверить ее текущее состояние при помощи функции QueryServiceLockStatus.
  1.         ; Получить необходимый размер памяти
  2.         invoke  QueryServiceLockStatus,[scm],NULL,0,BytesNeeded
  3.         add     [BytesNeeded],100
  4.  
  5.         ; Выделить память
  6.         invoke  GlobalAlloc,GMEM_FIXED+GMEM_ZEROINIT,[BytesNeeded]
  7.         mov     [mem],eax
  8.         invoke  GlobalLock,eax
  9.         mov     [LockDB],eax
  10.  
  11. lock_database_wait:
  12.         ; Получить статус блокировки базы
  13.         invoke  QueryServiceLockStatus,[scm],[LockDB],[BytesNeeded],tmp
  14.         mov     eax,[LockDB]
  15.         cmp     [eax+QUERY_SERVICE_LOCK_STATUS.fIsLocked],0
  16.         je      lock_database_done
  17.  
  18.         invoke  Sleep,1000
  19.         jmp     lock_database_wait
  20.  
  21. lock_database_done:
  22.         ; Освободить память
  23.         invoke  GlobalUnlock,[LockDB]
  24.         invoke  GlobalFree,[mem]
  25.  
  26.         ; Заблокировать базу
  27.         invoke  LockServiceDatabase,[scm]
  28.         mov     [ScLock],eax
  29.  
  30.         ...
  31.         ; Какие-то действия с сервисами
  32.         ...
  33.  
  34.         ; Разблокировать базу
  35.         invoke  UnlockServiceDatabase,[ScLock]
Если база блокирована, то в структуре QUERY_SERVICE_LOCK_STATUS будет информация об учетной записи, от имени которой была выполнена имеющаяся блокировка, а также о времени, в течение которого эта блокировка уже активна. Вам придется дождаться снятия блокировки перед тем, как блокировать базу из своего процесса. Если процесс, владеющий блокировкой, будет завершен, система автоматически снимет блокировку базы, чтобы сервисы снова могли продолжить работу.

В приложении примеры программ с исходными текстами, одна из которых выводит список установленных сервисов с их конфигурацией, а вторая позволяет управлять выбранным сервисом. Запускать ТОЛЬКО от админа.

Примеры программ с исходными текстами (FASM)Примеры программ с исходными текстами (FASM)

Services.Demo.zip (11,323 bytes)


Поделиться ссылкой ВКонтакте
Просмотров: 1721 | Комментариев: 15

Внимание! Статья опубликована больше года назад, информация могла устареть!

Комментарии

Отзывы посетителей сайта о статье
morgot (18.06.2021 в 00:36):
asm0rot, поставь ХР и изучай матчасть там или же запускай от админа (!). В плане не от юзера админа, а правой кнопкой - "запуск от имени администратора".
asm0rot (06.06.2021 в 20:09):
У меня стоит USER и он администратор а все равно не хочет грузиться что такое...
ManHunter (06.06.2021 в 19:14):
Запускать ТОЛЬКО от админа.
asm0rot (06.06.2021 в 19:11):
; Открыть менеджер сервисов
        invoke  OpenSCManager,NULL,NULL,SC_MANAGER_ALL_ACCESS
возвращает ERROR_ACCESS_DENIED (00000005) что делать?
_sheva740 (02.06.2021 в 21:40):
Спасибо ребята!!!
ManHunter (29.05.2021 в 11:17):
DRON, опять выручаешь :) Спасибо! Статью подкорректировал, архив обновлен.
DRON (28.05.2021 в 23:51):
QUERY_SERVICE_CONFIG содержит полный список сервисов, но в формате "doubly null-terminated strings" то есть за первой строкой сразу идёт вторая, а за последней идёт ещё один нолик.
Ссылка по теме: https://devblogs.microsoft.com...-00/?p=14883

Ну а вызовы Lock/UnlockServiceDatabase после XP просто игнорируется. Насколько я помню их убрали как раз из-за неправильного использования большинством разработчиков.

_sheva740: Битность сервиса определяется по битности кода вызвавшего CreateService. Если вы вызываете CreateService из 32-х битного приложения запущенного на 64-х битной системе (что типично для инсталляторов), то сервис помечается как 32-х битный (создаётся параметр WOW64 в соответствующей ветке реестра) независимо от разрядности самого сервиса.
morgot (28.05.2021 в 18:52):
Спасибо, хорошая статья! Именно вот мануал от и до по службам.
Единственное - касаемо зависимых сервисов. Вроде как QUERY_SERVICE_CONFIG содержит сервисы, от которых зависит текущий (их надо запустить перед ним); а вот EnumDependentServices перечисляет сервисы, зависимые от текущего (его надо запускать перед ними, или при завершении - сначала их).

Могу ошибаться! Хорошая тулза для работы со службами - Process Haker.
Exit (28.05.2021 в 13:18):
ЦитатаОфсайта нет, брал где-то давным-давно, уже и не вспомню.

ManHunter, Спасибо, поюзаю, на досуге)
ManHunter (27.05.2021 в 23:22):
Конечно можно. Например, тот же nnCron, Apache2, все проверено, все работает.
_sheva740 (27.05.2021 в 22:45):
Извините за неточность.
Вопрос - можно ли писать сервис 32-х битный и потом зарегистрировать этот сервис в OS Win10 x64?
Спасибо.
ManHunter (27.05.2021 в 22:14):
Ну вот, а я только телепатов в отпуск отправил. "он" - это кто? "зарегистрируется в системе" - это что?
_sheva740 (27.05.2021 в 15:54):
Спасибо!
А под Win10 x64 разве он зарегистрируется в системе?
ManHunter (26.05.2021 в 14:40):
Офсайта нет, брал где-то давным-давно, уже и не вспомню.
https://www.upload.ee/files/13...0.6.zip.html
В архиве оригинал и мой исправленный вариант. Пропатчены права доступа и исправлены ресурсы. Но остались косяки, которые патчем не поправить, только переписывать все нафиг.
Exit (26.05.2021 в 14:35):
ЦитатаService Tree от А.Н.Гусарова

ManHunter, а у проги есть сайт?
А то погуглил и не нашел...
Хоть глянуть, что за зверь:)

P.S. раньше, когда "воевал" со службами, юзал gtools
http://p-nand-q.com/download/p...l/index.html
А на Семерке, выпиливаю NTLite'ом
Нет файлов = нет процессов = нет дыр:)

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2024
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.07 сек. / MySQL: 2 (0.0087 сек.) / Память: 4.5 Mb
Наверх