Blog. Just Blog

Контроль запуска процессов на Ассемблере

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Образ мышления: Assembler | Автор: ManHunter
Сегодня разберем интересную задачу: надо отслеживать запуск приложений в системе и, в случае необходимости, выборочно блокировать их запуск. Решения могут быть различные, я предлагаю вот такой способ. Он заключается в том, что в цепочку AppCertDlls встраивается наша собственная библиотека-обработчик. При первом и любом последующем вызове функции CreateProcess обработчику будет передан полный путь до запускаемого файла.

Такой способ перехвата используется еще со времен Windows 2000, но подробно не документирован до сих пор. Ничего удивительного, что "коробочный" FASM совершенно не в курсе используемых в нем данных. Сперва немного констант:
  1. ; Флаги запроса
  2. APPCERT_IMAGE_OK_TO_RUN  = 1
  3. APPCERT_CREATION_ALLOWED = 2
  4. APPCERT_CREATION_DENIED  = 3
  5.  
  6. ; Флаги результата
  7. STATUS_SUCCESS      = 0x00000000
  8. STATUS_UNSUCCESSFUL = 0xC0000001
Переходим к созданию основного модуля. В экспорте вашей dll обязательно должна быть функция CreateProcessNotify которая и отвечает за обработку запуска процесса. У нее два параметра: lpApplicationName - указатель на строку имени файла запускаемого процесса и Reason - флаг запроса. Если с именем файла все более-менее понятно, то по флагу запроса надо внести ясность. Этот флаг может принимать одно из трех возможных значений. APPCERT_IMAGE_OK_TO_RUN - система опрашивает вашу библиотеку на предмет того, доверяете вы указанному процессу или нет. Такое бывает, если ваш обработчик первый или единственный. Если запускаемая программа вас устраивает, то верните STATUS_SUCCESS, в противном случае установите флаг результата в STATUS_UNSUCCESSFUL. Варианты запроса APPCERT_CREATION_ALLOWED или APPCERT_CREATION_DENIED поступают в том случае, если в системе уже установлены обработчики запуска приложений, какой-то из них уже проверил запускаемый файл и принял решение, можно его запускать или нет. Если передаваемый функции флаг имеет значение APPCERT_CREATION_ALLOWED, то процесс с этим именем может быть создан, а если APPCERT_CREATION_DENIED, то, соответственно, нет.

Очень важное замечание. Финальную точку в "голосовании" о судьбе запускаемого процесса принимает обработчик, который находится последним в очереди. Даже если все предыдущие обработчики приняли решение, что процесс запускать не надо, и передали по цепочке STATUS_UNSUCCESSFUL, то последний обработчик легко может отменить это решение, вернув флаг STATUS_SUCCESS, и наоборот. На мой взгляд, это очень странное поведение со стороны системы. Ведь ничто не мешает, например, вредоносной программе встроить свой обработчик последним и контролировать таким образом запуск приложений. Если вы создаете приложение просто для логирования запуска процессов, то хорошим тоном будет учитывать "мнение" предыдущих обработчиков и передавать его дальше по цепочке.

Каркас dll в общем виде выглядит следующим образом. Я оставил только значимые части.
  1. ;------------------------------------------------------------------
  2. ; Секция кода
  3. ;------------------------------------------------------------------
  4. proc CreateProcessNotify lpApplicationName:DWORD, Reason:DWORD
  5.         mov     eax,[Reason]
  6.         ; Мы первый или единственный обработчик в цепочке
  7.         cmp     eax,APPCERT_IMAGE_OK_TO_RUN
  8.         je      .check_file
  9.         ; Файл уже проверен, запуск разрешен
  10.         cmp     eax,APPCERT_CREATION_ALLOWED
  11.         je      .file_ok
  12.         ; Файл уже проверен, запуск запрещен
  13.         cmp     eax,APPCERT_CREATION_DENIED
  14.         je      .file_denied
  15.         ...
  16.         ...
  17.         ...
  18. .check_file:
  19.         ; Проверка запускаемого файла, после чего возвращаем нужный статус
  20.         mov     eax,STATUS_SUCCESS
  21.         jmp     .loc_ret
  22.         ; или 
  23.         mov     eax,STATUS_UNSUCCESSFUL
  24.         jmp     .loc_ret
  25.         ...
  26.         ...
  27.         ...
  28. .file_ok:
  29.         mov     eax,STATUS_SUCCESS
  30.         jmp     .loc_ret
  31.         ...
  32.         ...
  33. .file_denied:
  34.         mov     eax,STATUS_UNSUCCESSFUL
  35.         jmp     .loc_ret
  36.         ...
  37.         ...
  38.         ...
  39. .loc_ret:
  40.         ret
  41. endp
  42.  
  43. ;------------------------------------------------------------------
  44. ; Экспорт
  45. ;------------------------------------------------------------------
  46. section '.edata' export data readable
  47.  
  48.   export 'hook.dll',\
  49.          CreateProcessNotify,'CreateProcessNotify'
Чтобы установить обработчик в систему надо перейти в раздел реестра HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\AppCertDlls и создать в нем ключ с именем AppSecDll типа REG_EXPAND_SZ, затем присвоить ему значение полного пути до вашей библиотеки-обработчика. После перезагрузки системы обработчик начнет работать.

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

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

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

Комментарии

Отзывы посетителей сайта о статье
Кулибин (13.11.2017 в 22:25):
Большое спасибо!
Ща пошаманим... >:3
Давидыч (30.08.2017 в 19:54):
Шикарно!
ManHunter (28.08.2017 в 07:09):
Совсем обленились :( Просто добавить стандартные заголовки dll к каркасу + полезная нагрузка, вот и будет исходник. Готовую dll собирать тоже не хочу по причине разной разрядности систем, сам я сижу на x86, поведение 32-разрядных библиотек такого плана на 64-битной системе не тестировал. Я свою систему разок навернул в процессе отладки (повесил MessageBox на payload и ребутнулся), пришлось загружаться с диска и удалять обработчик через командную строку. Так что нет, вся движуха только под вашу ответственность.

ЦитатаВ чем смысл тогда? Просто рассказали о способе?

Да. Исходники с готовыми бинарниками я выкладываю только тогда, когда их можно сразу запустить и получить какой-то результат. Конкретно в этом случае только описание способа.
Wet (28.08.2017 в 05:30):
Исходников нет, готовой dll тоже нет. В чем смысл тогда? Просто рассказали о способе?
Fan (28.08.2017 в 05:26):
На самом интересном месте:не прилагаю)

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

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

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