Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.04.11;
Скачать: CL | DM;

Вниз

"Вклиниться" в адр. пространство библиотеки до выполнения Dllmain   Найти похожие ветки 

 
BiN ©   (2004-03-11 12:38) [0]

Добрый день, уважаемые мастера!
Возможно ли выполнить сабж без создания своего загрузчика.

Надеюсь, вы не подумаете, что здесь ведется разработка трояна - скорее наоборот.


 
Digitman ©   (2004-03-11 12:47) [1]

что значит "вклиниться" ?


 
Игорь Шевченко ©   (2004-03-11 12:50) [2]

А на какой предмет вклиниться, можно поподробнее ?

Можно ведь использовать LoadLibraryEx с флажком DONT_RESOLVE_DLL_REFERENCES, тогда DllMain вызываться не будет...


 
BiN ©   (2004-03-11 12:55) [3]

что значит "вклиниться"

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


 
Digitman ©   (2004-03-11 12:55) [4]


> Игорь Шевченко ©   (11.03.04 12:50) [2]


здесь, вероятно, имеется ввиду, что некий кодовый поток некоего (не обязательно текущего) процесса в статике или динамике грузит библ-ку, и требуется получить управление после загрузки, но до вызова системой DLLEntryPoint(DLL_PROCESS_ATTACH)


 
BiN ©   (2004-03-11 12:57) [5]

Digitman ©   (11.03.04 12:55) [4]

Спасибо за абсолютно правильную формулировку.


 
Digitman ©   (2004-03-11 12:59) [6]


> BiN ©   (11.03.04 12:55) [3]


в динамике, я думаю, можно перехватить вызов kernel32.LoadLibrary[Ex], по получению управления выполнить правку нужных таблиц, и после этого вернуть управление вызывающему коду

в статике, наверно, посложней будет


 
BiN ©   (2004-03-11 13:02) [7]

в дополнение  кпосту [3]: Меня настораживает фраза из SDK
Also, the system does not load additional executable modules that are referenced by the specified module

>>Digitman ©   (11.03.04 12:59) [6]
Да именно так я и делаю. Но ведь чтобы получить доступ к адресному пространству библиотеки, надо ее сначала загрузить, а тут как раз и просиходит вызов точки входа


 
Digitman ©   (2004-03-11 13:05) [8]


> надо ее сначала загрузить, а тут как раз и просиходит вызов
> точки входа


опять же - перехват LoadLibrary[Ex], в перехватчике - сначала [2], а потом - все остальное ... DLLEntryPoint в этом случае, по всей видимости. в своем перехватчике придется вызывать явно


 
BiN ©   (2004-03-11 13:22) [9]


в перехватчике - сначала [2], а потом - все остальное ...


вот функция перехватчика

var
 AddressOfEntryPoint:function (
 hinstDLL:HINSTANCE;  // handle to the DLL module
 fdwReason:DWORD;     // reason for calling function
 lpvReserved:Pointer):Bool; stdcall; будем считать, что адрес уже известен.

..
begin
 Result:=LoadLibraryEx("custom.dll",0 DONT_RESOLVE_DLL_REFERENCES);
 
 AddressOfEntryPoint(Result{?}, DLL_PROCESS_ATTACH, nil);
end;

Результат, к сожалению, -  AV при вызове какой-либо функции из библиотеки (адрес функции конечно проверяется на nil)


 
Digitman ©   (2004-03-11 13:56) [10]


> AddressOfEntryPoint


Это что ? Твоя собственная ф-ция ? как она реализована ?


 
BiN ©   (2004-03-11 14:16) [11]

Digitman ©   (11.03.04 13:56) [10]

Прошу прощения, между  Result:=.. и AddressOfEntryPoint(Result{?} ...
следует вставить

@AddressOfEntryPoint:=GetAddressOfEntryPoint(Result);
где GetAddressOfEntryPoint реализована как


function MakePtr(base:Dword;Offset:DWORD):Pointer;
begin
 Result:=Pointer(Base+Offset);
end;

function GetNtHeader(hLocalHinst:HMODULE):PImageNtHeaders;
var
 pDosHeader:PImageDosHeader;
begin
 pDosHeader:=PImageDosHeader(hLocalHinst);
 if IsBadReadPtr(Pointer(hLocalHinst),sizeof(PImageNtHeaders)) or (pDosHeader.e_magic<>IMAGE_DOS_SIGNATURE)
 then  Result:=nil
 else Result:=PImageNtHeaders(MakePtr(DWord(pDOSHeader),DWord(pDOSHeader._lfanew)));
end;

function GetAddressOfEntryPoint(hLib:HMODULE):Pointer;
var
 P:PImageNtHeaders;
begin
 P:=GetNtHeader(Result);
 if not Assigned(P)
 then Result:=nil
 else Result:=Pointer(P.OptionalHeader.AddressOfEntryPoint);
end;



Но я все же думаю, что таким способом нельзя корректно загрузить Dll. Ведь, как я уже говорил, LoadLibraryEx в случае с DONT_RESOLVE_DLL_REFERENCES не подружает дополнительно используемые модули.


 
BiN ©   (2004-03-11 14:19) [12]

...вдогонку
в строке  P:=GetNtHeader(Result); в функции GetAddressOfEntryPoint, конечно же должен стоять вместо Result hLib. Просто копирую код второпях


 
Игорь Шевченко ©   (2004-03-11 14:28) [13]

Сильно я сомневаюсь в возможности загрузки DLL с разрешением ссылок без вызова DllMain.

Единственная экпортируемая функция NTDLL.LdrLoadDll вызывает неэкспортируемую функцию NTDLL.LdrpLoadDll с параметром RunInitRoutines равным TRUE. Этот параметр как раз и определяет, нужно ли вызывать DllMain.

Может, глупое предложение, но попробовать LoadLibraryEx без разрешения ссылок, настроить таблицу импорта, убрать настроенные ссылки из таблицы импорта и вызывать Loadlibrary того же файла. На 90% не уверен, но попробовать можно.


 
Игорь Шевченко ©   (2004-03-11 14:30) [14]

P.S. Источник информации - MSDN Magazine RE :)


 
BiN ©   (2004-03-11 14:42) [15]

Игорь Шевченко ©   (11.03.04 14:28) [13]

Я уже проводил такой эксперимент


 H1:=LoadLibraryEx("custom.dll", 0, DONT_RESOLVE_DLL_REFERENCES)   H2:=LoadLibrary("custom.dll");

в результате H1 был равен H2 и при этом, что интересно, функция Dllmain не вызывалясь в обоих случаях. Что в принципе понятно: в SDK так и сказано:
During initial process startup or after a call to LoadLibrary, the system scans the list of loaded DLLs for the process. For each DLL that has not already been called with the DLL_PROCESS_ATTACH value, the system calls the DLL"s entry-point function.
--------------------
Следовательно LoadLibrary в нашем случае найдя уже существующую ссылку на эту библиотеку, просто не загружает ее вторично.

К тому же, попробуйте вызвать
SomeProc:=GetProcAddress(H2);
if Assigned(SomeProc)
then SomeProc(); В результате получаете AV


 
Digitman ©   (2004-03-11 14:46) [16]


> BiN


а тебе вызов каких ф-ций каких библиотек нужно перенаправить на себя ?


 
BiN ©   (2004-03-11 14:54) [17]

Digitman ©   (11.03.04 14:46) [16]

Хотелось бы, конечно произвольных. Я понимаю, что для перехвата записи-чтения на носители, а также в ms-реестр, можно (скорее всего даже нужно) написать драйвер аля Руссинович/Соломон- в этом направлении я тоже продвигаюсь - но все же хотелось бы обойтись только пользовательским режимом и только работой с одним процессом(+ его возможными дочерними).


 
Игорь Шевченко ©   (2004-03-11 14:59) [18]

BiN ©   (11.03.04 14:54)

Ну что же, мои 90% переросли в 100%

И все-таки, если не секрет, какую проблему надо решить ? Может, есть альтернативный способ ?


 
BiN ©   (2004-03-11 15:06) [19]

И все-таки, если не секрет, какую проблему надо решить ?

API-монитор, с возможностью разрешения/отклонения/перенаправления потенциально опасных действий.


 
Игорь Шевченко ©   (2004-03-11 15:16) [20]

BiN ©   (11.03.04 15:06)

Драйвер + Policy. Остальные способы не заткнут все дырки.


 
BiN ©   (2004-03-11 15:21) [21]

Ну что ж, спасибо всем за советы


 
BiN ©   (2004-03-12 11:35) [22]

Решение найдено. Перехватить вызов DllEntryPoint можно путем правки кода вызова этой функции в адресном пространстве ntdll.


 
evvcom   (2004-03-12 12:05) [23]

Тогда это приложение будет работать под семейством WinNT. В 9x ntdll нет.


 
Игорь Шевченко ©   (2004-03-12 12:12) [24]

BiN ©   (12.03.04 11:35)

Подробнее, пожалуйста, лучше всего, с примером


 
Kerk ©   (2004-03-12 14:58) [25]

практически тоже самое:
http://rootkit.host.sk/knowhow/hidingru.txt


 
Игорь Шевченко ©   (2004-03-12 15:34) [26]

Kerk ©   (12.03.04 14:58)

И где там написано про то, как загрузить DLL и перехватить вызов DLLMain при загрузке ?

<offtopic>
На какие только ухищрения народ не идет, чтобы гадость ближнему сделать, просто поразительно.
</offtopic>


 
Kerk ©   (2004-03-12 15:39) [27]

2Игорь Шевченко
Вот:
Все остальные модули могут быть загружены динамически в середине кода после
перехвата процесса. Вот почему мы должны перехватить LdrLoadDll, которая
загружает новые модули.
       
       NTSTATUS LdrLoadDll(
               PWSTR szcwPath,
               PDWORD pdwLdrErr,      
               PUNICODE_STRING pUniModuleName,
               PHINSTANCE pResultInstance
       );

       Наиболее важно для нас pUniModuleName - имя модуля. pResultInstance
будет адресом модуля, если вызов был успешен.
       Мы вызовем оригинальную LdrLoadDll и затем перехватим все функции в
загруженном модуле.


 
Игорь Шевченко ©   (2004-03-12 16:00) [28]

Kerk ©   (12.03.04 15:39)

LdrLoadDll в процессе своей работы вызывает DLLMain (DllEntryPoint) в загружаемой DLL. Автору ветки хочется иметь возможность получить доступ к DLL до вызова DLLMain.
Текст "для пакостников" не говорит, как это сделать.


 
Kerk ©   (2004-03-12 16:10) [29]

При изучении LdrLoadDll оказывается, что она сводится к другой функции, которая и производит чтения параметров и соответствующие вызовы ядра. И в NT, и в w2k дополнительным параметром является булевская переменная - исполнять или нет цепочку DllMain. Вызовем функцию LdrLoadDll "не с начала", а после того, как положим в стек 0 - FALSE (а не 1 - TRUE). Таким образом, после завершения LdrLoadDll и соответствующего исправления таблиц импорта нам останется лишь вызвать DllMain всех вновь появившихся модулей с причиной DLL_PROCESS_ATTACH.
http://i2r.rusfund.ru/static/565/out_16836.shtml
:-)

А почему это текст - "текст для пакостников"?
Тут раз в неделю появляются вопросы тех, кто пишет софт для всяких там клубов, о том, как от всех спрятаться...


 
Игорь Шевченко ©   (2004-03-12 16:21) [30]

Способ, описанный в этой статье (вызов "не с начала"), может сгодиться только для условии точного изучения конкретных реализаций функции LdrLoadDll. (И такое изучение придется делать для каждой системы, если не для каждого сервис-пака). Проще уж по методу Свена Шрайбера, через файлы идентификаторов для отладчика находить нужные адреса неэкспортируемых функций, составить табличку с адесами в каждом конкретном сервис-паке каждой конкретной версии системы (этот способ тоже имеет право на существование, благо неоднократно опробовался) и вызвать нужные функции (в данном случае, LdrpLoadDll) напрямую.


> А почему это текст - "текст для пакостников"?


I give you three guesses...


 
Kerk ©   (2004-03-12 16:27) [31]


> Способ, описанный в этой статье (вызов "не с начала")...


вызов "не с начала" описан не в этой статье... я ж ссылку совсем в другое место дал. Статья, о которой ты сказал, что это "текст для пакостников", не описывает как перехватить функции до выполнения DllMain [надо, кстати, это автору сказать].

методы описаные в статье реализованы в проекте HackerDefender и тестировались в разных операционках и сервис-паках.


 
Игорь Шевченко ©   (2004-03-12 16:37) [32]

Kerk ©   (12.03.04 16:27)


> Статья, о которой ты сказал, что это "текст для пакостников",
> не описывает как перехватить функции до выполнения DllMain


Ну хоть тут мы согласились.

> методы описаные в статье реализованы в проекте HackerDefender
> и тестировались в разных операционках и сервис-паках.

Только в статье приводится код с комментарием для NT4...

; в NT4 LdrLoadDll
                                            ; начинается командами
                                            ; push ebp | mov ebp,esp |
                                            ; push byte

Так вот, как ни странно, в других системах, функция LdrLoadDll начинается иначе... Например, в XP


 
Kerk ©   (2004-03-12 16:41) [33]


> > методы описаные в статье реализованы в проекте HackerDefender
>
> > и тестировались в разных операционках и сервис-паках.
>
> Только в статье приводится код с комментарием для NT4...


Блин, то ли лыжи не едут, то ли я по-русски как-то не правильно изъясняюсь...
Имел ввиду статью, на которую указал первой...
Это там все тестировалось и работает.. :)


> Так вот, как ни странно, в других системах, функция LdrLoadDll
> начинается иначе... Например, в XP

Проверял? :-)


 
Игорь Шевченко ©   (2004-03-12 16:45) [34]


> Проверял? :-)


А как же. Я обычно говорю проверенные сведения.


 
Игорь Шевченко ©   (2004-03-12 16:50) [35]


> Имел ввиду статью, на которую указал первой...
> Это там все тестировалось и работает.. :)


Ну вот там-то и нету метода загрузки с перехватом обращения к функции DllMain :)

Кстати, привилегия пишется через "и" :)


 
BiN ©   (2004-03-12 17:32) [36]

Вот только что закончил реализацию данной задачи. Кстати, принцип схож с http://i2r.rusfund.ru/static/565/out_16836.shtml.
Мой метод пока что на универсальность не претендует, но на w2ksp4 (сборка 2195) работает:
С помощью трассировщика определил самую "ближайшую" процедуру вызова Dllmain и переадресовал вызов на свой обработчик. Вот и все.


 
Kerk ©   (2004-03-13 12:09) [37]


> Кстати, привилегия пишется через "и" :)

Точно! :)


 
SPeller ©   (2004-03-14 17:17) [38]

А если скопировать в память содержимое ДЛЛ, запомнить адрес DllMain, куда-нить в конец файла вписать свой код, который, например, будет генерить какое-то событие, говорящее что обработчик запущен, вписать новый адрес DLLMain, загрузить в обычном режиме длл. Затем наша вставка сгенерит событие, по которому мы выполним нужные действия с образом модуля в памяти, затем продолжим выполнение нашей вставки, из которой и будет вызван настоящий DLLMain. Если вызывать DLLMain вообще не надо, то тогда ещё проще - вписываем обработчик из одного ret"а. При этом мы никак не затронем "внутренности" виндов и избавимся от платформо-зависимости. Многие вирусы работают по такому принципу правки адреса EntryPoint на другой, по окоторому расположен код вируса.


 
BiN ©   (2004-03-15 10:42) [39]

SPeller ©   (14.03.04 17:17) [38]
Этот метод на начальной стадии разработки был отвергнут как слишком грубый. К тому же пришлось бы править код во всех подгружаемых библиотеках, так что утверждение о том, что "при этом мы никак не затронем "внутренности" виндов" - не совсем корректно.
На днях я доработал метод [36]. С уверенностью могу утверждать, что на всех версиях W2k он будет работать. Думаю, что и на XP и далее - просто под рукой нет всего набора MSOS.


 
Игорь Шевченко ©   (2004-03-15 10:45) [40]

Kerk ©   (12.03.04 16:41)

К вопросу, почему статья для пакостников: я не поленился, сходил на основной сайт (там ссылочка дана на инструмент, в котором "данные решения успешно используются"), даже что-то оттуда попытался скачать, но неудачно - антивирус не дал, сказал, что файлы в архивах заражены Backdoor.HackDefender virus.

Интересно, правда ?



Страницы: 1 2 вся ветка

Текущий архив: 2004.04.11;
Скачать: CL | DM;

Наверх




Память: 0.58 MB
Время: 0.043 c
14-1081750703
31512
2004-04-12 10:18
2004.04.11
WinXP и Win98 - нет дружбы по сети?


7-1075231094
Ig
2004-01-27 22:18
2004.04.11
Скрытие файлов, папок и др.


1-1079686697
Vlad3
2004-03-19 11:58
2004.04.11
Как, находясь в окне, узнать, что мышь покинула его?


14-1082407603
New Brahman
2004-04-20 00:46
2004.04.11
Ne nu ja vse ponimaju - no predel dolgen bit ?


3-1079429085
Rule
2004-03-16 12:24
2004.04.11
Вопрос по поиску без учета регистра