Вход на хостинг
IT-новости
20.04.2016 iPhone 2017 года поместят в водонепроницаемый корпус из стекла
Линейка iPhone в новом году серьезно поменяется. В этом уверен аналитический исследователь Мин Чи Ку......
30.07.2015 Ищем уникальный контент для сайта
Ищем уникальный контент для сайта Без уникального контента Ваш сайт обречен на то, что его страницы......
В памяти PE-заголовок (вместе со всеми остальными заголовками) всегда располагается перед первой секцией, вплотную прижимаясь к ее передней границе («вплотную» – значит, что расстояние между виртуальным адресом первой секции и концом заголовка должно быть меньше, чем Section Alignment). На диске PE-заголовок может быть расположен в любом месте файла, например, в его середине или конце (т.е. между началом файла и первым байтом PE-заголовка могут обосноваться одна или несколько секций). Не знаю, сойдет ли какой загрузчик от этого с ума, но в Windows 9x/NT все работает. При этом SizeOf Header должно быть равно действительному размеру PE-заголовка плюс e_lfanew; SectionAlignment >= SizeOfHeaders и FirstSection.RVA >= SizeOfHeaders.
[IMAGE_FILE_HEADER] Machine
Тип центрального процессора, под который скомпилирован файл. Если здесь будет что-то отличное от 14Ch, на I386-машинах файл просто не загрузится.
[IMAGE_FILE_HEADER] NumberOfSections
Количество секций. Файл, не содержащий ни одной секции, завешивает Windows 9x и корректно прерывает свою загрузку под Windows NT. Максимальное количество секций определяется особенностями реализации конкретного лоадера. Так, NT переваривает «всего» 60h секций. Другие загрузчики могут иметь и более жесткие ограничения. В общем, количество секций должно быть сведено к минимуму.
Если заявленное количество секций меньше числа записей в Section Table, то остальные секции просто не грузятся, но в целом такой файл обрабатывается вполне нормально. Настоящее веселье начинается, когда Numbers OfSection превышает количество реально существующих секций, вылетая за конец Section Table. Если здесь окажутся нули (как чаще всего и бывает), Windows 9x отреагирует вполне нормально, чего нельзя сказать о Windows NT, наотрез отказывающейся загружать такой файл. Файл с количеством секций, равным нулю, мертво завешивает Windows 9x, в то время как Windows NT обрабатывает такую ситуацию вполне нормально, выдавая неизменное «файл не является приложением win32».
Попутно заметим, что многие упаковщики исполняемых файлов по окончании процесса распаковки искажают это поле в памяти либо увеличивая, либо уменьшая его значение, в результате чего дамперы не могут корректно сбросить такой образ на диск. В pe-tools/lord-pe используется довольно ненадежный алгоритм, сканирующий Section Table и отталкивающийся от того, что если PointerToRelocations, PointerToLinenumbers, NumberOfRelocations и NumberOf Linenumbers равны нулю, а Characteristics – нет, значит, это секция. Эту святую простоту ничего не стоит обмануть! На самом деле, проверку следует ужесточить: если очередная запись в Section Table выглядит как секция (т.е. все поля валидны) – это секция и соответственно наоборот. Под валидностью здесь понимается, что адрес начала секции выровнен в памяти и лежит непосредственно за концом предыдущей секции, а размер секции не вылетает за пределы страничного имиджа.
Ниже приведен простой макрос, считывающий содержимое поля NumberOfSection по указателю на первый байт PE-заголовка.
Листинг 1. Считыватель содержимого NumberOfSection
// p – указатель на PE-заголовок