Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "WinAPI";
Текущий архив: 2004.04.11;
Скачать: [xml.tar.bz2];

Вниз

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

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

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

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


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

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

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


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

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


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

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


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

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

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


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

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

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


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

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

Необходимо осущесвить правку таблицы импорта в библиотеке до выполнения Dllmain. Насколько безопасно на ваш взгляд будет решение Игоря при последующей загрузке 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)


 
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]

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


 
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], по получению управления выполнить правку нужных таблиц, и после этого вернуть управление вызывающему коду

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


 
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]
Да именно так я и делаю. Но ведь чтобы получить доступ к адресному пространству библиотеки, надо ее сначала загрузить, а тут как раз и просиходит вызов точки входа


 
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 в этом случае, по всей видимости. в своем перехватчике придется вызывать явно


 
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)


 
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


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


 
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: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. Просто копирую код второпях


 
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: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 :)


 
Игорь Шевченко ©   (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


 
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


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


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


> BiN


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


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

Digitman ©   (11.03.04 14:46) [16]

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


 
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%

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


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

BiN ©   (11.03.04 14:54)

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

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


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

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

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


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

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

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


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

BiN ©   (11.03.04 15:06)

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


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

BiN ©   (11.03.04 15:06)

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


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

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


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

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


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

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


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

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


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

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


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

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


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

BiN ©   (12.03.04 11:35)

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


 
Игорь Шевченко ©   (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


 
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>


 
Игорь Шевченко ©   (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 и затем перехватим все функции в
загруженном модуле.


 
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.
Текст "для пакостников" не говорит, как это сделать.


 
Игорь Шевченко ©   (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
:-)

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


 
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...


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

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


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


I give you three guesses...


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


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


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

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


 
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


 
Игорь Шевченко ©   (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

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


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


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


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


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

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


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


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


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


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


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


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


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


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


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

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


 
Игорь Шевченко ©   (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 и переадресовал вызов на свой обработчик. Вот и все.


 
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]


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

Точно! :)


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


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

Точно! :)


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

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


 
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.


 
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.

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


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

Kerk ©   (12.03.04 16:41)

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

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


 
Kerk ©   (2004-03-15 14:12) [41]


> Игорь Шевченко ©   (15.03.04 10:45) [40]

А ты запусти и еще раз касперским попробуй проверить... :)
Ничего страшного не случится... гарантирую.

Прога не является трояном сама по себе... она инструмент для скрытия всего что указано конфигурационных файлах...


 
Kerk ©   (2004-03-15 14:12) [41]


> Игорь Шевченко ©   (15.03.04 10:45) [40]

А ты запусти и еще раз касперским попробуй проверить... :)
Ничего страшного не случится... гарантирую.

Прога не является трояном сама по себе... она инструмент для скрытия всего что указано конфигурационных файлах...


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


> Ничего страшного не случится... гарантирую


Я извиняюсь, я антивирусу доверяю больше - он железный :)
И если антивирус ругается на некую программу, то место ей в Recycle Bin, как и прочим поделкам пакостников.


> Прога не является трояном сама по себе...


А эти сказки можно прокурору рассказать - он сжалится :))


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


> Ничего страшного не случится... гарантирую


Я извиняюсь, я антивирусу доверяю больше - он железный :)
И если антивирус ругается на некую программу, то место ей в Recycle Bin, как и прочим поделкам пакостников.


> Прога не является трояном сама по себе...


А эти сказки можно прокурору рассказать - он сжалится :))


 
Kerk ©   (2004-03-15 14:53) [43]


> Я извиняюсь, я антивирусу доверяю больше - он железный :)

Печально.. :( Не стоит слепо верить антивиру...
Кстати, прога с исходниками идет, если мне не доверяешь, можешь сам посмотреть.


> > Прога не является трояном сама по себе...
> А эти сказки можно прокурору рассказать - он сжалится :))

hxdef в принципе не способен нанести какой-либо ущерб!
Сама прога может и "для пакостников", но сами технологии потенциально полезны.


 
Kerk ©   (2004-03-15 14:53) [43]


> Я извиняюсь, я антивирусу доверяю больше - он железный :)

Печально.. :( Не стоит слепо верить антивиру...
Кстати, прога с исходниками идет, если мне не доверяешь, можешь сам посмотреть.


> > Прога не является трояном сама по себе...
> А эти сказки можно прокурору рассказать - он сжалится :))

hxdef в принципе не способен нанести какой-либо ущерб!
Сама прога может и "для пакостников", но сами технологии потенциально полезны.


 
Игорь Шевченко ©   (2004-03-15 17:29) [44]


> hxdef в принципе не способен нанести какой-либо ущерб!


"Program installs hidden
backdoors, register as hidden system service and installs hidden system driver.
The technology of backdoor allowed to do the implantation of redirector."

" Because rootkit hooks all process in the system all TCP ports on all
servers will be backdoors. For example, if the target has port 80/TCP open for
HTTP, then this port will also be available as a backdoor."

Еще комментарии нужны или как ?


 
Игорь Шевченко ©   (2004-03-15 17:29) [44]


> hxdef в принципе не способен нанести какой-либо ущерб!


"Program installs hidden
backdoors, register as hidden system service and installs hidden system driver.
The technology of backdoor allowed to do the implantation of redirector."

" Because rootkit hooks all process in the system all TCP ports on all
servers will be backdoors. For example, if the target has port 80/TCP open for
HTTP, then this port will also be available as a backdoor."

Еще комментарии нужны или как ?


 
VMcL ©   (2004-03-16 00:53) [45]

>>Игорь Шевченко ©  (15.03.04 14:43) [42]
>И если антивирус ругается на некую программу, то место ей в Recycle Bin

ИМХО, слишком категорично. Я когда-то лабы в вузе сдавал: брал задание, делал дома, приносил на занятия в WinRAR"ском SFX-архиве. Так один раз в лаборатории то ли Dr.Web, то ли AVP ругнулся на SFX-модуль - типа там вирус, хотя его там, естественно, не было. Лабу пришлось сдавать в следующий раз.

P.S. Так и не удалось мне убедить препода, что можно установленным у них WinRar"ом распаковать мой архив и проверить его содержимое, и если уже оно (содержимое) не в порядке, тогда вопросов нет.

P.P.S. В архиве были только исходники то ли PAS, то ли CPP.


 
VMcL ©   (2004-03-16 00:53) [45]

>>Игорь Шевченко ©  (15.03.04 14:43) [42]
>И если антивирус ругается на некую программу, то место ей в Recycle Bin

ИМХО, слишком категорично. Я когда-то лабы в вузе сдавал: брал задание, делал дома, приносил на занятия в WinRAR"ском SFX-архиве. Так один раз в лаборатории то ли Dr.Web, то ли AVP ругнулся на SFX-модуль - типа там вирус, хотя его там, естественно, не было. Лабу пришлось сдавать в следующий раз.

P.S. Так и не удалось мне убедить препода, что можно установленным у них WinRar"ом распаковать мой архив и проверить его содержимое, и если уже оно (содержимое) не в порядке, тогда вопросов нет.

P.P.S. В архиве были только исходники то ли PAS, то ли CPP.


 
SPeller ©   (2004-03-16 00:55) [46]


> Этот метод на начальной стадии разработки был отвергнут
> как слишком грубый. К тому же пришлось бы править код во
> всех подгружаемых библиотеках

Зато будет работать на ВСЕХ версиях ОС. Я ведь не говорю править исходный файл, а всего-лишь отображение его в памяти. Неужели независимость от версии ОС (хоть на вынь95 запускайте) не перевешивает "грубости" решения? Лично я не вижу ничего грубого в этом.

ЗЫ: Кстати, дайте мне скачать ваше творение, а то ссылка битая.


 
SPeller ©   (2004-03-16 00:55) [46]


> Этот метод на начальной стадии разработки был отвергнут
> как слишком грубый. К тому же пришлось бы править код во
> всех подгружаемых библиотеках

Зато будет работать на ВСЕХ версиях ОС. Я ведь не говорю править исходный файл, а всего-лишь отображение его в памяти. Неужели независимость от версии ОС (хоть на вынь95 запускайте) не перевешивает "грубости" решения? Лично я не вижу ничего грубого в этом.

ЗЫ: Кстати, дайте мне скачать ваше творение, а то ссылка битая.


 
BiN ©   (2004-03-16 09:45) [47]

SPeller ©   (16.03.04 00:55) [46]
  Я ведь не говорю править исходный файл, а всего-лишь отображение его в памяти

 В том-то и дело, что он отображается в памяти, когда уже полностью загружен и как правило _после_ вызова Dllmain (перечитай subj). Как уже упоминалось, можно написать свой загрузчик - но есть более простые и эффективные методы.
Лично я определяю адрес неэкспортируемой функции, кот. вызывает DllMain и правлю ее (функции) вызов. Синтаксис дан. функции (по крайней мере в W2k) такой (я назвал ее LdrpDllEntryPointCaller, не найдя, к сожалению, ее аналог в замечательной статье Russ Osterlund на http://msdn.microsoft.com/msdnmag/issues/02/03/Loader/default.aspx):

function LdrpDllEntryPointCaller(DllEntryPoint:TDllEntryPoint; hinstDLL:HMODULE; fdwReason:DWORD; lpvReserved:Pointer):BOOL; stdcall;

Кстати, дайте мне скачать ваше творение,

в этой теме я вроде никаких ссылок на свои творения не давал :)


 
BiN ©   (2004-03-16 09:45) [47]

SPeller ©   (16.03.04 00:55) [46]
  Я ведь не говорю править исходный файл, а всего-лишь отображение его в памяти

 В том-то и дело, что он отображается в памяти, когда уже полностью загружен и как правило _после_ вызова Dllmain (перечитай subj). Как уже упоминалось, можно написать свой загрузчик - но есть более простые и эффективные методы.
Лично я определяю адрес неэкспортируемой функции, кот. вызывает DllMain и правлю ее (функции) вызов. Синтаксис дан. функции (по крайней мере в W2k) такой (я назвал ее LdrpDllEntryPointCaller, не найдя, к сожалению, ее аналог в замечательной статье Russ Osterlund на http://msdn.microsoft.com/msdnmag/issues/02/03/Loader/default.aspx):

function LdrpDllEntryPointCaller(DllEntryPoint:TDllEntryPoint; hinstDLL:HMODULE; fdwReason:DWORD; lpvReserved:Pointer):BOOL; stdcall;

Кстати, дайте мне скачать ваше творение,

в этой теме я вроде никаких ссылок на свои творения не давал :)


 
Kerk ©   (2004-03-16 16:57) [48]


> Еще комментарии нужны или как ?

Ты архив распаковывал?
Чувствую к консенсусу не придем. Тебе прога не нравится - ладно, но текст то здесь при чем?!

И не надо меня прокурорами пугать! Я почти-что законопослушный гражданин! :)


 
Kerk ©   (2004-03-16 16:57) [48]


> Еще комментарии нужны или как ?

Ты архив распаковывал?
Чувствую к консенсусу не придем. Тебе прога не нравится - ладно, но текст то здесь при чем?!

И не надо меня прокурорами пугать! Я почти-что законопослушный гражданин! :)


 
Игорь Шевченко ©   (2004-03-16 17:38) [49]

Kerk ©   (16.03.04 16:57)

Распаковывал. Мне программа не нравится по двум причинам - по ее целям и по стилю написания. Антивирус мне exeшники вытер, разбираться в таком коде (про него вообще разговор отдельный) у меня нету ни времени, ни желания. Про цели я вроде цитаты привел...

> Чувствую к консенсусу не придем.

А что там в консенсусе должно образоваться ? :)


 
Игорь Шевченко ©   (2004-03-16 17:38) [49]

Kerk ©   (16.03.04 16:57)

Распаковывал. Мне программа не нравится по двум причинам - по ее целям и по стилю написания. Антивирус мне exeшники вытер, разбираться в таком коде (про него вообще разговор отдельный) у меня нету ни времени, ни желания. Про цели я вроде цитаты привел...

> Чувствую к консенсусу не придем.

А что там в консенсусе должно образоваться ? :)


 
Kerk ©   (2004-03-17 10:21) [50]


> А что там в консенсусе должно образоваться ? :)

Какое-то единое мнение. :)

> Мне программа не нравится по двум причинам ...

см. Kerk ©   (16.03.04 16:57) [48]:
Тебе прога не нравится - ладно, но текст (на который была ссылка) здесь при чем?!

> Антивирус мне exeшники вытер ...

Опять же - ты слишком доверяешь антивирусу. Написать вирь, неопределяющийся касперским можно за полчаса. А в базы антивиров часто добавляют совершенно безвредные проги (key-gen"ы всякие)...


 
Kerk ©   (2004-03-17 10:21) [50]


> А что там в консенсусе должно образоваться ? :)

Какое-то единое мнение. :)

> Мне программа не нравится по двум причинам ...

см. Kerk ©   (16.03.04 16:57) [48]:
Тебе прога не нравится - ладно, но текст (на который была ссылка) здесь при чем?!

> Антивирус мне exeшники вытер ...

Опять же - ты слишком доверяешь антивирусу. Написать вирь, неопределяющийся касперским можно за полчаса. А в базы антивиров часто добавляют совершенно безвредные проги (key-gen"ы всякие)...


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

Kerk ©   (17.03.04 10:21)


> Какое-то единое мнение. :)


Мое мнение - вредная програма :) Консенсус ?


> Опять же - ты слишком доверяешь антивирусу.


Experience :)

Кстати, если есть желание продолжить флейм на эту тему, давай по почте, а то уже злостный offtopic.


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

Kerk ©   (17.03.04 10:21)


> Какое-то единое мнение. :)


Мое мнение - вредная програма :) Консенсус ?


> Опять же - ты слишком доверяешь антивирусу.


Experience :)

Кстати, если есть желание продолжить флейм на эту тему, давай по почте, а то уже злостный offtopic.


 
SPeller ©   (2004-03-18 14:51) [52]


>  В том-то и дело, что он отображается в памяти, когда уже
> полностью загружен и как правило _после_ вызова Dllmain

Да ну?


 
SPeller ©   (2004-03-18 14:51) [52]


>  В том-то и дело, что он отображается в памяти, когда уже
> полностью загружен и как правило _после_ вызова Dllmain

Да ну?


 
Игорь Шевченко ©   (2004-03-18 15:13) [53]

SPeller ©   (18.03.04 14:51)


> Да ну?


Ну да. MSDN RE второй сигнальный номер: внутри загрузчика Windows NT


 
Игорь Шевченко ©   (2004-03-18 15:13) [53]

SPeller ©   (18.03.04 14:51)


> Да ну?


Ну да. MSDN RE второй сигнальный номер: внутри загрузчика Windows NT


 
BiN ©   (2004-03-18 15:31) [54]

>> SPeller ©

конечно же, сам образ библиотеки отображается в памяти до вызова DllMain - это очевидно хотя бы потому, что в качестве одного из параметров передается адрес (или хэндл) загруженного модуля.

Метод, предложеный тобой в [46] работать не будет по той причине, что ты собираешься править код в уже загруженной библиотеке и после вызова точки входа.


 
BiN ©   (2004-03-18 15:31) [54]

>> SPeller ©

конечно же, сам образ библиотеки отображается в памяти до вызова DllMain - это очевидно хотя бы потому, что в качестве одного из параметров передается адрес (или хэндл) загруженного модуля.

Метод, предложеный тобой в [46] работать не будет по той причине, что ты собираешься править код в уже загруженной библиотеке и после вызова точки входа.


 
BiN ©   (2004-03-18 15:32) [55]

Удалено модератором
Примечание: Дубль


 
BiN ©   (2004-03-18 15:32) [55]

Удалено модератором
Примечание: Дубль


 
Aleksey Pavlov ©   (2004-03-18 15:59) [56]

>> BiN:
можно полученный в результате код посмотреть?
164142@_NO_SPAM_PLZ_mail.ru


 
Aleksey Pavlov ©   (2004-03-18 15:59) [56]

>> BiN:
можно полученный в результате код посмотреть?
164142@_NO_SPAM_PLZ_mail.ru


 
BiN ©   (2004-03-18 17:21) [57]

Готовый проект я позже выложу где-нибудь в инете, а принцип объяснить могу и сейчас - к тому же он оказался прост до безобразия :). Как уже упоминалось, все сводится к изменению адреса в инструкции вызова в одной из вложеных в LdrLoadDll функций.
Сама LdrLoadDll выглядит примерноо так в переводе на дельфи :)

function LdrLoadDll(PathToFile:Pchar;  
                   Flags:ULONG;
                   ModuleFileName:PNICODE_STRING;
                   var ModuleHandle:DWORD); stdcall;
begin
 MapDataAndCreateIAT;  <<Более подробно можно посмотреть по
                        ссылке, указанной в [47]
 ...
 
 call offset // где offset - это смещение на функцию
                LdrpDllEntryPointCaller см [47]
 
end;

Этот последний вызов и требуется найти и изменить. Здесь и возникают проблемы с несовместимостью OS и как следствие, со  сдвигами адресов и т.д. Свен Шнайбер борется с этим с помощью отладочных файлов, кто-то еще находу анализирует код LdrLoadDll и патчит его начало.
Но ведь можно сократить наш поиск, элементарно осуществив его с конца, из недр своей подгружаемой библиотеки. Другими словами, функция определяющая адрес находится не в теле программы, а в библиотеке, что может создавать некоторые неудобства, но не тем кто, кто хочет осуществлять перехват в адресном пространстве другого процесса. На данный момент требуемый адрес находится по ссылкам оставляемым в стеке "шапками" процедур вида

push  ebp
mov   ebp, esp

Так как нужно определить всего лишь вторую ссылку, то и вероятность ошибки довольно мала. Точнее, этот метод будет работать железно при условии(!), что вызывающая Dllmain функция начинается с вышеуказанной шапки. Вуаля.


 
BiN ©   (2004-03-18 17:21) [57]

Готовый проект я позже выложу где-нибудь в инете, а принцип объяснить могу и сейчас - к тому же он оказался прост до безобразия :). Как уже упоминалось, все сводится к изменению адреса в инструкции вызова в одной из вложеных в LdrLoadDll функций.
Сама LdrLoadDll выглядит примерноо так в переводе на дельфи :)

function LdrLoadDll(PathToFile:Pchar;  
                   Flags:ULONG;
                   ModuleFileName:PNICODE_STRING;
                   var ModuleHandle:DWORD); stdcall;
begin
 MapDataAndCreateIAT;  <<Более подробно можно посмотреть по
                        ссылке, указанной в [47]
 ...
 
 call offset // где offset - это смещение на функцию
                LdrpDllEntryPointCaller см [47]
 
end;

Этот последний вызов и требуется найти и изменить. Здесь и возникают проблемы с несовместимостью OS и как следствие, со  сдвигами адресов и т.д. Свен Шнайбер борется с этим с помощью отладочных файлов, кто-то еще находу анализирует код LdrLoadDll и патчит его начало.
Но ведь можно сократить наш поиск, элементарно осуществив его с конца, из недр своей подгружаемой библиотеки. Другими словами, функция определяющая адрес находится не в теле программы, а в библиотеке, что может создавать некоторые неудобства, но не тем кто, кто хочет осуществлять перехват в адресном пространстве другого процесса. На данный момент требуемый адрес находится по ссылкам оставляемым в стеке "шапками" процедур вида

push  ebp
mov   ebp, esp

Так как нужно определить всего лишь вторую ссылку, то и вероятность ошибки довольно мала. Точнее, этот метод будет работать железно при условии(!), что вызывающая Dllmain функция начинается с вышеуказанной шапки. Вуаля.


 
Игорь Шевченко ©   (2004-03-18 17:43) [58]


> Так как нужно определить всего лишь вторую ссылку, то и
> вероятность ошибки довольно мала. Точнее, этот метод будет
> работать железно при условии(!), что вызывающая Dllmain
> функция начинается с вышеуказанной шапки.


Это все будет работать до Windows XP (и, соответственно, всех более поздних версий). Свен Шрайбер не зря ведь рекомендует пользоваться символьной информацией.


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


Идея интересная. Но LdrpLoadDll не начинается с той шапки в указанных мной версиях Windows.


 
Игорь Шевченко ©   (2004-03-18 17:43) [58]


> Так как нужно определить всего лишь вторую ссылку, то и
> вероятность ошибки довольно мала. Точнее, этот метод будет
> работать железно при условии(!), что вызывающая Dllmain
> функция начинается с вышеуказанной шапки.


Это все будет работать до Windows XP (и, соответственно, всех более поздних версий). Свен Шрайбер не зря ведь рекомендует пользоваться символьной информацией.


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


Идея интересная. Но LdrpLoadDll не начинается с той шапки в указанных мной версиях Windows.


 
BiN ©   (2004-03-18 17:53) [59]

... LdrpLoadDll не начинается с той шапки

в том-то и дело, что в моем методе нет зависимости от LdrpLoadDll, т.к. она вызывается где-то "посередине" иерархии вложенных функций . Что ж, из принципа придется сегодня ставить XP :)


 
BiN ©   (2004-03-18 17:53) [59]

... LdrpLoadDll не начинается с той шапки

в том-то и дело, что в моем методе нет зависимости от LdrpLoadDll, т.к. она вызывается где-то "посередине" иерархии вложенных функций . Что ж, из принципа придется сегодня ставить XP :)


 
BiN ©   (2004-03-18 20:20) [60]

Проведенное тестирование на MS Windows XP Professional SP1, позволяет с уверенностью утверждать, что предложенный мной метод увпешно работает и на этой ОС.


 
BiN ©   (2004-03-18 20:20) [60]

Проведенное тестирование на MS Windows XP Professional SP1, позволяет с уверенностью утверждать, что предложенный мной метод увпешно работает и на этой ОС.


 
Игорь Шевченко ©   (2004-03-19 10:18) [61]

Код на whitefranz@hotmail.com не затруднит отправить ?


 
Игорь Шевченко ©   (2004-03-19 10:18) [61]

Код на whitefranz@hotmail.com не затруднит отправить ?


 
SPeller ©   (2004-03-21 17:01) [62]

Товарищи, если я что-то не догоняю, то извините пожалуйста. Если можно, то расскажите мне, бестолковому, что мешает загрузить библиотеку через CreateFileMapping, сделать все нужные поправки, о которых я говорил ранее, и после этого вызвать DllMain ?


 
SPeller ©   (2004-03-21 17:01) [62]

Товарищи, если я что-то не догоняю, то извините пожалуйста. Если можно, то расскажите мне, бестолковому, что мешает загрузить библиотеку через CreateFileMapping, сделать все нужные поправки, о которых я говорил ранее, и после этого вызвать DllMain ?


 
Игорь Шевченко ©   (2004-03-21 22:39) [63]

SPeller ©   (21.03.04 17:01)

Это называется - написать свой загрузчик. Я там ссылочку на MSDN RE давал, почитай, чем занимается загрузчик.


 
Игорь Шевченко ©   (2004-03-21 22:39) [63]

SPeller ©   (21.03.04 17:01)

Это называется - написать свой загрузчик. Я там ссылочку на MSDN RE давал, почитай, чем занимается загрузчик.


 
Alexander666 ©   (2004-03-21 22:50) [64]

А на адрес alexj_8@hotmail.com тоже можно отправить?


 
Alexander666 ©   (2004-03-21 22:50) [64]

А на адрес alexj_8@hotmail.com тоже можно отправить?


 
BiN ©   (2004-03-22 09:39) [65]

SPeller ©   (21.03.04 17:01) [62]

Здесь можно посоветовать почитать статью, где описываются минимальные действия по созданию загрузчика на дельфи, но даже там в результате получается несколько ущербный вариант.
http://rsdn.ru/article/baseserv/peloader.xml


 
BiN ©   (2004-03-22 09:39) [65]

SPeller ©   (21.03.04 17:01) [62]

Здесь можно посоветовать почитать статью, где описываются минимальные действия по созданию загрузчика на дельфи, но даже там в результате получается несколько ущербный вариант.
http://rsdn.ru/article/baseserv/peloader.xml


 
Игорь Шевченко ©   (2004-03-22 10:28) [66]

BiN ©   (22.03.04 09:39)

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


 
Игорь Шевченко ©   (2004-03-22 10:28) [66]

BiN ©   (22.03.04 09:39)

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


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

Игорь Шевченко ©   (22.03.04 10:28) [66]
... как можно убедиться в перехваченной точке, что DLL загружена и ее разделы импорта настроены нужным образом


Обязательно настроены, ведь без этого работа самой Dllmain была бы некорректна.

Насколько я понял, ты перехватываешь вызов той программы, которая вызывает внутри себя DllMain.

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

В данном же случае требуется перехватить любые попытки вызова функции A, как в a) теле программы так и в b) теле DllMain при динамической загрузке. Это решается просто, если исследуемый процесс создавать самим, т.е. использовать отработанную схему:
CREATE_SUSPENDED
внедрение нашей длл, в кот. происходит:
   правка IAT
   правка адреса в ntdll, кот-ю, кстати, возможно придется делать  в  новом потоке, а не изнутри процедуры точки входа нашей внедренной длл - я, к сожалению, пока не тестировал все варианты.
ResumeThread

Или, может, я не до конца понял вопрос?


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

Игорь Шевченко ©   (22.03.04 10:28) [66]
... как можно убедиться в перехваченной точке, что DLL загружена и ее разделы импорта настроены нужным образом


Обязательно настроены, ведь без этого работа самой Dllmain была бы некорректна.

Насколько я понял, ты перехватываешь вызов той программы, которая вызывает внутри себя DllMain.

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

В данном же случае требуется перехватить любые попытки вызова функции A, как в a) теле программы так и в b) теле DllMain при динамической загрузке. Это решается просто, если исследуемый процесс создавать самим, т.е. использовать отработанную схему:
CREATE_SUSPENDED
внедрение нашей длл, в кот. происходит:
   правка IAT
   правка адреса в ntdll, кот-ю, кстати, возможно придется делать  в  новом потоке, а не изнутри процедуры точки входа нашей внедренной длл - я, к сожалению, пока не тестировал все варианты.
ResumeThread

Или, может, я не до конца понял вопрос?


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

BiN ©   (22.03.04 11:13)


> Обязательно настроены, ведь без этого работа самой Dllmain
> была бы некорректна.


Э....ты же перехватываешь не то место, где вызывается DLLMain, а перехватываешь вызов той процедуры, которая вызывает DllMain внутри себя, если я правильно в коде разобрался. Или прокомментируй каждую команду в процедуре, начинающуюся с
{$O-} {<-- на всякий случай}

Я хочу сказать, а не вызывается ли настройка импорта (или еще чего-нибудь важного) в промежутке между адресом, который ты перехватил, и точкой вызова DllMain ?


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

BiN ©   (22.03.04 11:13)


> Обязательно настроены, ведь без этого работа самой Dllmain
> была бы некорректна.


Э....ты же перехватываешь не то место, где вызывается DLLMain, а перехватываешь вызов той процедуры, которая вызывает DllMain внутри себя, если я правильно в коде разобрался. Или прокомментируй каждую команду в процедуре, начинающуюся с
{$O-} {<-- на всякий случай}

Я хочу сказать, а не вызывается ли настройка импорта (или еще чего-нибудь важного) в промежутке между адресом, который ты перехватил, и точкой вызова DllMain ?


 
BiN ©   (2004-03-22 12:16) [69]


...ты же перехватываешь не то место, где вызывается DLLMain, а перехватываешь вызов той процедуры, которая вызывает DllMain внутри себя


Совершенно верно

... а не вызывается ли настройка импорта (или еще чего-нибудь важного) в промежутке между адресом, который ты перехватил, и точкой вызова DllMain ?

эта процедура в ntdll w2ksp4 в переводе на паскаль выглядит примерно так (ассемблерный код можно посмотреть самому):

function LdrpDllEntryPointCaller(DllEntryPoint:TDllEntryPoint; hinstDLL:HMODULE; fdwReason:DWORD; lpvReserved:Pointer):BOOL; stdcall;
begin
 Result:=DllEntryPoint(hinstDll, fdwReason, lpvReserved);
end;

Причем, никаких иных действий эта функция не производит. Она же получает управление и для вызова Dllmain при выгрузке библиотеки. Следовательно, логично предположить, что в ней не будет происходить какие-либо изменения IAT - зачем при выгрузке библиотеки настраивать таблицу импорта.
Следует отметить, что описанный в предыдущих постах пример не затрагивает перехват Dllmain при вызове FreeLibrary и т.п., в этом просто нет необходимости.


 
BiN ©   (2004-03-22 12:16) [69]


...ты же перехватываешь не то место, где вызывается DLLMain, а перехватываешь вызов той процедуры, которая вызывает DllMain внутри себя


Совершенно верно

... а не вызывается ли настройка импорта (или еще чего-нибудь важного) в промежутке между адресом, который ты перехватил, и точкой вызова DllMain ?

эта процедура в ntdll w2ksp4 в переводе на паскаль выглядит примерно так (ассемблерный код можно посмотреть самому):

function LdrpDllEntryPointCaller(DllEntryPoint:TDllEntryPoint; hinstDLL:HMODULE; fdwReason:DWORD; lpvReserved:Pointer):BOOL; stdcall;
begin
 Result:=DllEntryPoint(hinstDll, fdwReason, lpvReserved);
end;

Причем, никаких иных действий эта функция не производит. Она же получает управление и для вызова Dllmain при выгрузке библиотеки. Следовательно, логично предположить, что в ней не будет происходить какие-либо изменения IAT - зачем при выгрузке библиотеки настраивать таблицу импорта.
Следует отметить, что описанный в предыдущих постах пример не затрагивает перехват Dllmain при вызове FreeLibrary и т.п., в этом просто нет необходимости.


 
Игорь Шевченко ©   (2004-03-22 13:26) [70]

Да, нашел. Называется LdrpCallInitRoutine. В этом случае действительно DLL готова к выполнению функции инициализации.


 
Игорь Шевченко ©   (2004-03-22 13:26) [70]

Да, нашел. Называется LdrpCallInitRoutine. В этом случае действительно DLL готова к выполнению функции инициализации.


 
pasha_golub ©   (2004-03-22 13:46) [71]

Напишите, пожалуйста, статью по этому поводу и код исходный на pavel.golub@farata.kr.ua киньте, пожалуйста.


 
pasha_golub ©   (2004-03-22 13:46) [71]

Напишите, пожалуйста, статью по этому поводу и код исходный на pavel.golub@farata.kr.ua киньте, пожалуйста.



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

Форум: "WinAPI";
Текущий архив: 2004.04.11;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.9 MB
Время: 0.044 c
3-1081431044
GIL
2004-04-08 17:30
2004.05.09
добавление записи с блобовыми полями через SQL


7-1080563938
Alex-drob
2004-03-29 16:38
2004.05.09
Закрыть другую программу


3-1081741809
Геннадий
2004-04-12 07:50
2004.05.09
Как выделить составляющую из даты?


1-1082382811
A. Sonin
2004-04-19 17:53
2004.05.09
Собственное создание формы без использования кода в проекте


1-1082928160
Denis_Visma
2004-04-26 01:22
2004.05.09
Начало отсчета с 1 в Chart





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский