Способ принудительной загрузки DLL в адресное пространство п
От: Сторожевых Сергей Россия  
Дата: 14.11.07 17:18
Оценка: 810 (17)
#Имя: FAQ.asm.Inject DLL
Статья:
Способ принудительной загрузки DLL в адресное пространство процесса
Автор(ы): Сторожевых Сергей
Дата: 14.11.2007
При решении многих задач системного программированния зачастую бывает необходимо загрузить динамически подключаемую библиотеку (DLL) в адресное пространство другого процесса, с целью исследования либо изменения его поведения. В данной статье показан способ, позволяющий внедрить DLL в любой процесс (в том числе защищенный) на самом раннем этапе его создания.


Авторы:
Сторожевых Сергей

Аннотация:
При решении многих задач системного программированния зачастую бывает необходимо загрузить динамически подключаемую библиотеку (DLL) в адресное пространство другого процесса, с целью исследования либо изменения его поведения. В данной статье показан способ, позволяющий внедрить DLL в любой процесс (в том числе защищенный) на самом раннем этапе его создания.

17.03.08 19:58: Перенесено из 'WIN API'
Re: Способ принудительной загрузки DLL в адресное пространст
От: lifrsdn  
Дата: 17.03.08 14:32
Оценка:
Здравствуйте, Сторожевых Сергей,

Внимательно прочитал всю статью, но не нашел ссылку на исходные тексты. Не подскажете где взять? Или это теоретическая разработка?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[2]: Способ принудительной загрузки DLL в адресное простра
От: Sergey Storozhevykh Россия  
Дата: 17.03.08 15:18
Оценка:
Здравствуйте, lifrsdn, Вы писали:

L>Внимательно прочитал всю статью, но не нашел ссылку на исходные тексты. Не подскажете где взять? Или это теоретическая разработка?


Странно, должно было быть с исходниками.

Кстати, в анонс к статье вкралась ошибка: способ не работает для защищенных процессов. В самой статье об этом говорится отдельно, а вот шапку проморгали
Re[3]: Способ принудительной загрузки DLL в адресное простра
От: lifrsdn  
Дата: 17.03.08 15:35
Оценка:
Здравствуйте, Sergey Storozhevykh, Вы писали:

L>>Внимательно прочитал всю статью, но не нашел ссылку на исходные тексты. Не подскажете где взять? Или это теоретическая разработка?


SS>Странно, должно было быть с исходниками.


Спасибо, скачал. В тексте статьи не мог найти эту ссылку.

SS>Кстати, в анонс к статье вкралась ошибка: способ не работает для защищенных процессов. В самой статье об этом говорится отдельно, а вот шапку проморгали


Да, так и написано. Даже есть ссылка на ту утилиту, что работает с защищенными.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[4]: Способ принудительной загрузки DLL в адресное простра
От: Sergey Storozhevykh Россия  
Дата: 17.03.08 15:47
Оценка:
Здравствуйте, lifrsdn, Вы писали:

L>Да, так и написано. Даже есть ссылка на ту утилиту, что работает с защищенными.


Ну это как раз по делу написано, чтоб показать, что нет ничего невозможного Просто сам по себе способ не годится для этого (без докруток, напрямую не относящихся к самому способу).
Re: Способ принудительной загрузки DLL в адресное пространст
От: Аноним  
Дата: 18.03.08 09:09
Оценка:
Здравствуйте, Сторожевых Сергей, Вы писали:

Статья:

В работе был предложен новый способ принудительной загрузки DLL в адресное пространство процесса


Это далеко не новый способ. Есть продукты в которых он уже используется.
Re[2]: Способ принудительной загрузки DLL в адресное простра
От: Sergey Storozhevykh Россия  
Дата: 18.03.08 09:35
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Это далеко не новый способ. Есть продукты в которых он уже используется.


С форсированием инжекта? с поддержкой WOW64?
Re[3]: Способ принудительной загрузки DLL в адресное простра
От: Аноним  
Дата: 18.03.08 11:19
Оценка:
Здравствуйте, Sergey Storozhevykh, Вы писали:

SS>С форсированием инжекта? с поддержкой WOW64?


Точно не скажу, не проверял. Но для инжекта тоже используется механизм APC. Инжект производится в процессы WinLogon и Explorer как минимум.
Re[4]: Способ принудительной загрузки DLL в адресное простра
От: Sergey Storozhevykh Россия  
Дата: 18.03.08 11:49
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Точно не скажу, не проверял. Но для инжекта тоже используется механизм APC. Инжект производится в процессы WinLogon и Explorer как минимум.


Да, это я знаю и проводил обзор известных решений в ходе работы. Но основной момент — внедрить DLL на самом раннем этапе (форсирование доставки APC) до инициализации статически-связанных библиотек. Этому посвящена существенная часть статьи. Причем, в общем случае, этот способ позволят при необходимости жестко задать момент инжекта (до определенной пользовательской DLL). Плюс поддержка WOW64. На тот момент, когда писалась статья (группо)гугл выдавал 0 результатов на запрос Wow64ApcRoutine.
Re[3]: Способ принудительной загрузки DLL в адресное простра
От: Valery A. Boronin Россия linkedin.com/in/boronin
Дата: 18.03.08 11:57
Оценка:
Здравствуйте, Sergey Storozhevykh, Вы писали:

А>>Это далеко не новый способ. Есть продукты в которых он уже используется.

SS>С форсированием инжекта? с поддержкой WOW64?
конечно, например у нас уже несколько лет

есть небольшие различия, однако это нисколько не умаляет достоинств предложенного решения — Сергей, принимай свои заслуженные 3 балла от меня. Именно такие качественные статьи могут удержать и поднять уровень ресурса
... << RSDN@Home 1.2.0 alpha rev. 0>>
Valery A. Boronin, RSDN Team, linkedin.com\in\boronin
R&D Mgmt & Security. AppSec & SDL. Data Protection and Systems Programming. FDE, DLP, Incident Management. Windows Filesystems and Drivers.
Re[4]: Способ принудительной загрузки DLL в адресное простра
От: Sergey Storozhevykh Россия  
Дата: 18.03.08 12:15
Оценка:
Здравствуйте, Valery A. Boronin, Вы писали:

SS>>С форсированием инжекта? с поддержкой WOW64?

VAB>конечно, например у нас уже несколько лет

Ну мне было затруднительно провести обзор аналогов подобного рода

VAB>есть небольшие различия, однако это нисколько не умаляет достоинств предложенного решения — Сергей, принимай свои заслуженные 3 балла от меня. Именно такие качественные статьи могут удержать и поднять уровень ресурса


Спасибо!
Re[5]: Способ принудительной загрузки DLL в адресное простра
От: Valery A. Boronin Россия linkedin.com/in/boronin
Дата: 18.03.08 12:35
Оценка:
Здравствуйте, Sergey Storozhevykh, Вы писали:

SS>>>С форсированием инжекта? с поддержкой WOW64?

VAB>>конечно, например у нас уже несколько лет

SS>Ну мне было затруднительно провести обзор аналогов подобного рода

кстати все различие по большому счету лишь в том, что мы не трогали Wow64ApcRoutine, а фактически сделали эту ф-ть руками. просто оказалось быстрее, чем искать в Сети — тем более что в 2006 (или даже чуть раньше?) и не находилось действительно ничего толком... справедливости ради предложение поискать недокументированный аналог у МС звучало на самых ранних обсуждениях этого дела, мы понимали что им самим оно нужно

Пиши это дело сейчас, наверное бы тоже пошли по описанному в статье пути — ну да без реальной нужды переписывать куски продукта никакого времени не хватит — так и живем без Wow64ApcRoutine с самопальным кодом

Зато лавры пионера Wow64ApcRoutine остаются целиком за тобой и всеми кто поучавствовал из Agnitum
... << RSDN@Home 1.2.0 alpha rev. 0>>
Valery A. Boronin, RSDN Team, linkedin.com\in\boronin
R&D Mgmt & Security. AppSec & SDL. Data Protection and Systems Programming. FDE, DLP, Incident Management. Windows Filesystems and Drivers.
Re[6]: Способ принудительной загрузки DLL в адресное простра
От: Sergey Storozhevykh Россия  
Дата: 18.03.08 12:44
Оценка:
Здравствуйте, Valery A. Boronin, Вы писали:

VAB>Зато лавры пионера Wow64ApcRoutine остаются целиком за тобой и всеми кто поучавствовал из Agnitum


Справедливости ради хочу отметить, что сейчас гугл находит старый топик на wasm.ru датированный 2006-ым годом. Однако на момент разработки способа и написания статьи почему-то не находил, видимо недавно только проиндексировал

Ну и вдобавок опять таки после сдачи статьи появился замечательный A catalog of NTDLL kernel mode to user mode callbacks, part 3: KiUserApcDispatcher.
Re[7]: Способ принудительной загрузки DLL в адресное простра
От: Аноним  
Дата: 18.03.08 18:36
Оценка: +1
В любом случае статья хорошая.
Re[7]: Способ принудительной загрузки DLL в адресное простра
От: Valery A. Boronin Россия linkedin.com/in/boronin
Дата: 18.03.08 21:10
Оценка:
VAB>>Зато лавры пионера Wow64ApcRoutine остаются целиком за тобой и всеми кто поучавствовал из Agnitum

SS>Справедливости ради хочу отметить, что сейчас гугл находит старый топик на wasm.ru датированный 2006-ым годом. Однако на момент разработки способа и написания статьи почему-то не находил, видимо недавно только проиндексировал

ну так и кывт одно время не очень хорошо индексировался, если не путаю у нас даже спец защиты были от индексаторов — просто политика вроде изменилась некоторое время назад. Может быть и у wasm что-то подобное случилось?

кстати любопытно что воин цзена maxdm оставил на wasm ровно одно сообщение — правильно, то самое о котором речь выше

SS>Ну и вдобавок опять таки после сдачи статьи появился замечательный A catalog of NTDLL kernel mode to user mode callbacks, part 3: KiUserApcDispatcher.

да, блог отличный, всегда приятно читать. Указанная 3я часть появилась on Monday, November 19th, 2007 at 1:38 pm
А твою статью мы начали обсуждать на квартал-другой раньше в приватном порядке, если правильно помню. Даже внутри RSDN первый вариант появился "официально" в середине сентября 2007 — вот сейчас глянул. Так что в плане статей\заметок на блогах — остаешься пионером, Сергей, деваться тут некуда
... << RSDN@Home 1.2.0 alpha rev. 0>>
Valery A. Boronin, RSDN Team, linkedin.com\in\boronin
R&D Mgmt & Security. AppSec & SDL. Data Protection and Systems Programming. FDE, DLP, Incident Management. Windows Filesystems and Drivers.
Re: Способ принудительной загрузки DLL в адресное пространст
От: gear nuke  
Дата: 19.03.08 15:01
Оценка:
Здравствуйте, Сторожевых Сергей, Вы писали:

СС>необходимо либо реализовывать логику загрузчика самостоятельно, либо отложить внедрение нужной DLL (обозначим как inject.dll), пока не произойдет переход потока в режим пользователя и не инициализируется системный загрузчик.


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


А какие, собственно, струтуры нужны, PEB.Ldr?

Тут выходит весь финт с форсированием APC делается для одной цели — подождать пока LdrpInitialize (LdrInitializeThunk) сформиреут окружение лоадера, что бы можно было вызвать LdrLoadDll.

Ведь в это же время можно так же и "вручную" загрузить модули из ядра (всё равно же вместо трудоёмкого загрузчика используется ZwMapViewOfSection, даже релоки настраивает). LdrpHashTable (LdrpCheckForLoadedDll) скорее всего не требуется для таких dll, для вызова точки входа dll конечно придётся руками добавить в список... Но есть 2 момента... Что будет выполнять DllEntry, помимо дебажных сообщений? Никаких других dll нет, и (на подавляющем большенстве систем это будет работать!) исполняемый модуль может не импортировать ничего.

СС> К тому же при реализации собственного загрузчика в режиме ядра необходимо учитывать, что inject.dll, в свою очередь, может иметь обширный список статически связанных DLL, которые также нужно будет загрузить и вызвать их точки входа.


По-моему обработать таблицу экспорта и вызвать загрузчик рекурсивно не сложнее, чем парсить импорт ntdll.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[2]: Способ принудительной загрузки DLL в адресное простра
От: Sergey Storozhevykh Россия  
Дата: 20.03.08 11:37
Оценка:
Здравствуйте, gear nuke, Вы писали:

GN>Здравствуйте, Сторожевых Сергей, Вы писали:


Спасибо за отклик!

СС>>необходимо либо реализовывать логику загрузчика самостоятельно, либо отложить внедрение нужной DLL (обозначим как inject.dll), пока не произойдет переход потока в режим пользователя и не инициализируется системный загрузчик.


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

Под корректной загрузкой я понимаю здесь следующее: загрузить так, чтобы это с одной стороны не накладывало ограничений на саму DLL, а с другой — чтоб для системы такая DLL была "как родная". Самый простой способ это сделать — это попросить сиситему саму загрузить DLL. Это гарантирует нам корректность и к тому же избавляет от лишней ручной работы.

GN>А какие, собственно, структуры нужны, PEB.Ldr?

да, по крайней мере. И сторого говоря PEB тоже недокументирован. Причем здесь важны не только сам формат структур но и логика, последовательность действий загрузчика при работе с ними.

GN>Тут выходит весь финт с форсированием APC делается для одной цели — подождать пока LdrpInitialize (LdrInitializeThunk) сформиреут окружение лоадера, что бы можно было вызвать LdrLoadDll.

Не совсем. То, что вы отметили, касается самой идеи реализации инжекта с помощью APC, а трюк с форсированием — для того, чтоб наша DLL загрузилась строго раньше других. Причем в статье отмечается, что момент инжекта может быть определен с точностью до определенной DLL (т.е. инжект будет произведен перед определенной DLL, в том числе загружаемой динамически).

GN>Ведь в это же время можно так же и "вручную" загрузить модули из ядра (всё равно же вместо трудоёмкого загрузчика используется ZwMapViewOfSection, даже релоки настраивает).

ZwMapViewOfSection фиксит релоки?

GN>LdrpHashTable (LdrpCheckForLoadedDll) скорее всего не требуется для таких dll,

но может понадобится для тех DLL, которые связаны статически с inject.dll.

GN>для вызова точки входа dll конечно придётся руками добавить в список...

да

GN>Но есть 2 момента... Что будет выполнять DllEntry, помимо дебажных сообщений? Никаких других dll нет, и (на подавляющем большенстве систем это будет работать!) исполняемый модуль может не импортировать ничего.

здесь не совсем понял, что имеется в виду, но если речь о DllEntry инжектируемой DLL, то никаких ограничений нет. Нужнные DLL из импорта подгрузятся как обычно.

СС>> К тому же при реализации собственного загрузчика в режиме ядра необходимо учитывать, что inject.dll, в свою очередь, может иметь обширный список статически связанных DLL, которые также нужно будет загрузить и вызвать их точки входа.


GN>По-моему обработать таблицу экспорта и вызвать загрузчик рекурсивно не сложнее, чем парсить импорт ntdll.

да, при этом найти импортируемые DLL в соответствии с правилами LoadLibrary, позаботиться о known DLLs, не допустить повторной загрузки и увеличить счетчик ссылок где надо, поставить в очередь для инициализации...

В общем слишком много ручной работы и тонких мест, поэтому я и назвал этот вариант трудоемким, и, в самом начале работы отмел и пристально не исследовал возможность его реализации.
Re: Способ принудительной загрузки DLL в адресное пространст
От: Аноним  
Дата: 21.03.08 06:48
Оценка:
Здравствуйте, Сторожевых Сергей, Вы писали:

СС>Статья:

СС>Способ принудительной загрузки DLL в адресное пространство процесса
Автор(ы): Сторожевых Сергей
Дата: 14.11.2007
При решении многих задач системного программированния зачастую бывает необходимо загрузить динамически подключаемую библиотеку (DLL) в адресное пространство другого процесса, с целью исследования либо изменения его поведения. В данной статье показан способ, позволяющий внедрить DLL в любой процесс (в том числе защищенный) на самом раннем этапе его создания.

СС>Авторы:
СС> Сторожевых Сергей
СС>Аннотация:
СС>При решении многих задач системного программированния зачастую бывает необходимо загрузить динамически подключаемую библиотеку (DLL) в адресное пространство другого процесса, с целью исследования либо изменения его поведения. В данной статье показан способ, позволяющий внедрить DLL в любой процесс (в том числе защищенный) на самом раннем этапе его создания.
Сергей, получите заслуженные 3 балла — отличная статья, много познавательного материала.
Re[3]: Способ принудительной загрузки DLL в адресное простра
От: gear nuke  
Дата: 21.03.08 09:26
Оценка:
Здравствуйте, Sergey Storozhevykh, Вы писали:

SS>И сторого говоря PEB тоже недокументирован. Причем здесь важны не только сам формат структур но и логика...


Собствено, я к этому и вёл — PEB документирован ровно так же, как и APC. Более того, форсирование APC как раз закладывается на "последовательность действий загрузчика" (и поэтому не работает на Vista 64)

То есть возможно, ради совместимости с Вистой, можно подумать всё же о ручном заполнении структур. Сама идея ожидания загрузки импортируемых модулей хорошая — Ldr должен быть в этот момент инициализирован в любой системе (иначе как она будет добавлять в список еще модуль) можно даже пропарсить импорт exe и делать прогноз, сработает ли.

Кстати для запуска кода есть еще диспетчер исключений...

SS>если речь о DllEntry инжектируемой DLL, то никаких ограничений нет. Нужнные DLL из импорта подгрузятся как обычно.


И да и нет. В АП не каждого процесса можно грузить какие попало dll.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[4]: Способ принудительной загрузки DLL в адресное простра
От: Sergey Storozhevykh Россия  
Дата: 21.03.08 09:46
Оценка:
Здравствуйте, gear nuke, Вы писали:

GN>Собствено, я к этому и вёл — PEB документирован ровно так же, как и APC. Более того, форсирование APC как раз закладывается на "последовательность действий загрузчика" (и поэтому не работает на Vista 64)


Инжект без форсирования работает везде. Форсирование не работает только в WOW64 (безотносительно к версии Windows). Т.к. при форсировании на самом раннем этапе не инициализировано окружение WOW64.

GN>То есть возможно, ради совместимости с Вистой, можно подумать всё же о ручном заполнении структур. Сама идея ожидания загрузки импортируемых модулей хорошая — Ldr должен быть в этот момент инициализирован в любой системе (иначе как она будет добавлять в список еще модуль) можно даже пропарсить импорт exe и делать прогноз, сработает ли.


GN>Кстати для запуска кода есть еще диспетчер исключений...


Боюсь здесь возникнут те же самые проблемы с WOW64. По любому нужно ждать пока окружение WOW64 будет полностью проинициализировано.

GN>И да и нет. В АП не каждого процесса можно грузить какие попало dll.


Да, но смысл в том, что если DLL может быть в принципе загружена для этого процесса обычным способом, то она будет загружена и с помощью предлагаемого инжекта.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.