· Начало · Статистика · WASM.RU · Noir.Ru ·

 WASM Phorum (Оффлайн - 24.11.2003) —› WASM.WIN32 —› Куда указывает [ESP] при старте программы?

Посл.отвђт Сообщенiе


Дата: Фев 18, 2003 00:59:03

Анализировал тут на днях один исходничек. И вопросы возникли, и много. :) Автор исходника начинает с того, что берет двойное слово на которое указывает ESP в момент запуска его прог-мы (другими словами dword лежащий изначально на самом дне стека) и делает предположение(а может и утверждение) что это - номер ячейки памяти из адресного пространства KERNEL32.DLL загруженного для его прогр-мы. Понятно выразился? :) То есть, грубо если при старте нашей программы стек кажет на 76d80000h то если пошарить "недалеко, в окресностях" :) то мы наткнемся на загруженный KERNEL32.DLL. Так вот интересно - это что справедливо для всей линейки Win'95-XP? И это официальная точка зрения или, так сказать, "житейская мудрость простых программеров"? :))
Теперь дальше. Просматриваются все адреса "в окрестности" которые кончаются на, минимум, 4-е ноля(ну это понятно - любая бибилиотека грузится только так). И если первые 2-а байта=='MZ' ,а потом dword по смещению 3ch кажет на 4-е байта=='PE',0,0 - это признается KERNEL32 для нашей программы. Тут я совсем уже плохо понимаю. 1)Такая комбинация байт может "лечь" случайно. Понятно, что вероятность такого события крайне мала, но не 0 все-таки! Или я что из вида упускаю? 2)Совершенно не понятно, почему это должен ОБЯЗАТЕЛЬНО оказаться KERNEL? USER32,GDI32 и иже с ними ничем не хуже, адреса загрузки весьма рядом с кернелом и все нужные 'MZ'/'PE' на месте. Тем не менее это всегда оказывается кернел! В чем здесь фокус?
Ну и на последок. Насколько я знаю, все сист. библиотеки(и кернел в т.ч.) грузятся в адреса между 2Gb и 3Gb. Поэтому ограничение зоны поиска "сверху" числом 0BFF70000h вполне понятно, где-то 3 гига и получается. Но вот почему "снизу" поиск идет начиная с 70000000h? У меня получается это где-то 1.88 гига. Не рановато искать начинаем?


Дата: Фев 18, 2003 11:17:54

Можно ли понять это вопрос так -> насколько можно доверять недокументированным "вещам" ?

А как Вы думаете что произойдет быстрей, устареет ваша программа или
измениться модель загрузки програм у фирмы Microsoft?


Дата: Фев 18, 2003 12:21:40

Вот вот програмист это не скульптор, а скорее повар:)


Дата: Фев 18, 2003 12:42:18

[ Smarty: Анализировал тут на днях один исходничек. ]

Это ты Kernel by y0da смотрел наверное.

[ Smarty: Автор исходника начинает с того, что берет двойное слово на которое указывает ESP в момент запуска его прог-мы (другими словами dword лежащий изначально на самом дне стека) и делает предположение(а может и утверждение) что это - номер ячейки памяти из адресного пространства KERNEL32.DLL загруженного для его прогр-мы. ]

Передача управления на точку входа происходит так: call [EntryPoint]
Естественно, что при этом в стек будет помещен адрес следующей инструкции. И этот адрес будет обязательно в пределах секции кода kernel32.dll, т.к. созданием процессов именно kernel32.dll занимается, а не user или gdi.

[ Smarty: Так вот интересно - это что справедливо для всей линейки Win'95-XP? И это официальная точка зрения или, так сказать, "житейская мудрость простых программеров"? :)) ]

Я тестировал только под 98 и 2к. Думаю, под 95 100% будет работать, под ХР наверное тоже. Это, естественно плоды медитации - гарантии никакой. Не будет call [EntryPoint], а например jmp [EntryPoint] и сразу работать перестанет.

[ Smarty: Просматриваются все адреса "в окрестности" которые кончаются на, минимум, 4-е ноля(ну это понятно - любая бибилиотека грузится только так). И если первые 2-а байта=='MZ' ,а потом dword по смещению 3ch кажет на 4-е байта=='PE',0,0 - это признается KERNEL32 для нашей программы. Тут я совсем уже плохо понимаю. 1)Такая комбинация байт может "лечь" случайно. Понятно, что вероятность такого события крайне мала, но не 0 все-таки! Или я что из вида упускаю? ]

Все правильно. Чисто теоретически может такое быть, но практически невероятно. Можно дополнительные проверки сделать.

[ Smarty: 2)Совершенно не понятно, почему это должен ОБЯЗАТЕЛЬНО оказаться KERNEL? ]

См. выше.

[ Smarty: Насколько я знаю, все сист. библиотеки(и кернел в т.ч.) грузятся в адреса между 2Gb и 3Gb. Поэтому ограничение зоны поиска "сверху" числом 0BFF70000h вполне понятно, где-то 3 гига и получается. Но вот почему "снизу" поиск идет начиная с 70000000h? У меня получается это где-то 1.88 гига. Не рановато искать начинаем?
]

Адрес 70000000h взят "от балды". С таким же успехом можно было взять и 77000000h. Дело в том, что в w2k адрес загрузки kernel32.dll = 77E80000h, а в 98 = 0BFF70000h. Поэтому y0da и решил, что 70000000h в самый раз будет. Кстати, ограничения сверху там нет - сканирование вниз идет по 64кБ. И если до 70000000h не нашли MZ, то просто тупо считается что kernel32.dll по адресу 0BFF70000h сидит. Глянь внимательнее.

Можешь почитать статью "Locating API function offsets in memory" по теме тут:
Programming Journal #4


Дата: Фев 18, 2003 15:09:39

{Four-F: Можешь почитать статью "Locating API function offsets in memory" по теме тут}

Вот спасибо за ссылочку! Все стало намного понятнее. И, как я предполагал, SEH в исходнике о котором шла речь - лишний. Если мы сканируем внутри загруженной библиотеки какие же могут быть исключения?

{Four-F: Кстати, ограничения сверху там нет - сканирование вниз идет по 64кБ. И если до 70000000h не нашли MZ, то просто тупо считается что kernel32.dll по адресу 0BFF70000h сидит. Глянь внимательнее.}

Да это-то я сразу понял, что сканирование вниз идет. Просто чтобы свой пост не перегружать излишними подробностями представил это в таком виде. А так, если отталкиваться от предположения, что мы изначально внутри кернела, конечно сканировать надо вниз, куда ж еще? :)

{Four-F:Я тестировал только под 98 и 2к. Думаю, под 95 100% будет работать, под ХР наверное тоже. Это, естественно плоды медитации - гарантии никакой. Не будет call [EntryPoint], а например jmp [EntryPoint] и сразу работать перестанет.}

Под XP даже не наверное, а точно. :) У меня XP Prof и все на ура работает. А что бы Микрософт call на jmp сменил - маловероятно(но возможно!). Ведь "поплывет" вся база создания процессов.

{Four-F:Это ты Kernel by y0da смотрел наверное.}

Ну конечно же его!! :))


Дата: Фев 18, 2003 16:51:07

[ Smarty: И, как я предполагал, SEH в исходнике о котором шла речь - лишний. ]

Практически - да. Теоретически - никогда не помешает.


Дата: Фев 18, 2003 18:54:14

Все это хорошо, но не все так просто. :)

Как бы все работает, а вопросы остаются(правда уже несколько иная тема).

Выдержка из упоминаемого исходника:

;---- AN UNUSED IMPORT ----
; The Win32 Loader of Win2k (maybe also of WinNT) won't call the EntryPoint of files which don't
; have an Import Table :(
; So here's an unused Import to make MASM compile an Import Table.
PUSH NULL
CALL GetOpenFileName


Выдержка из статьи по ссылке выше:

There is another problem for WinNT/Win2K (at least proven for Win2K and guessed for WinNT) which has nothing to do with my code, but with the fact that those operating systems don't run EXE files that have no import table. For compatibiliy reasons I use InitCommonControls in the example.


То есть понятно, да? Люди парятся и вставляют нафиг им не нужные функции только затем, что бы получившийся файл запустился под 2K, потому что без таблицы импорта - никуда (якобы). Так вот не знаю как там в 2K(но медитация мне подсказывает что там 99.99% тоже, что и в XP), но вот у меня на XP Prof получившийся файл без ЕДИНОЙ секции(весь массив DataDirectory в PE-заголовке забит нулями) не только грузится, но и на ура отрабатывает и корректно завершается!
Собсно, вопрос простой - кому верить? :) Кто нибудь на личном примере убеждался, что без импорта на Win2K EXE-шник не запускается?


Дата: Фев 19, 2003 09:35:44

Угу. И даже мессагу кажет, что типа импорта нет и запускать не буду.
Вроде так. Пару раз видел, но давно - могу путать ченить. Щас машинка как раз с ХР. Завтра попробую под 2000.


Дата: Фев 19, 2003 16:38:57

Прикольно!

Получается, что в XP и 2000 механизм запуска - разный!!! Вот уж не ожидал...


Дата: Фев 20, 2003 14:04:22

Щас глянул под 2000 Pro. Насчем мессаги я чето попутал. Мессаги нет никакой. А exe без импорта просто не запускается.


Дата: Фев 20, 2003 14:10:31

Понятно, спасибо за эксперимент. Под XP Pro такой файл запустится - широчайшее поле для медитаций открывается... :))


Дата: Ноя 10, 2003 21:13:12

В продолжение темы...
Кто-нибудь тестил "kernel by y0da" под 2003 и последующих??
В смысле ничего не поменялось в плане загрузки приложений виндой??


Дата: Ноя 10, 2003 23:43:36

В XP все так же, в стеке лежит адрес возврата в kernel.

Но лучше получать адрес kernel'а через PEB - это короче, удобнее и надежнее.


Дата: Ноя 11, 2003 01:50:41

Дык на XP я тоже проверял, интересно как в последующих!


Дата: Ноя 21, 2003 12:38:33

Читая это хочется спросить :
Дык если в NT загрузчик NtDll, то почему при старте
в стеке адресс возврата в kernel32, а не в NtDll.
И еще : как узнать ImageBase NtDll, естественно без
всяких там API. В FS:0 какие-то адресса принадлежащие kernel32.


Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.071