какая секция pe файла обычно содержит код программы

4. PE-файлы: секции

4.1. Заголовки секций

Сразу после заголовка PE в файле располагается массив заголовков секций. Его размер задается полем NumberOfSections заголовка файла. Каждый заголовок секции состоит из 0x28 байт и имеет следующую структуру:

Смещение (hex)РазмерТипНазваниеОписание
008CHAR[8]NameНазвание секции.
084DWORDMisc.VirtualSizeРазмер секции в памяти. Если это значение больше SizeOfRawData, то секция дополняется в памяти нулевыми байтами.
0C4DWORDVirtualAddressRVA секции в памяти.
104DWORDSizeOfRawDataРазмер секции в файле. Всегда кратен FileAlignment из необязательного заголовка. Если секция содержит только неинициализированные данные, то это поле равно нулю.
144DWORDPointerToRawDataСмещение в файле до начала данных секций. Всегда кратно FileAlignment из необязательного заголовка. Если секция содержит только неинициализированные данные, то это поле равно нулю.
184DWORDPointerToRelocationsВ исполняемых файлах это поле всегда равно нулю.
4DWORDPointerToLinenumbersВ исполняемых файлах это поле всегда равно нулю.
202WORDNumberOfRelocationsВ исполняемых файлах это поле всегда равно нулю.
222WORDNumberOfLinenumbersВ исполняемых файлах это поле всегда равно нулю.
244DWORDCharacteristicsАтрибуты секции.

Прокомментируем некоторые поля.

Название секции

Название секции содержит от 0 до 8 ASCII-символов. Вместо константы 8 можно использовать определение IMAGE_SIZEOF_SHORT_NAME. Если длина названия меньше 8 символов, то оно дополняется нулевыми байтами. Если оно состоит ровно из 8 символов, то завершающего нулевого байта нет. Важно отметить, что название секции, вообще говоря, никак не соотносится с ее содержимым. Каждый компилятор использует свое собственное соглашение о именовании секций, поэтому полагаться на название секции при ее анализе нельзя. Единственно надежным способом определить, что содержит данная секция, является анализ ее атрибутов и содержащихся в ней каталогов данных.

Атрибуты секции

32-битовое поле Characteristics содержит набор флагов, описывающих содержимое данной секции. Секции исполняемого файла могут иметь следующие атрибуты:

НазваниеЗначениеОписание
IMAGE_SCN_CNT_CODE0x00000020Секция содержит исполняемый код.
IMAGE_SCN_CNT_INITIALIZED_DATA0x00000040Секция содержит инициализированные данные.
IMAGE_SCN_CNT_UNINITIALIZED_DATA0x00000080Секция содержит неинициализированные данные.
IMAGE_SCN_MEM_DISCARDABLE0x02000000Секция может быть удалена из памяти после создания процесса.
IMAGE_SCN_MEM_NOT_CACHED0x04000000Секция не может кэшироваться.
IMAGE_SCN_MEM_NOT_PAGED0x08000000Секция не может выгружаться в файл подкачки.
IMAGE_SCN_MEM_SHARED0x10000000Все копии данного файла могут иметь один общий экземпляр этой секции. По-видимому, используется только для секций данных динамических библиотек.
IMAGE_SCN_MEM_EXECUTE0x20000000Секцию можно исполнять как программный код.
IMAGE_SCN_MEM_READ0x40000000Секцию можно читать.
IMAGE_SCN_MEM_WRITE0x80000000В секцию можно писать.

4.2. Содержимое секций

Сами секции располагаются в файле после всех заголовков секций. Каждая секция выравнена на границу FileAlignment из необязательного заголовка.

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

4.3. Доступ к секциям

Для получения указателя на заголовок первой секции можно использовать следующий макрос, определенный в WINNT.H:

где pHeader – указатель на заголовок PE, возвращаемый функцией GetHeader.

Для перебора всех заголовков секций удобно использовать такой цикл:

Теперь мы можем привести алгоритм, позволяющий пересчитать любой RVA в смещение относительно начала файла. Нам потребуются две функции. Первая ищет секцию, содержащую данный RVA, а вторая преобразует RVA в указатель на соответствующую ему позицию в файле.

В качестве примера приведем программу, которая печатает для каждого непустого каталога данных его RVA, размер и позицию в файле.

Источник

3. PE-файлы: заголовок PE

3.1. Структура заголовка

Заголовок PE (IMAGE_NT_HEADERS) всегда выравнен на границу 8 байт и состоит из трех частей:

Как уже было сказано, заголовок PE всегда начинается с 4-байтовой сигнатуры “PE\0\0” (IMAGE_NT_SIGNATURE). За ней следуют два заголовка: заголовок файла (IMAGE_FILE_HEADER) и необязательный заголовок (IMAGE_OPTIONAL_HEADER). Несмотря на свое название, IMAGE_OPTIONAL_HEADER присутствует в PE-файле всегда (необязательным он является с точки зрения общего формата COFF, поскольку не используется в объектных и библиотечных файлах).

3.2. Заголовок файла

Заголовок файла состоит из 0x14 байтов (определение IMAGE_SIZEOF_FILE_HEADER), размещается сразу после сигнатуры и содержит общее описание файла. Он состоит из следующих полей:

Смещение (hex)РазмерТипНазваниеОписание
002WORDMachineОбозначение процессора.
022WORDNumberOfSectionsКоличество секций в файле.
044DWORDTimeDateStampДата и время создания файла.
084DWORDPointerToSymbolTableСмещение до таблицы символов или 0.
0C4DWORDNumberOfSymbolsКоличество элементов в таблице символов.
102WORDSizeOfOptionalHeaderРазмер необязательного заголовка.
122WORDCharacteristicsАтрибуты файла.

Опишем назначения полей.

Поле Machine

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

НазваниеЗначениеПроцессор
IMAGE_FILE_MACHINE_UNKNOWN0неизвестный процессор
IMAGE_FILE_MACHINE_I3860x014CIntel 80386 или выше
0x014DIntel 80486 или выше
0x014EIntel Pentium или выше
0x0160MIPS R3000, big-endian
IMAGE_FILE_MACHINE_R30000x0162MIPS R3000, little-endian
IMAGE_FILE_MACHINE_R40000x0166MIPS R4000
IMAGE_FILE_MACHINE_R100000x0168MIPS R10000
IMAGE_FILE_MACHINE_WCEMIPSV20x0169MIPS WCE v2
IMAGE_FILE_MACHINE_ALPHA0x0184DEC/Compaq Alpha AXP
IMAGE_FILE_MACHINE_SH30x01A2Hitachi SH3
IMAGE_FILE_MACHINE_SH3DSP0x01A3Hitachi SH3 DSP
IMAGE_FILE_MACHINE_SH3E0x01A4Hitachi SH3E
IMAGE_FILE_MACHINE_SH40x01A6Hitachi SH4
IMAGE_FILE_MACHINE_SH50x01A8Hitachi SH5
IMAGE_FILE_MACHINE_ARM0x01C0ARM
IMAGE_FILE_MACHINE_THUMB0x01C2ARM Thumb
IMAGE_FILE_MACHINE_AM330x01D3Panasonic AM33
IMAGE_FILE_MACHINE_POWERPC0x01F0IBM PowerPC
IMAGE_FILE_MACHINE_POWERPCFP0x01F1IBM PowerPC FP
IMAGE_FILE_MACHINE_IA640x0200Intel IA-64 (Itanium)
IMAGE_FILE_MACHINE_MIPS160x0266MIPS16
0x0268Motorola 68000
IMAGE_FILE_MACHINE_ALPHA640x0284DEC/Compaq Alpha AXP 64-bit
0x0290HP PA-RISC
IMAGE_FILE_MACHINE_MIPSFPU0x0366MIPS with FPU
IMAGE_FILE_MACHINE_MIPSFPU160x0466MIPS16 with FPU
IMAGE_FILE_MACHINE_TRICORE0x0520Infineon TriCore
IMAGE_FILE_MACHINE_CEF0x0CEF.
IMAGE_FILE_MACHINE_EBC0x0EBCEFI Byte Code
IMAGE_FILE_MACHINE_AMD640x8664AMD 64 (K8)
IMAGE_FILE_MACHINE_M32R0x9041Renesas M32R
IMAGE_FILE_MACHINE_CEE0xC0EE.

Поле TimeDateStamp

32-битовое число, которое содержит дату и время создания данного файла. Формат этого поля недокументирован, однако сборщики Microsoft заносят сюда время как количество секунд от полуночи 01.01.1970 в UTC (т. е. используют юниксовский формат времени, возвращаемого функцией time языка C). Между прочим, это означает, что текущее состояние формата PE действительно только до 18.01.2038 г.

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

Поля PointerToSymbolTable и NumberOfSymbols

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

Поле SizeOfOptionalHeader

16-битовое число, задающее размер необязательного заголовка. Оно равно 0xE0 для файлов PE32 (IMAGE_SIZEOF_NT_OPTIONAL32_HEADER) и 0xF0 для файлов PE32+ (IMAGE_SIZEOF_NT_OPTIONAL64_HEADER).

Поле Characteristics

16-битовое поле флагов, содержащее COFF-атрибуты файла. Перечислим только те флаги, которые относятся к исполняемым файлам.

3.3. Необязательный заголовок

Необязательный заголовок имеет два различных формата: для PE32 и для PE32+. Соответствующие структуры называются IMAGE_OPTIONAL_HEADER32 и IMAGE_OPTIONAL_HEADER64. Их поля сведены в следующей таблице:

Смещение (hex, PE32/PE32+)Размер (PE32/PE32+)Тип (PE32/PE32+)НазваниеОписание
002WORDMagicСигнатура заголовка.
021BYTEMajorLinkerVersionСтаршая цифра номера версии сборщика. Загрузчиком не используется.
031BYTEMinorLinkerVersionМладшая цифра номера версии сборщика. Загрузчиком не используется.
044DWORDSizeOfCodeСумма размеров всех секций, содержащих програмный код.
084DWORDSizeOfInitializedDataСумма размеров всех секций, содержащих инициализированные данные.
0C4DWORDSizeOfUninitializedDataСумма размеров всех секций, содержащих неинициализированные данные.
104DWORDAddressOfEntryPointRVA точки запуска программы. Для драйвера – это адрес DriverEntry, для DLL – адрес DllMain или нуль.
144DWORDBaseOfCodeRVA начала кода программы.
18/–4/0DWORDBaseOfDataRVA начала данных программы. Ненадежное поле, загрузчиком не используется. В PE32+ отсутствует!
1С/184/8DWORD/ULONGLONGImageBaseПредпочтительный базовый адрес программы в памяти, кратный 64 Кб. По умолчанию равен 0x00400000 для EXE-файлов в Windows 9x/NT, 0x00010000 для EXE-файлов в Windows CE и 0x10000000 для DLL. Загрузка программы с этого адреса позволяет обойтись без настройки адресов.
204DWORDSectionAlignmentВыравнивание в байтах для секций при загрузке в память, большее или равное FileAlignment. По умолчанию равно размеру страницы виртуальной памяти для данного процессора.
244DWORDFileAlignmentВыравнивание в байтах для секций внутри файла. Должно быть степенью 2 от 512 до 64 Кб включительно. По умолчанию равно 512. Если SectionAlignment меньше размера страницы виртуальной памяти, то FileAlignment должно с ним совпадать.
282WORDMajorOperatingSystemVersionСтаршая цифра номера версии операционной системы. Загрузчиком не используется.
2A2WORDMinorOperatingSystemVersionМладшая цифра номера версии операционной системы. Загрузчиком не используется.
2C2WORDMajorImageVersionСтаршая цифра номера версии данного файла. Загрузчиком не используется.
2E2WORDMinorImageVersionМладшая цифра номера версии данного файла. Загрузчиком не используется.
302WORDMajorSubsystemVersionСтаршая цифра номера версии подсистемы.
322WORDMinorSubsystemVersionМладшая цифра номера версии подсистемы.
344DWORDWin32VersionValueЗарезервировано, всегда равно 0.
384DWORDSizeOfImageРазмер файла в памяти, включая все заголовки. Должен быть кратен SectionAlignment.
3C4DWORDSizeOfHeadersСуммарный размер заголовка и заглушки DOS, заголовка PE и заголовков секций, выравненный на границу FileAlignment. Задает смещение от начала файла до данных первой секции.
404DWORDCheckSumКонтрольная сумма файла.
442WORDSubsystemИсполняющая подсистема Windows для данного файла.
462WORDDllCharacteristicsДополнительные атрибуты файла.
484/8DWORD/ULONGLONGSizeOfStackReserveРазмер стека стартового потока программы в байтах виртуальной памяти. При загрузке в физическую память отображается только SizeOfStackCommit байт, в дальнейшем отображается по одной странице виртуальной памяти. По умолчанию равен 1 Мб.
4C/504/8DWORD/ULONGLONGSizeOfStackCommitНачальный размер стека программы в байтах. По умолчанию равен 4 Кб.
50/584/8DWORD/ULONGLONGSizeOfHeapReserveРазмер кучи программы в байтах. При загрузке в физическую память отображается только SizeOfHeapCommit байт, в дальнейшем отображается по одной странице виртуальной памяти. По умолчанию равен 1 Мб. Во всех 32-разрядных версиях Windows куча ограничена только размером виртуальной памяти и это поле, по-видимому, игнорируется.
54/604/8DWORD/ULONGLONGSizeOfHeapCommitНачальный размер кучи программы в байтах. По умолчанию равен 4 Кб.
58/684DWORDLoaderFlagsУстаревшее поле, не используется.
5C/6C4DWORDNumberOfRvaAndSizesКоличество описателей каталогов данных. На текущий момент всегда равно 16.
60/70128IMAGE_DATA_DIRECTORY[16]DataDirectoryОписатели каталогов данных.

Поясним некоторые поля этой структуры.

Поле Magic

16-битовое поле, содержащее сигнатуру заголовка. Может принимать значения:

Поля MajorSubsystemVersion и MinorSubsystemVersion

16-битовые числа, указывающее ожидаемую версию Windows. В отличие от всех остальных полей с номерами версий это поле анализировалось при загрузке программ в NT 4.0 и 95. Если программа была графическим приложением и это поле не содержало версии 4.0, то считалось, что программа разработана для NT 3.51 и моделировалось поведение этой ОС (в частности, отсутствие трехмерных стилей диалогов и пр.). В настоящее время не используется и практически всегда равно 4.0.

Поле CheckSum

32-битовая контрольная сумма файла. Проверяется только в Windows NT при загрузке драйверов ядра и нескольких системных DLL. Алгоритм вычисления контрольной суммы недокументирован, но для ее вычисления можно использовать системную функцию CheckSumMappedFile из библиотеки IMAGEHLP.DLL.

Поле Subsystem

16-битовое число, указывающее в какой подсистеме Windows API должен исполняться данный файл. Его возможные значения:

НазваниеЗначениеПодсистема
IMAGE_SUBSYSTEM_UNKNOWN0Неизвестная подсистема.
IMAGE_SUBSYSTEM_NATIVE1Подсистема не требуется, используется драйверами и “родными” приложениями NT.
IMAGE_SUBSYSTEM_WINDOWS_GUI2Графическая подсистема Windows.
IMAGE_SUBSYSTEM_WINDOWS_CUI3Консольная подсистема Windows.
IMAGE_SUBSYSTEM_OS2_CUI5Консольная подсистема OS/2.
IMAGE_SUBSYSTEM_POSIX_CUI7Консольная подсистема POSIX.
IMAGE_SUBSYSTEM_NATIVE_WINDOWS8“Родной” драйвер Win 9x.
IMAGE_SUBSYSTEM_WINDOWS_CE_GUI9Графическая подсистема Windows CE.
IMAGE_SUBSYSTEM_EFI_APPLICATION10Программа EFI.
IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER11Драйвер EFI, обеспечивающий загрузочный сервис.
IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER12Драйвер EFI времени выполнения.
IMAGE_SUBSYSTEM_EFI_ROM13Прошивка ПЗУ для EFI.
IMAGE_SUBSYSTEM_XBOX14Подсистема Xbox.

Поле DLLCharacteristics

16-битовое поле флагов, задающие дополнительные атрибуты файла. Возможные значения флагов:

НазваниеЗначениеОписание
IMAGE_DLLCHARACTERISTICS_NO_SEH0x0400Файл не использует структурную обработку исключений.
IMAGE_DLLCHARACTERISTICS_NO_BIND0x0800Запрещает статическое связывание этого файла.
IMAGE_DLLCHARACTERISTICS_WDM_DRIVER0x2000Файл является WDM-драйвером.
IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE0x8000Если этот флаг не установлен, то при загрузке программы терминальным сервером будет загружена вспомогательная DLL, обеспечивающая совместимость кода.

Поля NumberOfRvaAndSizes и DataDirectory

В конце необязательного заголовка располагается 32-битовое число, в котором хранится количество описателей каталогов данных. За ним следует массив самих описателей, каждый из которых имеет такой вид:

В настоящее время поле NumberOfRvaAndSizes всегда содержит число 16 (символическое имя IMAGE_NUMBEROF_DIRECTORY_ENTRIES). Соответственно массив DataDirectory состоит также из 16 описателей. Каждый описатель содержит RVA и размер для одного каталога данных. Если какого-либо каталога в файле нет, то оба поля его описателя равны нулю.

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

Источник

Структура программных компонентов

Обзор структуры PE-файла

какая секция pe файла обычно содержит код программы. Смотреть фото какая секция pe файла обычно содержит код программы. Смотреть картинку какая секция pe файла обычно содержит код программы. Картинка про какая секция pe файла обычно содержит код программы. Фото какая секция pe файла обычно содержит код программы

В секциях размещаются код и данные исполняемого файла, а также служебная информация, необходимая загрузчику (например, секция “. reloc ” на схеме содержит таблицу релокаций). Секции в оперативной памяти должны быть выровнены по границам страниц, поэтому загрузчик отображает каждую секцию, начиная с новой страницы адресного пространства процесса. Это приводит к тому, что в памяти секции, как правило, располагаются менее компактно, чем в файле (и это отражено на схеме).

Секции

Секция в PE-файле представляет либо код, либо некоторые данные (глобальные переменные, таблицы импорта и экспорта, ресурсы, таблица релокаций). Каждая секция имеет набор атрибутов, задающий ее свойства. Атрибуты секции определяют, доступна ли секция для чтения и записи, содержит ли она исполняемый код, должна ли она оставаться в памяти после загрузки исполняемого файла, могут ли различные процессы использовать один экземпляр этой секции и т.д.

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

Выбор базового адреса образа PE-файла в памяти
Импорт функций

В PE-файле существует специальная секция “.idata”, описывающая функции, который этот файл импортирует из динамических библиотек. Описание импортируемых функций в секции “.idata” приводит к тому, что библиотеки загружаются загрузчиком операционной системы еще до запуска программы. В принципе, необязательно описывать каждую импортируемую функцию в этой секции, так как динамические библиотеки можно загружать с помощью функции LoadLibrary из Win32 API прямо во время выполнения программы.

Экспорт функций

Информация об экспортируемых функциях хранится внутри PE-файла в специальной секции “.edata”. При этом каждой функции присваивается уникальный номер, и с этим номером связывается RVA тела функции, и, возможно, имя функции. Не всякая экспортируемая функция имеет имя, так как имена служат, главным образом, для удобства программистов.

Источник

Какая секция pe файла обычно содержит код программы

Вероятно, это одна из самых важных глав данного пособия. Прочитайте его!

Введение

Очень важно хорошо представлять себе структуру заголока PE-файла, чтобы писать наши виндовозные вирусы. В этой главе я перечислю все, что считаю наиболее важным, но здесь не вся информация о PE-файле, поэтому рекомендую взглянуть на документы, упомянутые в разделе “Что потребуется. “.

какая секция pe файла обычно содержит код программы. Смотреть фото какая секция pe файла обычно содержит код программы. Смотреть картинку какая секция pe файла обычно содержит код программы. Картинка про какая секция pe файла обычно содержит код программы. Фото какая секция pe файла обычно содержит код программы

Давайте рассмотрим каждую из этих частей поподробнее. Вот диаграмма в стиле Micheal J. O’Leary.

какая секция pe файла обычно содержит код программы. Смотреть фото какая секция pe файла обычно содержит код программы. Смотреть картинку какая секция pe файла обычно содержит код программы. Картинка про какая секция pe файла обычно содержит код программы. Фото какая секция pe файла обычно содержит код программы

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

IMAGE_FILE_HEADER

какая секция pe файла обычно содержит код программы. Смотреть фото какая секция pe файла обычно содержит код программы. Смотреть картинку какая секция pe файла обычно содержит код программы. Картинка про какая секция pe файла обычно содержит код программы. Фото какая секция pe файла обычно содержит код программы

Я дам краткое описание (резюме того, что сказал в своем прекрасном документе о формате PE-файла Мэтт Питрек) полей IMAGE_FILE_HEADER.

Это метка, которая есть у каждого PE-файла. Просто проверяйте ее существование при заражении файла. Если метки нет, то это не PE-файл, ок?

Так как компьютером, который мы используем может быть несовместим с PC (теоретически), а PE-файлы могут быть и на таких компьютерах, в этом поле указывается тип машины, для которой предназначается приложение. Это может быть одно из следующих значений:

Это поле играет важную роль при заражении. Оно сообщает, сколько секций в файле.

Содержит количество секунд, которое прошло с декабря 31-ого 1969 года с 4:00 до того момента, когда файл был слинкован.

¤ Указатель на таблицу символов

Не интересно, поскольку используется только в OBJ-файлах.

Не интересно, поскольку используется только в OBJ-файлах.

¤ Размер опционального заголовка:

Содержит количество байтов, которое занимает IMAGE_OPTIONAL_HEADER (смотри описание

Флаг дает нам еще кое-какую информацию о файле. Нам это не интересно.

IMAGE_OPTIONAL_HEADER

какая секция pe файла обычно содержит код программы. Смотреть фото какая секция pe файла обычно содержит код программы. Смотреть картинку какая секция pe файла обычно содержит код программы. Картинка про какая секция pe файла обычно содержит код программы. Фото какая секция pe файла обычно содержит код программы

Так как это поле всегда равно 010Bh, похоже, что это какая-то сигнатура. Не интересно.

¤ Старшая и младшая версии линкера:

Версия линкера, который создал файл. Не интересно.

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

¤ Размер инициализированных данных:

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

¤ Размер неинициализированных данных:

Неинициализированные данные не занимают места на винте, но когда система загружает файл, она выделяет ему некоторое количество памяти (виртуальную память).

Где загрузчик начнет выполнение кода. Это RVA относительно базы образа, когда система загружает файл. Очень интересно.

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

RVA, откуда начинаются секции с данными. Они обычно идут последними после PE-заголовка и секций с кодом.

Когда линкер создает экзешник, он предполагает, что файл будет промэппирован в определенное место в памяти. Этот адрес и хранится в данном поле, делая возможным определенную оптимизацию со стороны линкера. Если файл действительно промэппирован по этому адресу, код не нуждается в каком-либо патчении перед запуском. В экзешниках, компилируемых для Windows NT, база образа по умолчанию равна 0x10000, а для DLL он по умолчанию равен 0x400000. В Win9x адрес 0x10000 не может использоваться при загрузке 32-х битных EXE, так как он находится внутри региона, разделяемого всеми процессами. Из-за этого Микрософт изменил адрес базы по умолчанию на 0x400000.

При мэппировании секции выравниваются таким образом, чтобы они начинались с виртуального адреса, кратного данному значению. Выравнивание секций по умолчанию равно 0x1000.

В PE-файле raw-данные, представляющие каждую из секций, начинаются со значения, кратного данному параметру. По умолчанию он равен 0x200, вероятно, потому что тогда секции будут начинаться с начала сектора диска (который также равен 0x200 байтам). Это поле эквивалентно размеру выравнивания сегментов/ресурсов в NE-файлах. В отличии от NE-файлов, PE-файлы не имеют сотен секций, поэтому на файловое выравнивание уходит очень мало место.

¤ Старшая и младшая версии операционной системы:

Минимальная версия операционной системы, которая требуется для использования данной программы. Назначение данного поля не совсем ясно, так как поля подсистемы служат, похоже, той же самой цели. Это поле по умолчанию равно 1.0.

¤ Младшая и старшая версии образа:

Задаваемое пользователем поле. Оно позволяет вам иметь разные версии EXE или DLL. Вы можете установить значения этих полей с помощью опции линкера /VERSION. Например “LINK /VERSION:2.0 myobj.obj”.

¤ Старшая и младшая версии подсистемы:

Похоже, что оно всегда равно 0 (идеально для метки заражения).

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

Размер PE-заголовка и таблицы секций (объектов). Raw-данные секций начинаются непосредственно после всех компонентов заголовка.

Предположительно CRC файла. Как и в других микрософтовских форматах исполняемых файлов, это поле игнорируется и устанавливается в 0. Есть одно исключение из этого правила: в доверенных (trusted) сервисах и EXE это поле должно содержать верную чексумму.

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

Набор флагов, задающий при каких условиях будет вызываться функция инициализации DLL (например DLLMain). Похоже, что это значение всегда равно 0, тем не менее операционная система вызывает инициализацию DLL для всех 4-х событий.

¤ Размер зарезервированного стека:

Количество виртуальной памяти, резервируемой для начального стека треда. Тем не менее, не вся эта память выделяется (смотри следующее поле). Это поле по умолчанию равно 0x100000. Если вы укажете 0 в качестве размера стека при создании треда функцией CreateThread, именно столько будет занимать стек нового треда.

¤ Размер выделенного стека:

Количество памяти, выделяемой для начального стека треда. Это поле по умолчанию равно 0x1000 (1 страница) у Microsoft Linker, в то время как TLINK32 делает это поле равным двум страницам.

¤ Размер зарезервированной кучи:

Количество виртуальной памяти, которое необходимо зарезервировать для начальной кучи процесса. Этот хэндл кучи можно получить, вызывав GetProcessHeap. Нет вся эта память выделяется (смотри следующее поле).

¤ Размер выделенной кучи:

Согласно WINNT.H эти поля относятся к поддержке отладки. Я никогда не видел экзешника с установленными битами этого поля, да и как заставить линкер их установить не совсем понятно.

1. Вызвать инструкцию точки прерывания перед запуском процесса 2. Вызвать отладчик после того, как процесс будет загружен в память

¤ Number Of Rva And Sizes:

Количество элементов в массиве DataDirectory (ниже). Современные компиляторы всегда устанавливает это поле равным 16.

IMAGE_SECTION_HEADER

какая секция pe файла обычно содержит код программы. Смотреть фото какая секция pe файла обычно содержит код программы. Смотреть картинку какая секция pe файла обычно содержит код программы. Картинка про какая секция pe файла обычно содержит код программы. Фото какая секция pe файла обычно содержит код программы

Это 8-ми байтовое имя в формате ANSI (UNICODE), которая задает имя секции. Большая часть имен секций начинается с “.” (например “.text”), но это не обязательное требование как утверждают некоторые руководства по формату PE. Вы можете назвать вашу секцию как хотите с помощью специальной директивы ассемблера или с помощью “#pragma data_seg” и “#pragma code_seg” в Microsoft C/C++ компиляторе. Важно учитывать, что если имя секции занимает 8 байт, то в конце не будет NULL-байта. Вы можете использовать %.8s с функцией printf, чтобы скопировать строку в другой буфер и добавить NULL в конце.

Значение этого файла отличается в EXE и OBJ. В EXE он содержит реальный размер код или данных. Это размер до округления до ближайшего числа, кратного файловому выравниванию. Поле SizeOfRawData ‘размер raw-данных’ (похоже, названное не совсем верно) содержит округленное значение. Линкер Borland’а меняет значения этих двух полей и похоже, что он прав. Для OBJ файлов этой поле означает физический адрес секции. Первая секция начинается с адреса 0. Чтобы найти физический адрес следующей секции в OBJ-файле, добавьте значение SizeOfRawData к физическому адресу текущих секции.

В EXE это поле содержит RVA на то место, куда загрузчику следует промэппировать секцию. Чтобы посчитать реальный стартовый адрес данной секции в памяти и добавьте базовый адрес образа к виртуальному адресу (поле VirtualAddress). Микрософтовские инструменты по умолчанию указывают на RVA 0x1000. В OBJ’ах это поле не имеет значения и установленно в 0.

В EXE это поле содержит округленный до кратного файловому выравниванию числа размер секции. Например, предположим, что файловое выравнивание равно 0x200. Если поле VirtualSize содержит значение 0x35A, в этом поле будет находиться 0x400. В OBJ’ах это поле содержит точный размер секции, созданной компилятором или ассемблером. Другими словами для OBJ это поле играет ту же роль, что и виртуальный размер в EXE.

¤ Указатель на raw-данные:

¤ Указатель на релокейшены:

В OBJ’ах это смещение на информацию о релокейшенах данной секции. Информация о релокейшенах каждой секции OBJ следует непосредственно за raw-данными этой секции. В EXE это поле не имеет значения (как и следующее поле) и установлено в ноль. Когда линкер создает EXE, он устанавливает большую часть адресных записей (fixups), и только релокейшены адреса базы и импортируемых функций устанавливаются во время загрузки. Информация о релокейшенах базы и импортируемых функций находится в специальных секциях, поэтому в EXE нет необходимости держать информацию о релокейшенах после каждой секции raw-данных.

¤ Указатель на номера строк:

¤ Количество номеров строк:

Количество номеров строк в соответствующей таблице для данной секции.

То, что большинство программистов называет флагами, формат COFF/PE называет характеристиками. Это поле является множеством флагов, которые задают аттрибуты секции (такие как код/данные, доступно ли для чтения или для записи). Чтобы получить полный список всех возможных аттрибутов секций, смотрите IMAGE_SCN_XXX_XXX #defin’ы в WINNT.H. Некоторые из важных флагов приведены ниже:

0x00000020 Эта секция содержит код. Обычно устанавливается вместе с флагом выполняемого кода (0x80000000).

0x00000800 Содержимое этой секции не должно помещаться в конечный EXE-файл. Эти секции используются компилятором/ассемблером, чтобы передать информацию линкеру.

0x10000000 Эта секция является разделяемой. Если используется вместе с DLL, данные в этой секции будут разделяться всеми процессами, ее использующими. По умолчанию секции данных являются неразделяемыми, и это означает, что каждый процесс, использующий DLL получает свою собственную копию этой секции данныи. Если использовать техническую терминологию, флаг разделяемости говорит менеджеру загрузки, чтобы тот установил мэппинги страниц таким образом, чтобы все процессы, использующие DL ссылались на одну и ту же физическую страницу в памяти. Чтобы сделать секцию разделямой, используйте аттрибут SHARED во время линковки. Например:

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

0x20000000 Эта секция является исполняемой. Этот флаг обычно устанавливается везде, где установлен флаг кода (0x00000020).

0x40000000 Эта секция доступня для чтения. Этот флаг установлен почти для всех секций EXE-файла.

Необходимые изменения

Хорошо, здесь я объясню вам изменения, которые необходимо выполнить при заражении PE. Я предполагаю, что вы делаете вирус, который увеличивает размер последней секции PE-файла. Эта техника получила наибольшее распространение среди нас, да и она, между прочим, гораздо проще, чем добавление другой секции. Давайте посмотрим, как вирус может изменить заговок исполняемого файла. Для этого мы используем программу INFO-PE Lord’а Julus’а [SLAM].

Источник

Leave a Reply

Your email address will not be published. Required fields are marked *