Исполнение кода на ранней стадии инициализации процесса
От: smbdnew  
Дата: 31.10.18 15:16
Оценка:
Хочу исполнить некоторый код при старте процесса.
Код имеет зависимости от ntdll, kernel32, и еще от пары системных либ, которые он загрузит самостоятельно с помощью LoadLibrary (не принципиально, но очень желательно).
Хочу его исполнить сразу после загрузки kernel32.
Пробовал вот что:
1) ProcessCreateNotifyRoutine: создать системный тред, в котором ждать инициализации лоадера, создать тред в процессе и сделать дела. Не устроил, ибо через раз процесс успевает завершиться раньше чем шелл закончит исполнение
2) LoadImageNotifyRoutine на загрузку длл — хукнуть точку входа, когда она получит управление сделать дела и восстановить её. При выделении памяти при загрузке длл получаем deadlock (как и сказано в документации). И даже если извратится и выделить память раньше, например в ProcessCreateNotifyRoutine — в перехваченной dllmain всё не получится загрузить другую длл.
3) LoadImageNotifyRoutine на загрузку exe — как ни странно работает без deadlock'а, но пока точка входа получит управление может быть поздно.
Задача довольно специфичная, но может быть есть возможность её решить ?
Отредактировано 31.10.2018 15:19 smbdnew . Предыдущая версия . Еще …
Отредактировано 31.10.2018 15:19 smbdnew . Предыдущая версия .
Re: Исполнение кода на ранней стадии инициализации процесса
От: enigmas Ниоткуда  
Дата: 31.10.18 15:27
Оценка:
Здравствуйте, smbdnew, Вы писали:

S>Хочу исполнить некоторый код при старте процесса.

S>Код имеет зависимости от ntdll, kernel32, и еще от пары системных либ, которые он загрузит самостоятельно с помощью LoadLibrary (не принципиально, но очень желательно).

Посмотрите TLS callback, свой код можно запустить из него.
Вполне хороший документированный метод и достаточно прост в реализации.
The Enigma Protector — software protection system
http://enigmaprotector.com/
Re[2]: Исполнение кода на ранней стадии инициализации процес
От: smbdnew  
Дата: 31.10.18 16:16
Оценка:
Здравствуйте, enigmas, Вы писали:

E>Посмотрите TLS callback, свой код можно запустить из него.

E>Вполне хороший документированный метод и достаточно прост в реализации.

Не совсем понял что вы имели ввиду. Если что, процесс не мой, а вообще любой произвольный.
Отредактировано 31.10.2018 16:23 smbdnew . Предыдущая версия .
Re: Исполнение кода на ранней стадии инициализации процесса
От: SomeOne_TT  
Дата: 31.10.18 18:00
Оценка:
Здравствуйте, smbdnew, Вы писали:

S>Хочу исполнить некоторый код при старте процесса.


CreateProcess c CREATE_SUSPENDED флагом не подойдет?
Re[2]: Исполнение кода на ранней стадии инициализации процесса
От: Слава  
Дата: 31.10.18 19:02
Оценка:
Здравствуйте, SomeOne_TT, Вы писали:

S>>Хочу исполнить некоторый код при старте процесса.


SO_>CreateProcess c CREATE_SUSPENDED флагом не подойдет?


Так трояны с криптомайнером не пишутся.
Re: Исполнение кода на ранней стадии инициализации процесса
От: okman Беларусь https://searchinform.ru/
Дата: 31.10.18 19:04
Оценка:
Здравствуйте, smbdnew, Вы писали:

S>Пробовал вот что:

S>...
S>2) LoadImageNotifyRoutine на загрузку длл — хукнуть точку входа, когда она получит управление сделать дела и восстановить её. При выделении памяти при загрузке длл получаем deadlock (как и сказано в документации). И даже если извратится и выделить память раньше, например в ProcessCreateNotifyRoutine — в перехваченной dllmain всё не получится загрузить другую длл.

Патчить точку входа на последних версиях Windows так-то просто не выйдет.
ZwProtectVirtualMemory нельзя из-за DisableDynamicCode policy (она же Arbitrary Code Guard на последних версиях Win10),
будет 0xC0000604 (STATUS_DYNAMIC_CODE_BLOCKED). На более ранних версиях функция, кстати, вообще не экспортируется ядром.
Способы с MmProtectXxx или сброс WP-бита в CR0 вспоминать не будем, так как это явно некорректно.
Можно попробовать написать минифильтр FS, подменяющий exe при его отображении в память, но это дико
сложно (и к тому же будут слетать цифровые подписи исполняемых файлов).

S>3) LoadImageNotifyRoutine на загрузку exe — как ни странно работает без deadlock'а,...


Это только до поры.
Нельзя там ни ZwAllocateVirtualMemory, ни ZwProtectVirtualMemory (я ловил дедлоки и в этой ситуации).

S>...но пока точка входа получит управление может быть поздно.


Ага. А еще есть .NET-приложения, у которых точка входа не в exe, а в mscoree.dll...

S>Задача довольно специфичная, но может быть есть возможность её решить ?


Решить-то можно, вот только стоит оно того?
Затраты, ИМХО, будут несоизмеримо большими, чем профит...
Re[2]: Исполнение кода на ранней стадии инициализации процесса
От: smbdnew  
Дата: 01.11.18 10:17
Оценка:
Хорошо, допустим я выделю код в ProcessCreateNotyRoutine.
А как бы на него передать управление как можно раньше ?
Re[3]: Исполнение кода на ранней стадии инициализации процесса
От: okman Беларусь https://searchinform.ru/
Дата: 02.11.18 06:10
Оценка: 3 (1)
Здравствуйте, smbdnew, Вы писали:

S>Хорошо, допустим я выделю код в ProcessCreateNotyRoutine.

S>А как бы на него передать управление как можно раньше ?

Если надо совсем-совсем раньше, прямо сразу после загрузки ntdll/kernel32, то вариантов немного.

Можно попробовать вариант с APC (KeInitializeApc/KeInsertQueueApc и далее alertable-ожидание,
чтобы APC сразу прилетела в поток), хотя тут 100% будут конфликты с другим софтом (антивирусы) и
есть масса других проблем. Описан в статье "способ принудительной загрузки dll..." (и сразу не
советую слепо доверять тому, что там написано и приведенному коду — его еще фиксить и фиксить).

Еще можно на этапе загрузки exe пропатчить таблицу импорта и вставить туда свою dll.
Так делает McAfee, если память не изменяет.

IMHO, относительно надежное — это патчить на этапе запуска exe какую-нибудь структуру: TLS-калбэки,
CONTEXT, таблица импорта и т.п. Я патчил CONTEXT (лежит в стеке стартового потока), но у меня
не было цели запускаться так рано.

Еще, говорят, можно написать фильтрующий драйвер файловой системы (минифильтр) и в нем изменять
исполняемые файлы прямо во время их отображения в память (например, добавлять доп. секцию в
загруженный exe и там размещать свой код), при этом будут проблемы с проверкой целостности
файлов (цифровые подписи) и другие...
Re: Исполнение кода на ранней стадии инициализации процесса
От: ononim  
Дата: 02.11.18 11:37
Оценка:
4) QueueUserApc, с учетом битности процесса. LdrpInitilizeProcess вызывает NtTestAlert перед переходом на точку входа, после исполнения DllMain прилинкованных длл-ке, потому APC исполнится. Но есть тонкость — NtTestAlert может вызвать DllMain одна из длл-ек и могут быть сюрпризы с порядком инициализации, так что ничего кроме ntdll/kernel32 лучше не юзать.
Как много веселых ребят, и все делают велосипед...
Re[4]: Исполнение кода на ранней стадии инициализации процесса
От: _NN_ www.nemerleweb.com
Дата: 16.11.18 09:16
Оценка:
Здравствуйте, okman, Вы писали:

O>Еще можно на этапе загрузки exe пропатчить таблицу импорта и вставить туда свою dll.

O>Так делает McAfee, если память не изменяет.

Это как раз самый надёжный вариант.
Только нужно учитывать параллельную загрузку dll-ек в Windows 10.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[4]: Исполнение кода на ранней стадии инициализации процесса
От: smbdnew  
Дата: 22.11.18 14:57
Оценка:
Здравствуйте, okman, Вы писали:

O>Если надо совсем-совсем раньше, прямо сразу после загрузки ntdll/kernel32, то вариантов немного.


O>Можно попробовать вариант с APC (KeInitializeApc/KeInsertQueueApc и далее alertable-ожидание,

O>чтобы APC сразу прилетела в поток), хотя тут 100% будут конфликты с другим софтом (антивирусы) и
O>есть масса других проблем. Описан в статье "способ принудительной загрузки dll..." (и сразу не
O>советую слепо доверять тому, что там написано и приведенному коду — его еще фиксить и фиксить).

Забыл отписать, на нём в итоге и остановился.
Вариант с форсированной доставкой APC в итоге не пригодился, меня устроил вызов перед точкой входа.
Просматривая чьи то исходники видел форсированную доставку не через alertable ожидание, а через доставку пустой kernel APC сразу после моей.
По причине ненадобности проверять не стал, но интересно — такой вариант жизнеспособен в теории ?
Re[5]: Исполнение кода на ранней стадии инициализации процесса
От: okman Беларусь https://searchinform.ru/
Дата: 24.11.18 08:52
Оценка:
Здравствуйте, smbdnew, Вы писали:

S>Просматривая чьи то исходники видел форсированную доставку не через alertable ожидание, а через доставку пустой kernel APC сразу после моей.

S>По причине ненадобности проверять не стал, но интересно — такой вариант жизнеспособен в теории ?

Насколько я знаю, доставка юзерских APC выполняется или при alertable-ожидании, или посредством вызова
специальных сервисов типа NtTestAlert/KeTestAlertThread. В итоге для потока выставляется флаг
"User APC Pending = TRUE" и при выходе из системного вызова как раз и происходит доставка.

Например, загрузчик в ntdll как раз и вызывает NtTestAlert ровно перед тем, как прыгнуть на точку входа;
на этом факте, как правило, и построены методы с внедрением dll через APC.

Как доставка kernel APC может "сама по себе" доставить пользовательскую APC — мне неизвестно.
Скорее всего, там какие-то детали остались за кадром...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.