Вход на хостинг
IT-новости
20.04.2016 iPhone 2017 года поместят в водонепроницаемый корпус из стекла
Линейка iPhone в новом году серьезно поменяется. В этом уверен аналитический исследователь Мин Чи Ку......
30.07.2015 Ищем уникальный контент для сайта
Ищем уникальный контент для сайта Без уникального контента Ваш сайт обречен на то, что его страницы......
Рисунок 1. Схематическое изображение PE-файла
Все PE-файлы без исключения (и системные драйверы в том числе!) начинаются с old-exe заголовка, за концом которого следует dos-заглушка (ms-dos real-mode stub program или просто stub), обычно выводящая разочаровывающее ругательство на терминал, хотя в некоторых случаях в нее инкапсулирована MS-DOS версия программы, но это уже экзотика. Мэтт Питтерек в «Секретах системного программирования под Windows 95» пишет: «после того как загрузчик win32 отобразит в память PE-файл, первый байт отображения файла соответствует первому байту заглушки DOS». Это неверно! Первый байт отображения соответствует первому байту самого файла, т.е. отображение всегда начинается с сигнатуры «MZ», в чем легко можно убедиться, загрузив файл в отладчик и просмотрев его дамп.
PE-заголовок, в подавляющем большинстве случаев начинающийся непосредственно за концом old-exe программы, на самом деле может быть расположен в любом месте файла – хоть в середине, хоть в конце, т.к. загрузчик определяет его положение по двойному слову e_lfanew, смещенному на 3Ch байт от начала файла.
PE-заголовок представляет собой 18h-байтовую структуру данных, описывающую фундаментальные характеристики файла и содержащую «PEx0x0»-сигнатуру, по которой файл, собственно говоря, и отождествляется.
Непосредственно за концом PE-заголовка следует опциональный заголовок, специфицирующий структуру страничного имиджа более детально (базовый адрес загрузки, размер образа, степень выравнивания – все это и многое другое задается именно в нем). Название «опциональный» выбрано не очень удачно и слабо коррелирует с окружающей действительностью, ибо без опционального заголовка файл попросту не загрузится, так какой же он «опциональный», если обязательный? (Впрочем, когда PE-формат только создавался, все было по-другому, а сейчас мы вынуждены тащить это наследие старины за собой.) Важной структурой опционального заголовка является DATA_DIRECTORY, представляющая собой массив указателей на подчиненные структуры данных, как то: таблицы экспорта и импорта, отладочную информацию, таблицу перемещаемых элементов и т. д. Типичный размер опционального заголовка составляет E0h байт, но может варьироваться в ту или иную сторону, что определяется полнотой занятости DATA_DIRECTORY, а также количеством мусора за ее концом (если таковой вдруг там есть, хотя его настоятельно рекомендуется избегать). Может показаться забавным, но размер опционального заголовка хранится в PE-заголовке, так что эти две структуры очень тесно связаны.
За концом опционального заголовка следует суверенная территория, оккупированная таблицей секций. Политическая принадлежность ее весьма условна. Ни к одному из заголовков она не принадлежит и, судя по всему, является самостоятельным заголовком безымянного типа (подробнее см. «SizeOfHeaders» и «Таблица секций»). Редкое внедрение в исполняемый файл обходится без правки таблицы секций, поэтому эта структура для нас ключевая.
За концом таблицы секций раскинулось топкое болото ничейной области, не принадлежащей ни заголовкам, ни секциям, образовавшееся в результате выравнивания физических адресов секций по кратным адресам. В зависимости от ряда обстоятельств, подробно разбираемых по ходу изложения материала, заболоченная память может как отображаться на адресное пространство процесса, так и не отображаться на него. Обращаться с ней следует крайне осторожно, т.к. здесь может быть расположен чей-то оверлей, исполняемый код или структура данных (таблица диапазонного импорта, например).