Blog. Just Blog

Принудительное завершение процесса

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Образ мышления: Assembler | Автор: ManHunter
Рано или поздно в программистской практике возникает задача по управлению процессами, в частности их принудительного завершения. Для дочерних процессов, порожденных собственным приложением, обычно хватает вызова TerminateProcess, но в некоторых случаях требуется принудительно завершить чужой процесс. Зная идентификатор процесса сделать это не составит большого труда. Открываем процесс функцией OpenProcess с правами PROCESS_TERMINATE, а затем, в случае успеха, отдаем полученный хэндл функции TerminateProcess. Вроде бы все просто, но не тут-то было. При попытке открыть некоторые процессы, как правило системные, возвращается ошибка ERROR_ACCESS_DENIED. Это связано с тем, что дескрипторы безопасности системных процессов блокируют такой доступ для всех пользователей, включая Администраторов. Чтобы обойти запрет, требуется поднять привилегии нашего процесса, а именно получить привилегию отладчика SE_DEBUG_NAME. Как повышать привилегии процесса в системе я уже писал. Напомню только, что необходимые структуры и константы в FASM отсутствуют и их придется определить самостоятельно.
  1. ; Константы для работы привилегиями
  2. TOKEN_ADJUST_PRIVILEGES = 20h
  3. TOKEN_QUERY             = 8h
  4. SE_PRIVILEGE_ENABLED    = 2h
  5.  
  6. ; Структуры для работы привилегиями
  7. struct LUID
  8.     lowPart             dd ?
  9.     HighPart            dd ?
  10. ends
  11.  
  12. struct LUID_AND_ATTRIBUTES
  13.     pLuid               LUID
  14.     Attributes          dd ?
  15. ends
  16.  
  17. struct _TOKEN_PRIVILEGES
  18.     PrivilegeCount      dd ?
  19.     Privileges          LUID_AND_ATTRIBUTES
  20. ends
Когда данные подготовлены, можно поднять привилегии нашего процесса. Этот код вам уже должен быть знаком и трудностей не вызовет.
  1.         invoke  GetCurrentProcess
  2.         invoke  OpenProcessToken,eax,TOKEN_ADJUST_PRIVILEGES+TOKEN_QUERY,TTokenHd
  3.  
  4.         ; Получить привилегии процесса
  5.         invoke  LookupPrivilegeValue,NULL,SE_DEBUG_NAME,udtLUID
  6.  
  7.         ; Повысить привилегии процесса
  8.         mov     [tkp.PrivilegeCount],1
  9.         mov     [tkp.Privileges.Attributes],SE_PRIVILEGE_ENABLED
  10.         mov     eax,[udtLUID.lowPart]
  11.         mov     [tkp.Privileges.pLuid.lowPart],eax
  12.         mov     eax,[udtLUID.HighPart]
  13.         mov     [tkp.Privileges.pLuid.HighPart],eax
  14.         invoke  AdjustTokenPrivileges,[TTokenHd],0,tkp,0,0,0
Все, теперь у нас есть доступ ко всем процессам, включая сервисы и системные приложения. Конечно, есть особые программы типа антивирусов и фаерволов, которые на уровне ядра системы защищаются от манипуляций с их процессами, с ними такой трюк не сработает.

Усложним задачу. Предположим, что нам надо завершать не только произвольный процесс, но также и все процессы, порожденные им и его дочерними процессами. То есть нам надо обработать дерево процессов. Воспользуемся функцией CreateToolhelp32Snapshot для получения списка процессов, а затем переберем их по очереди и завершим все процессы, идентификатор родительского процесса которых равняется идентификатору убиваемого процесса. Но это только первый уровень, значит придется вызывать функцию завершения рекурсивно, указывая в качестве параметра идентификаторы дочерних процессов. Вот что у меня получилось:
  1. ;------------------------------------------------------
  2. ; Рекурсивная функция завершения дерева процессов
  3. ; by ManHunter / PCL
  4. ; http://www.manhunter.ru
  5. ;------------------------------------------------------
  6. ; Параметры:
  7. ; pID - идентификатор процесса
  8. ; recursive - завершать дочерние процессы (TRUE/FALSE)
  9. ;------------------------------------------------------
  10. proc    KillProcess pID:DWORD, recursive:DWORD
  11.         ; Сохранить регистры
  12.         pusha
  13.  
  14.         ; Требуется рекурсивный поиск?
  15.         cmp     [recursive],TRUE
  16.         jne     .kill_process
  17.  
  18.         ; Снимок процессов системы
  19.         invoke  CreateToolhelp32Snapshot,TH32CS_SNAPPROCESS,0
  20.         mov     ebx,eax
  21.  
  22.         ; Перебрать в цикле все процессы
  23.         mov     [ProcEntry.dwSize],sizeof.PROCESSENTRY32
  24.         invoke  Process32First,ebx,ProcEntry
  25. .check_process:
  26.         ; Ничего не найдено?
  27.         cmp     eax,FALSE
  28.         je      .stop_scan
  29.  
  30.         ; Это дочерний процесс от убиваемого?
  31.         mov     eax,[ProcEntry.th32ParentProcessID]
  32.         cmp     eax,[pID]
  33.         jne     .next_process
  34.  
  35.         ; Рекурсивно убить дочерний процесс
  36.         stdcall KillProcess,[ProcEntry.th32ProcessID],[recursive]
  37. .next_process:
  38.         ; Следующий процесс
  39.         invoke  Process32Next,ebx,ProcEntry
  40.         jmp     .check_process
  41. .stop_scan:
  42.         ; Закрыть хэндл
  43.         invoke  CloseHandle,ebx
  44. .kill_process:
  45.         ; Самоубийством не занимаемся
  46.         invoke  GetCurrentProcessId
  47.         cmp     eax,[pID]
  48.         je      @f
  49.  
  50.         ; Убить заказанный процесс
  51.         invoke  OpenProcess,PROCESS_TERMINATE,FALSE,[pID]
  52.         or      eax,eax
  53.         jz      @f
  54.         invoke  TerminateProcess,eax,0
  55. @@:
  56.         ; Востановить регистры
  57.         popa
  58.         ret
  59. endp
Функция универсальная, она позволяет завершать как отдельный процесс, так и дерево процессов. Все "неубиваемые" процессы пропускаются, свой собственный процесс также не завершается, независимо от того, на каком уровне иерархии дерева он находится.

В приложении несколько программ, запускающих друг друга для создания дерева процессов, а также программа, принудительно завершающая выбранный процесс вместе с его дочерними процессами.

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

Terminate.Process.Demo.zip (7,472 bytes)


Поделиться ссылкой ВКонтакте Поделиться ссылкой на Facebook Поделиться ссылкой на LiveJournal Поделиться ссылкой в Мой Круг Добавить в Мой мир Добавить на ЛиРу (Liveinternet) Добавить в закладки Memori Добавить в закладки Google
Просмотров: 5855 | Комментариев: 18

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

Комментарии

Отзывы посетителей сайта о статье
Андрей (24.03.2014 в 18:05):
Просто на мой взгляд складывается довольно странная ситуация
"Все, теперь у нас есть доступ ко всем процессам, включая сервисы и системные приложения." с последующей возможностью их убиения. А скорректировать время я не могу.
ManHunter (24.03.2014 в 17:57):
А взять и подумать? Программа НЕ МОЖЕТ ПОЛУЧАТЬ ПРАВА АДМИНА по своему желанию. И никто никогда этого не разрешит сделать.
Андрей (24.03.2014 в 17:55):
Уважаемый ManHunter, хочу спросить вашего совета по поводу прав на изменение (коррекцию) времени на системе Windows 7. Пытаясь самостоятельно освоить ассемблер, в качестве цели выбрал задачу по контролю времени работы компьютера моего сына. В качестве усложнения поставленной задачи разрешил ему всячески её "обходить". На сегодняшний день ситуация следующая - моя программа умеет выключать компьютер по таймеру. Он практически сразу догадался сдвигать часы. Я это могу фиксировать запросом времени из интернета, однако для коррекции системных часов у меня не хватает прав. Вернее если своей программе в свойствах файла я задаю права администратора, то коррекция происходит. Программно это сделать не получается. За основу брал Ваш код повышения прав доступа с привилегиями
;SE_SHUTDOWN_NAME db 'SeShutdownPrivilege',0
;SE_SYSTEMTIME_NAME db 'SeSystemtimePrivilege',0
;SE_DEBUG_NAME   db 'SeDebugPrivilege',0
подставляя их поочерёдно. Но ничего путного из этого не получилось. Если у вас найдётся минута свободного времени не сочтите за труд подскажите в каком направлении мне думать. Спасибо.
Андрей (24.03.2014 в 17:22):
Огромное спасибо за Ваш энтузиазм. Без сайтов подобных Вашему вряд ли смог бы продвинуться в изучении ассемблера намного дальше нежели "Привет мир"
Semiono (26.10.2011 в 19:40):
Здравствуйте. А можно ли выгружать зависшие DLL ?
Я видел Unlocker, но от графических утилит практической пользы мало.
Евлампий (26.09.2011 в 19:22):
приветствую
запустил прогу под обычным юзером
процессы админа ей не по зубам - ну это правильно
если бы привелегии(свои) с обычного юзера до админа поднимала вот
было бы круто
удачи
bigcatwar (29.08.2011 в 22:58):
ManHunter и если можно допиши о таких процессах которые не могут быть удалены даже из сафе мода serija cvhost
morgot (23.08.2011 в 00:39):
Спасибо, вещь актуальная.
Nutscracker (22.08.2011 в 19:25):
ManHunter, спасибо!
ManHunter (22.08.2011 в 10:44):
Про антируткиты я лучше что-нибудь отдельное напишу, тут тема совсем не про это.
Vito (22.08.2011 в 10:41):
А что вы можете сказать про XueTr?
ManHunter (22.08.2011 в 08:40):
Nutscracker, вот тут самый свежий: http://rghost.ru/18826521
Nutscracker (22.08.2011 в 01:40):
> RkUnhooker
Что-то я только http://forum.sysinternals.com/...37300509.rar нашел. Под семеркой, увы, не стартует: "Error loading driver, NTSTATUS code: C0000001".
И закрытую тему: http://www.kernelmode.info/for...rt=150#p6016
В теме значится более новая версия, но ссылок не видать.
ManHunter (21.08.2011 в 22:11):
RkUnhooker хорошо справляется с такими задачами. Но там вроде это делается через дров.
Isaev (21.08.2011 в 18:19):
Nutscracker, Unlocker то помогает, потому и понятно, что это возможно
Только программно как того же эффекта достичь, вот в чём вопрос!
Nutscracker (21.08.2011 в 01:08):
Isaev, а Unlocker http://www.emptyloop.com/unlocker/ или копирование в карантин в AVZ http://www.z-oleg.com/secur/avz/ не помогают?
Isaev (20.08.2011 в 16:02):
А как на счёт копирования файла занятого неубиваемым процессом? На васме читал статью про 3 способа, но как-то ничего не прокатило... Нет наработок в этом направлении?
Юзер (20.08.2011 в 04:08):
Спасибо. Добавить бы одну фичу: принудительное завершение всех зависших процессов по нажатию одной кнопки и утиль стала бы на редкость полезной. А если бы такую команду можно было подавать через ком.строку, или/и по нажатию настраиваемых горячих клавиш... дайте мне губозакаталку :)

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

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

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