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

Вниз

Хендл KERNEL32   Найти похожие ветки 

 
-SeM-   (2004-11-23 12:17) [0]

Как узнать хендл (адрес загрузки) kernel32.dll без использования API?
Можно ли со 100% уверенностью ожидать ее загрузки по $BFF60000? Или могут быть иные случаи?


 
Digitman ©   (2004-11-23 12:27) [1]


> Как узнать хендл (адрес загрузки) kernel32.dll без использования
> API?


опираясь на факт фиксированного (платформозависимого) адреса размещения PEB-структуры в АП процессов просканировать в цикле список модулей данного процесса


> Можно ли со 100% уверенностью ожидать ее загрузки по $BFF60000?


нельзя.
адрес этот зависит и от конкретной ОС-платформы и от версии kernel32

что задумал-то ? поясни ...
может, не ту траву куришь ..


 
-SeM-   (2004-11-23 12:49) [2]

Digitman ©   (23.11.04 12:27) [1]

> может, не ту траву куришь ..

Да другой просто нет :)

Прога без использования импорта может использовать API. Т.е. предложеный тобой вариант - наверное не подходит, т.к. нет подгруженых модулей. Как быть?


 
-SeM-   (2004-11-23 13:01) [3]

Digitman ©   (23.11.04 12:27)

Всегда ли кернел имеет самый большой адрес загрузки? Если да, с какого адреса производить поиск (вниз кратно $00010000) сигнатуры РЕ?


 
Digitman ©   (2004-11-23 13:36) [4]


> -SeM-


вот "скелет" решения задачи :


TModuleInfo = packed record
  DllBase          : Pointer;
  EntryPoint       : Pointer;
  SizeOfImage      : Cardinal;
  FullDllName      : TUNICODE_STRING;
  BaseDllName      : TUNICODE_STRING;
  Flags            : Cardinal;
  LoadCount        : Word;
  TlsIndex         : Word;
  HashLinks        : TLIST_ENTRY;
  SectionPointer   : Pointer;
  CheckSum         : Cardinal;
  TimeDateStamp    : Cardinal;
  LoadedImports    : Pointer;
  EntryPointActivationContext : Pointer;
end;
PModuleInfo = ^TModuleInfo;

function FindModuleInfo(hModule: THandle): PModuleInfo;
var
 Peb: PPeb;
 pLdrData : PPEB_LDR_DATA;
 pLoadOrderList : PPLIST_ENTRY;
 pInLoadModuleEntry: PModuleEntry;
begin
 Result := nil;
 if hModule = 0 then Exit;
 Peb := GetCurrentPeb;
 LockLoader(Peb);
 try
   pLdrData := Peb^.LdrData;
   pLoadOrderList := @pLdrData.InLoadOrderModuleList;
   pInLoadModuleEntry := PModuleEntry(pLoadOrderList^);
   while PPListEntry(pInLoadModuleEntry) <> pLoadOrderList do
     begin
       Result := @pInLoadModuleEntry.ModuleInfoData;
       if Result^.DllBase = Pointer(hModule) then
         Exit;
       pInLoadModuleEntry := PModuleEntry(pInLoadModuleEntry.InLoadOrderLinks.Flink);
     end;
   Result := nil;
 finally
   UnLockLoader(Peb);
 end;
end;

function GetModuleInfo(lpModule: PChar; out ModuleInfo: TModuleInfo): Boolean;
var
 peb: PPeb;
 hModule: THandle;
 pLdrData : PPEB_LDR_DATA;
 pLoadOrderList : PPLIST_ENTRY;
 pInLoadModuleEntry: PModuleEntry;
 pModuleNfo: PModuleInfo;
begin
 Result := False;
 if not Assigned(lpModule) then Exit;
 peb := GetCurrentPeb;
 LockLoader(Peb);
 try
   hModule := FindHInstance(lpModule);
   if hModule = 0 then Exit;
   if hModule <> THandle(lpModule) then
     hModule := GetModuleHandle(lpModule);
   if hModule = 0 then Exit;
   pLdrData := peb^.LdrData;
   pLoadOrderList := @pLdrData.InLoadOrderModuleList;
   pInLoadModuleEntry := PModuleEntry(pLoadOrderList^);
   while PPListEntry(pInLoadModuleEntry) <> pLoadOrderList do
     begin
       pModuleNfo := @pInLoadModuleEntry.ModuleInfoData;
       if pModuleNfo^.DllBase = Pointer(hModule) then
         begin
           if Assigned(@ModuleInfo) then
             ModuleInfo := pModuleNfo^;
           Result := True;
           Break;
         end;
       pInLoadModuleEntry := PModuleEntry(pInLoadModuleEntry.InLoadOrderLinks.Flink);
     end;
 finally
   UnLockLoader(Peb);
 end;
end;


как видишь, никаких API-вызовов нет и в помине, однако база требуемого модуля, если он присутствует в тек.АП, замечательно определяется

не приведенные здесь описания используемых структур можно поиметь, например, в книге Свена Шрайбера "Недок. возможности Винтукея"

приведенный "скелет" касаем  только НТ-линейки


 
clickmaker ©   (2004-11-23 13:38) [5]


>  [3] -SeM-   (23.11.04 13:01)
> Digitman ©   (23.11.04 12:27)
>
> Всегда ли кернел имеет самый большой адрес загрузки?

нет


 
-SeM-   (2004-11-23 13:53) [6]

Digitman ©   (23.11.04 13:36) [4]

> как видишь, никаких API-вызовов нет и в помине


>    if hModule <> THandle(lpModule) then
>      hModule := GetModuleHandle(lpModule);


А GetModuleHandle что-то свое или из кернел?


 
Digitman ©   (2004-11-23 14:35) [7]

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


 
-SeM-   (2004-11-23 15:13) [8]

Digitman ©   (23.11.04 14:35) [7]

Ок. Спасибо. Буду пробовать.
А для 9х какие-нибудь решения есть?

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


 
Игорь Шевченко ©   (2004-11-23 16:56) [9]


> При старте ехе указатель стека содержит адрес из кернел
> (оставляет наверное загрузчик). Всегда ли это так


Под Win9x скорее всего, всегда. Под NT адресв стеке, скорее всего будет в NTDLL.DLL. Это не загрузчик, а функция CreateThread.


 
-SeM-   (2004-11-23 17:07) [10]

Игорь Шевченко ©   (23.11.04 16:56)

Игорь, извините, но что Вы можете сказать по сабжу. Может есть другие варианты определения хендла кернела для 9х/NT?


 
Digitman ©   (2004-11-23 17:15) [11]


> -SeM-   (23.11.04 17:07) [10]


в Win9x тоже есть PEB .. ищи инфу ...

а по поводу использования для этой цели PEB на НТ-платформе тебе уже сказано в [4]


 
-SeM-   (2004-11-23 17:21) [12]

Digitman ©   (23.11.04 17:15) [11]

Да я не отказываюсь :) Спасибо. Просто а вдруг еще есть варианты


 
-SeM-   (2004-11-23 17:22) [13]

Digitman ©   (23.11.04 17:15) [11]

Да я не отказываюсь :) Спасибо. Просто а вдруг еще есть варианты


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

-SeM-   (23.11.04 17:07) [10]

За 9x не скажу ничего. За NT могу сказать - NTDLL.DLL экспортирует функцию LdrGetDllHandle, которая выполняется те же самые действия, что и GetModuleHandle. Под NT в адресное пространство любого приложения загружена NTDLL.DLL


 
-SeM-   (2004-11-23 17:33) [15]

Игорь Шевченко ©   (23.11.04 17:24) [14]

Хм... Хендл которой все равно нужно как-то узнать. Ведь адрес ее загрузки, наверное, тоже не фиксирован...

Ладно, спасибо всем. Буду продолжать с [4]


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

-SeM-   (23.11.04 17:33) [15]

Адрес загрузки NTDLL.DLL можно узнать, проанализировав заголовок PE-файла на диске. Эта библиотека всегда грузится по одному и тому же адресу.
Но я не понимаю, какой смысл - под NT NTDLL.DLL у тебя всегда есть, Kernel32.dll у тебя всегда есть.


 
-SeM-   (2004-11-23 17:53) [17]

Игорь Шевченко ©   (23.11.04 17:43) [16]

Но как сказали мне выше адрес загрузки кернел

> зависит и от конкретной ОС-платформы и от версии kernel32

а хотелось попроще (к примеру [8])


 
n0name   (2004-11-23 19:28) [18]

http://delphimaster.net/view/4-1100098886/


 
Digitman ©   (2004-11-24 08:26) [19]


> -SeM-   (23.11.04 17:53) [17]


kernel32 ведь как правило всегда загружается одним из первых модулей, поэтому и адрес его загрузки как правило равен предпочтительному адресу, фигурирующему в PE-заголовке


 
Leonid Troyanovsky   (2004-11-24 10:58) [20]


> -SeM-   (23.11.04 17:33) [15]

> Хм... Хендл которой все равно нужно как-то узнать. Ведь
> адрес ее загрузки, наверное, тоже не фиксирован...



http://groups.google.com/groups?selm=emFadfYyDHA.2720%40TK2MSFTNGP09.phx.gbl

Как, собс-но, и kernel32.dll, о чем некогда рассказывал Slava Usov.

Так что, можешь смело пользовать GetModuleHandle,
во всяком случае, в Win32.

--
С уважением, LVT.


 
-SeM-   (2004-11-24 16:52) [21]

Leonid Troyanovsky   (24.11.04 10:58) [20]


> Так что, можешь смело пользовать GetModuleHandle

Да не могу. Он же сидит в кернел, адрес которого и хочу определить. Нет у меня ни одного импорта (и ExitProcess тоже).


 
Leonid Troyanovsky   (2004-11-24 21:50) [22]


> -SeM-   (24.11.04 16:52) [21]
> > Так что, можешь смело пользовать GetModuleHandle
>
> Да не могу. Он же сидит в кернел, адрес которого и хочу
> определить. Нет у меня ни одного импорта (и ExitProcess
> тоже).


Чего-чего нет?
А чего мы тут распинались? :)

--
С уважением, LVT.

PS Т.е., пробывать слабо.


 
-SeM-   (2004-11-25 09:57) [23]

Leonid Troyanovsky   (24.11.04 21:50) [22]

А что тут смешного? Действительно приложение имеет девственно чистую таблицу импорта. Все адреса необходимых внешних функций определяются динамически аналогом GetProcAddress (и ExitProcess тоже). Одно только пока не реализовано - определение адреса загрузки kernel32.dll - зашито жестко. На возможное замечание о линковщике скажу сразу - используется замена модулей system и sysinit и компилируется в среде Delphi обычным образом.


 
Leonid Troyanovsky   (2004-11-25 10:13) [24]


> -SeM-   (25.11.04 09:57) [23]

> А что тут смешного? Действительно приложение имеет девственно
> чистую таблицу импорта. Все адреса необходимых внешних функций
> определяются динамически аналогом GetProcAddress (и ExitProcess
> тоже). Одно только пока не реализовано - определение адреса
> загрузки kernel32.dll - зашито жестко. На возможное замечание
> о линковщике скажу сразу - используется замена модулей system
> и sysinit и компилируется в среде Delphi обычным образом.


Ну, я ж не предполагал, что дело зашло так далеко :)
Могу лишь предложить устанавливать оный адрес, скажем
при установке приложения. Т.е., установщик определит
нужный адрес и пропатчит екзешник (достаточно 4 байт).

--
С уважением, LVT.


 
Digitman ©   (2004-11-25 10:29) [25]


> приложение имеет девственно чистую таблицу импорта


ты хоть пояснил бы, зачем ты так извращаешься, пытаясь создать "девственно чистое" приложение ..

я могу еще понять, если твоя цель - внедрение кода в чужой процесс и старт этого кода в виде удаленного трэда, при том что этот тред разворачивает свою бурную "черную деятельность" т.с. с нуля, безо всяких IAT, т.е. имея адрес kernel32 получает точку входа в GetProcAddress() и с этого момента получает независимый от IAT доступ ко всем нужным ему модулям, как уже загруженным, так и требуемым к загрузке по ходу дела ..


 
-SeM-   (2004-11-25 10:51) [26]

Leonid Troyanovsky   (25.11.04 10:13) [24]
Да нет, спасибо. Мне так не нравится.

Digitman ©   (25.11.04 10:29) [25]
Ну почему же сразу бурную "черную деятельность", можно просто деятельность.
А зачем? Не знаю... Наверное спортивный интерес. Уже не раз подымался вопрос - можно ли написать драйвер в Delphi. Обычно говорят - не получится, т.к. модуль в любом случае будет иметь импорт из-за линковщика, что не допустимо для драйверов. Мне вообще-то драйвера не надо, а вот стало интересно - а смогу ли я отказаться от стат. импорта. А зачем? Не знаю, сделаю - потом буду думать зачем оно мне :)

С уважением


 
n0name   (2004-11-25 11:37) [27]

-SeM-   (25.11.04 10:51) [26]
xe xe. Я сделал чистую имп. таблицу. Исходники показывал ищи xGetProcAddress. Но можно и проще kernel32.dll всегда 2ая в списке модулей.


 
Digitman ©   (2004-11-25 11:48) [28]


> Уже не раз подымался вопрос - можно ли написать драйвер
> в Delphi. Обычно говорят - не получится


да, от начала и до конца не получится

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

но вовсе не потому делфевый линкер включает в модуль драйвера IAT : ничто не мешает драйверу иметь стат.импорт (загляни любой утилиткой просмотра зависимостей в любой полноценный NT KMD и увидишь там ссылку хотя бы на ntoskrnl)

другой вопрос, что КMD не вправе импортировать и использовать сист.модули режима пользователя, хотя бы тот же kernel32.dll, ссылку на который линкер по дифолту включает в IAT из-за того что ссылки на него имеются в SysInit.

поэтому опять же непонятна связь твоего "спортивного" интереса к KMD и вопроса про определение адреса kernel32 как модуля искл-но польз.режима


 
-SeM-   (2004-11-25 12:14) [29]

n0name   (25.11.04 11:37) [27]
Да есть у меня GetProcAddress (не xGetProcAddress). Или же в хGetProcAddress реализован поиск адреса загрузки кернел?

> kernel32.dll всегда 2ая в списке модулей

Модулей чего?

Digitman ©   (25.11.04 11:48) [28]
Повторюсь еще раз. Не надо мне драйверов режима ядра. Нет ни желания, ни обходимости. Была когда-то ветка, в которой обсуждалось и создание драйвера в Delphi, и то что ее линкер в любом случае добавляет импорт. Вот и стал разбираться, пробовать а можно ли без этого. Можно. Но для того чтобы закрыть приложение без "выкрутасов с RET" (Digitman ©   (24.11.04 10:37) [82] в соседней ветке) нужно использовать "как минимум одну ф-цию - ExitProcess(), поскольку в соответствии с док-цией Майкрософт вызов этой ф-ции есть предпочтительный способ нормального завершения процесса", для чего как минимум нужно знать хендл kernel32 и аналог GetProcAddress. Со вторым проблем нет.
Надеюсь что я объяснил свой интерес к "определению адреса kernel32 как модуля искл-но польз.режима"


 
Digitman ©   (2004-11-25 12:39) [30]


> -SeM-   (25.11.04 12:14) [29]


ну согласен .. может я и неверно истолковал твой комментарий по поводу КМД ..

но в общем и целом ответ на вопрос свой ты уже получил : полагаясь на факт неизменности адреса загрузки этого модуля, в "своем" процессе получить адрес т.входа в kernel32.GetProcAddress (hKernel32) и просто передать этот адрес параметром в стартуемый тобой удаленный трэд - он и там, в "чужом" АП, будет столь же актуален и корректен, как и в "своем" АП .. а далее логика удаленного трэда проста : получаешь адрес т.входа в hKernel32.LoadLibrary() и далее ты волен грузить любой нужный тебе модуль (если он уже загружен, ты, инкрементировав ссылку на него,  просто получишь его хэндл) и, получив этот хэндл, далее получать т.входа экспортируемые этим модулем ф-ции, чтобы их беспроблемно вызывать по необх-ти

вот такая схема какие-то сомнения вызывает у тебя ?


 
-SeM-   (2004-11-25 13:13) [31]

Digitman ©   (25.11.04 12:39) [30]
Мне кажется ты связываешь мой вопрос с "самодостаточным кодом" :)
Об этом я пока не задумывался. А по-поводу приведенной схемы смущает только это

> [1] адрес этот зависит и от конкретной ОС-платформы и от версии kernel32


> [30] полагаясь на факт неизменности адреса загрузки этого модуля

Ведь речь идет об одном и том же модуле?

ЗЫ Вариант [4], честно говоря, еще не пробовал - нет времени.


 
Digitman ©   (2004-11-25 13:22) [32]


> по-поводу приведенной схемы смущает только это
>
> > [1] адрес этот зависит и от конкретной ОС-платформы и
> от версии kernel32


не понимаю почему тебя это смущает..

каким бы ни был этот адрес, он будет одним и тем же и в своем и в чужом процессе


> речь идет об одном и том же модуле?


ну да, о kernel32.dll, о каком же еще ?


 
-SeM-   (2004-11-25 13:47) [33]

Digitman ©   (25.11.04 13:22) [32]

> одним и тем же и в своем и в чужом процессе

Нет, не уводи меня в сторону. Это я даже не могу поставить под сомнение.
Нет у меня чужого процесса. Только свой. И только для него нужен этот адрес, вне зависимости в какой ОС он работает.

Чтобы зря не толочь воду, давай я для начала попробую [4]. А будут вопросы (думаю будут :)) - вот тогда и спрошу.


 
n0name   (2004-11-25 13:57) [34]

-SeM-   (25.11.04 12:14) [29]
Рядом с xGetProcessAddress лежит мой же xGetModuleHandle.(Отвечаю и на первый и на второй вопросы).

http://delphimaster.net/view/4-1100098886/


 
n0name   (2004-11-25 14:03) [35]

-SeM-   (25.11.04 12:14) [29]
Рядом с xGetProcessAddress лежит мой же xGetModuleHandle.(Отвечаю и на первый и на второй вопросы).

http://delphimaster.net/view/4-1100098886/


 
Digitman ©   (2004-11-25 14:17) [36]


> Нет у меня чужого процесса. Только свой. И только для него
> нужен этот адрес, вне зависимости в какой ОС он работает.


так ведь блажь ! ну блажь же ! самая настоящая !

на кой вообще ляд тогда ОС-платформа с ее АПИ нужна ? если даже в своем процессе ты отказываешься от того, что тебе дает АПИ платформы ? нахаляву ? бери и пользуй, так сказать ? быстро и беспроблемно ? не выпендриваясь и не изобретая велосипедов ?


 
-SeM-   (2004-11-25 15:49) [37]

n0name   (25.11.04 14:03) [34]
Да, признаю, не досмотрел...
Как ты думаешь, по каким двум причинам мне не нравится следующее

function LdrLockLoaderLock(Flags: DWORD; result, Magic: PDWORD): NTSTATUS; stdcall; external "ntdll.dll";
function LdrUnlockLoaderLock(Flags, Magic: DWORD): NTSTATUS; stdcall; external "ntdll.dll";


Digitman ©   (25.11.04 14:17) [36]
Сергей, тезка, да не переживай ты так :)
Я же не говорю, что не буду использовать API, тем более куда я без нее :)
Я говорю "спортивный интерес", пусть даже с твоей точки зрения нездоровый.


 
Digitman ©   (2004-11-25 16:31) [38]


> -SeM-   (25.11.04 15:49) [37]


ладныть, тезка .. уговорил ... более не "переживаю" ... как тебе будет угодно.

жаль вот только, что силушку молодецкую-программистскую почем зря прожигаешь)


 
n0name   (2004-11-25 17:29) [39]

-SeM-   (25.11.04 15:49) [37]
Можешь убрать это(для кернела не надо).
Можешь сам дописать функцию чтобы она находила ntdll.dll(она первая в списке в PEB(смотри исходник)) и xGetProcAddress для 2х причин.


 
Kerk ©   (2004-11-25 17:32) [40]

Промотать цепочку SEH до конца. Последний элемент указывает куда-то внутри кернела. Выровнять на границу $1000 и сдвигать вверх с шагом $1000 проверяй наличие PE-заголовка. Платформонезависимый способ.



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

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

Наверх




Память: 0.57 MB
Время: 0.049 c
14-1103838942
AlterEgo of WondeRu
2004-12-24 00:55
2005.01.16
"Правильные" вопросы в форум ;-)


3-1103095185
PereZ
2004-12-15 10:19
2005.01.16
Поиск таблиц содержащих искомое поле


6-1098625186
criogen
2004-10-24 17:39
2005.01.16
Почта через прокси


11-1085075514
Terminus
2004-05-20 21:51
2005.01.16
Еще о KOLTabControl


14-1103881207
Ozone
2004-12-24 12:40
2005.01.16
Встреча в Тюмени (Тобольске)





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский