Перехвар api до вызова DLLMain
От: Aniskin  
Дата: 28.09.17 03:10
Оценка:
Правильно ли я понимаю, что если я хочу в загружаемой dll перехватить вызов некой функции из kernel32.dll до вызова DLLMain, то у меня есть три пути:

1) Сплайсинг самой функции из kernel32.dll
2) Запуск процесса в режиме отладки и ожидание WaitForDebugEvent с LOAD_DLL_DEBUG_EVENT и последующая модификация IAT таблицы.
3) Написание своего загрузчика dll, в котором будет модифицироваться IAT таблица.
Re: Перехвар api до вызова DLLMain
От: EreTIk EreTIk's Box
Дата: 28.09.17 16:52
Оценка: 6 (2)
Здравствуйте, Aniskin, Вы писали:

A>Правильно ли я понимаю, что если я хочу в загружаемой dll перехватить вызов некой функции из kernel32.dll до вызова DLLMain, то у меня есть три пути:


Механизм SHIM (Application Verifier) — https://github.com/ionescu007/HookingNirvana/blob/master/Esoteric%20Hooks.pdf, раздел "AVRF Hooks" и до конца документа
PoC — https://github.com/ionescu007/HookingNirvana/tree/master/verif.dll
Re: Перехвар api до вызова DLLMain
От: ononim  
Дата: 28.09.17 20:51
Оценка: 6 (2)
A>1) Сплайсинг самой функции из kernel32.dll
A>2) Запуск процесса в режиме отладки и ожидание WaitForDebugEvent с LOAD_DLL_DEBUG_EVENT и последующая модификация IAT таблицы.
A>3) Написание своего загрузчика dll, в котором будет модифицироваться IAT таблица.
Для ценителей:
4.a) LdrRegisterDllNotification + сплайсинг DllMain + модификация IAT из хука на DLLMain
Для рисковых ценителей:
4.b) LdrRegisterDllNotification + патч EntryPoint в соответствующей LDR_DATA_TABLE_ENTRY + модификация IAT из хука на DLLMain

ЗЫ А может все-таки в отдельном процессе запустить тот архиватор?
Как много веселых ребят, и все делают велосипед...
Re[2]: Перехвар api до вызова DLLMain
От: Aniskin  
Дата: 29.09.17 03:55
Оценка:
Здравствуйте, ononim, Вы писали:

O>ЗЫ А может все-таки в отдельном процессе запустить тот архиватор?


Для ситуации, в которой мне понадобилось произвести перехват api до вызова DLLMain, "тот архиватор" уже в отдельном процессе, точнее в отдельном COM сервере.
Re: Перехвар api до вызова DLLMain
От: rumit7  
Дата: 29.09.17 06:35
Оценка:
Здравствуйте, Aniskin, Вы писали:

A>Правильно ли я понимаю, что если я хочу в загружаемой dll перехватить вызов некой функции из kernel32.dll до вызова DLLMain, то у меня есть три пути:


что за dll? как она грузится? что за функция из кернел32? зачем это вам вообще?
я думаю если знать ситуацию ближе, то и вариантов куда больше будет
Re[2]: Перехвар api до вызова DLLMain
От: Aniskin  
Дата: 29.09.17 08:45
Оценка: 15 (3)
Здравствуйте, rumit7, Вы писали:

R>я думаю если знать ситуацию ближе, то и вариантов куда больше будет


Есть у меня широко известный в узких кругах проект TC4Shell. Суть проекта — работа с разными архивами в Проводнике, как с простыми папками. Сам проект по сути представляет собой враппер над различными сторонними dll, такими как 7z.dll и unrar.dll. Дополнительно реализована возможность подключения WCX плагинов от TotalCommander. Все это чудесненько работает.

Решил я добавить поддержку плагинов от FAR. И добавил. И снова все чудесненько работает, включая эмуляцию FAR dialog api. Но есть один момент. Поскольку сам FAR и его плагины работают в консоли, то мне нужно перехватывать и эмулировать слой API, работающий с консолью. Я это сделал, но обнаружил, что отдельные плагины вызывают консольное API в DLLMain. Например, плагин NetBox, вызывает CreateFile('CONIN$') и сохраняет полученный хендл в своих закромах, который затем использует (в частности) при вызове Peek/ReadConsoleInput. Но поскольку в Проводнике консоли нет, то CreateFile возвращает INVALID_HANDLE_VALUE, и мне в перехваченную Peek/ReadConsoleInput также приходит INVALID_HANDLE_VALUE. Я в данный момент делаю так: если мне пришел INVALID_HANDLE_VALUE, то считаю, что это мой правильный хендл, и соответственно обрабатываю его. Но как то это не красиво. Вот и хочу попробовать перехватывать API не после LoadLibrary, а до вызова DLLMain.

А перехватываю я очень много. CreateFileAW/CloseHandle и практически все из списка. Как то так.
Re[3]: Перехвар api до вызова DLLMain
От: SaZ  
Дата: 29.09.17 11:39
Оценка:
Здравствуйте, Aniskin, Вы писали:

A>Есть у меня широко известный в узких кругах проект TC4Shell.


Спасибо, круто.
Re[3]: Перехвар api до вызова DLLMain
От: rumit7  
Дата: 29.09.17 11:51
Оценка: 3 (1)
Здравствуйте, Aniskin, Вы писали:

A>Вот и хочу попробовать перехватывать API не после LoadLibrary, а до вызова DLLMain.


тогда до кучи — перехват NtMapViewOfSection, там как-то так получится:

LoadLibrary->LdrLoadDll->LdrpFindOrMapDll->LdrpMapViewOfSection->NtMapViewOfSection
...
LoadLibrary->LdrLoadDll->...->LdrpCallInitRoutine->DllMain


Остается после вызова оригинальной NtMapViewOfSection узнать имя замапленной секции, и если это нужная длл, то "делаем нехорошие дела дальше".
Но принцип такой-же как и указанно выше
Автор: ononim
Дата: 28.09.17
уважаемым ononim-ом.


A>А перехватываю я очень много. CreateFileAW/CloseHandle и практически все из списка. Как то так.


ну на всякий случай скину, может Ваш случай:

Faking KERNEL32.DLL — an Amateur Sandbox
Using Pragmas to Create a Proxy DLL
Forwarded DLL Exports and an Interesting Loader Behaviour
Отредактировано 29.09.2017 11:53 rumit7 . Предыдущая версия . Еще …
Отредактировано 29.09.2017 11:52 rumit7 . Предыдущая версия .
Re[3]: Перехвар api до вызова DLLMain
От: ononim  
Дата: 29.09.17 15:58
Оценка:
A>но обнаружил, что отдельные плагины вызывают консольное API в DLLMain.
Ну если "тот архивтаор" правда в отдельном процессе, то не проще ли дать ему консольку на руки при помощи AllocConsole? Ее кстати даже не обязательно делать видимой, можно спрятать ее окно или ваще запускать процесс на неинтерактивном десктопе, а если хочется значть что он там такое рисует — периодически вычитывать содержимое консольки ReadConsoleOutput()-ом
Как много веселых ребят, и все делают велосипед...
Отредактировано 29.09.2017 15:59 ononim . Предыдущая версия .
Re: Перехвар api до вызова DLLMain
От: BLov  
Дата: 29.09.17 19:30
Оценка:
Здравствуйте, Aniskin, Вы писали:

A>1) Сплайсинг самой функции из kernel32.dll

A>2) Запуск процесса в режиме отладки и ожидание WaitForDebugEvent с LOAD_DLL_DEBUG_EVENT и последующая модификация IAT таблицы.
A>3) Написание своего загрузчика dll, в котором будет модифицироваться IAT таблица.

Так была же тема, епрст — http://www.rsdn.org/forum/asm/6681483.1

Андрей, выложил, посмотрите.
Re[4]: Перехвар api до вызова DLLMain
От: Aniskin  
Дата: 29.09.17 19:39
Оценка:
Здравствуйте, ononim, Вы писали:

O>не проще ли дать ему консольку на руки при помощи AllocConsole? Ее кстати даже не обязательно делать видимой, можно спрятать ее окно

Если вызывать AllocConsole, а затем прятать окно консоли, то окно мигает. Не красиво.

O>или ваще запускать процесс на неинтерактивном десктопе,

Я использую COM сервера (простота реализации, удобство вызова callback функций из сервера в клиентское приложение), т.е. процесс запускается не мной, а COM подсистемой.

O>если хочется знать что он там такое рисует — периодически вычитывать содержимое консольки ReadConsoleOutput()-ом

Для корректного UI мне нужен именно перехват функций.
Re[2]: Перехвар api до вызова DLLMain
От: Aniskin  
Дата: 29.09.17 21:08
Оценка:
Здравствуйте, BLov, Вы писали:

BL>Так была же тема, епрст — http://www.rsdn.org/forum/asm/6681483.1


BL>Андрей, выложил, посмотрите.


Посмотрел. Осознал, как мало я знаю о этой жизни... Для меня это слишком сложно, не осилю.
Re[5]: Перехвар api до вызова DLLMain
От: Denwer Россия  
Дата: 02.10.17 09:51
Оценка:
Здравствуйте, Aniskin, Вы писали:

A>Здравствуйте, ononim, Вы писали:


O>>не проще ли дать ему консольку на руки при помощи AllocConsole? Ее кстати даже не обязательно делать видимой, можно спрятать ее окно

A>Если вызывать AllocConsole, а затем прятать окно консоли, то окно мигает. Не красиво.

Ну кончено не красиво, можно сделать и красиво. При создании процесса можно передать свои хендлы для ввода-вывода через структуру STARTUPINFO. Там обычные пайпы передаются. Никакого окна не будет.
Re[5]: Перехвар api до вызова DLLMain
От: Alexander G Украина  
Дата: 02.10.17 10:00
Оценка:
Здравствуйте, Aniskin, Вы писали:


O>>или ваще запускать процесс на неинтерактивном десктопе,

A>Я использую COM сервера (простота реализации, удобство вызова callback функций из сервера в клиентское приложение), т.е. процесс запускается не мной, а COM подсистемой.

Можно, чтобы процесс был COM-сервисом, правда инсталляция (регистрация) такого сервиса требует админа (но только регистрация).
Русский военный корабль идёт ко дну!
Re[6]: Перехвар api до вызова DLLMain
От: Aniskin  
Дата: 02.10.17 10:28
Оценка:
Здравствуйте, Denwer, Вы писали:

A>>Если вызывать AllocConsole, а затем прятать окно консоли, то окно мигает. Не красиво.


D>Ну кончено не красиво, можно сделать и красиво. При создании процесса можно передать свои хендлы для ввода-вывода через структуру STARTUPINFO. Там обычные пайпы передаются. Никакого окна не будет.


Спасибо за совет, но как я уже писал, мне не нужна консоль как таковая. Мне нужен именно перехват функций.
Re[6]: Перехвар api до вызова DLLMain
От: Aniskin  
Дата: 02.10.17 10:30
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>Можно, чтобы процесс был COM-сервисом, правда инсталляция (регистрация) такого сервиса требует админа (но только регистрация).


А где про это почитать?
Re[7]: Перехвар api до вызова DLLMain
От: Alexander G Украина  
Дата: 02.10.17 14:00
Оценка:
Здравствуйте, Aniskin, Вы писали:

A>А где про это почитать?


здесь.

An object written as a service is installed for use by COM by establishing a LocalService value under its AppID key and performing a standard service installation.


(Я вообще вручную этого никогда не делал, с ATL ведь как, Wizard, ATL Project, в Application Settings выбираешь Service — и всё работает).
Русский военный корабль идёт ко дну!
Отредактировано 02.10.2017 14:10 Alexander G . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.