Формат объектного coff файла

Обновлено: 07.07.2024

* Common Object File Format - стандартный формат
oбъектного файла
* Некоторые поля файла имеют восьмеричный
формат
* COFF-формат был сам по себе неплохой отправной
точкой, но нуждался в расширении, чтобы
удовлетворить потребностям новых операционных
систем, таких как Windows NT или Windows 98.
Результатом такого усовершенствования явился РЕформат

3. Portable Executable - переносимый исполняемый

* Это формат исполняемых файлов, объектного кода
и динамических библиотек, используемый в 32- и
64-битных версиях операционной системы Microsoft
Windows.
* Формат PE представляет собой структуру данных,
содержащую всю информацию, необходимую PE
загрузчику для проецирования файла в память.
* PE-файл состоит из заголовка и некоторого набора
секций, количество и размер которых зависит от
информации, содержащейся в заголовке.

4. COFF и PE. В чем различие?

* Компоновщик не превращает объектный файл в
исполняемый, а создаёт загрузочный модуль на
основе информации, содержащейся в одном или
нескольких объектных модулях.
* Другими словами, объектный и исполняемый
файлы - это два совершенно разных файла, хотя и
содержащие значительный объем одинаковой
информации.

5. Шаг 1 – Написание программы

*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
.386
.model flat
extrn MessageBoxA: dword
extrn ExitProcess: dword
extrn GetComputerNameA: dword
.code
_start:
push offset nSize
push offset lpBuffer
call GetComputerNameA
push 40h
push offset msg
push offset lpBuffer
push 00h
call MessageBoxA
push 00h
call ExitProcess
.data
lpBuffer db 20 dup(0),0
nSize db 3 dup(0),14h
msg db 'PE Linker',0
end _start
* обязательно должна использоваться
модель памяти FLAT (плоская
бессегментная модель).
* все внешние функции (в данном случае
- функции API) необходимо объявлять с
помощью директивы:
extrn <имя
функции>: dword
* имена функций чувствительны к
регистру символов.
* адрес загрузки брать из задания!
* После написания программы её
необходимо откомпилировать с
помощью команды:
ml/coff /c <имя файла>

6. Шаг 2 - Создание заголовка PE-файла

7. Шаг 2 - Создание заголовка PE-файла

* первый байт отображения
файла соответствует
первому байту заглушки
DOS.
* настоящий заголовок
можно обнаружить,
найдя его стартовое сме
щение, которое хранится
в заголовке DOS.
* Поле e_lfanew собственно и содержит относительное
смещение (RVA) настоящего заголовка РЕ-файла.

8. Шаг 2 - Создание заголовка PE-файла

Файловое
смещение
заголовка
* Поле Signature (сигнатура - подпись), представленное как
ASCII код, - это РЕ00 (два нулевых байта после РЕ).

9. Шаг 2 - Создание заголовка PE-файла

Файловое смещение
дополнительного
заголовка
* NumberOfSections – кол-во
секций = 3
(кода,данных,импорта)
* TimeDateStamp –время
создания файла (поумолчанию = 0)

10. Шаг 2 - Создание заголовка PE-файла

Файловое
смещение
таблицы
секций
* ImageBase – адрес
загрузки (см.шаг 1)
* Magic - слово-сигнатура, определяющее
состояние отображенного файла(010bисполняемое
отобра-жение). Для
64 разрядной
системы равно 020b.

11. Шаг 2 - Создание заголовка PE-файла

* AddressOfEntryPoint = 1000 (входная точка главного потока
= RVA данных секции кода(.text)
* SectionAlignment ≥ 1000 (const Кратность выравнивания
секций в памяти = размер страницы)
* FileAlignment ≥ 200 (const Кратность выравнивания секций
на диске = размер сектора винчестера)
* SizeOfImage = VirtualAddress(последней скции) +
VirtualSize(последней секции) = 3000+1000=4000
* SizeOfHeaders = 400 (const = размер всех заголовков и
таблицы секций)

12. Шаг 2 - Создание заголовка PE-файла

* SizeOfStackReserve = 100000 (const = зарезервированный в
вирт. пространстве объём для стека главного потока)
* SizeOfStackCommit = 1000 (const = зарезервированный в
пространстве физ. памяти объём для стека главного
потока)
* SizeOfHeapReserve = 100000 (const = зарезервированный
объём для главного хипа)
* SizeOfHeapCommit = 1000 (const = зарезервированный в
пространстве физ. памяти объём для главного хипа)

13. Шаг 3 - Создание секций PE-файла

* Name – название секции
* VirtualSize = 1000 (вирт.
размер секции)
* VirtualAddress = 1000 +
VirtualSize * (номер
секции -1) (адрес начала
секции в памяти)
* SizeOfRawData = 200 (физ.
размер секции)
* PointerToRawData = 400 +
SizeOfRowData * номер
секции (смещение
относительно начала
файла)

14. Шаг 3 - Создание секций PE-файла

* Для секции кода(.text)
* Для секции данных(.data и .idata)

15. Шаг 3 - Создание секций PE-файла

16. Шаг 3 - Создание секций PE-файла

* Если это не секция “.idata” то
1)Клик мышкой на ячейку (0;0)
2)В нижней части всплывшего окна выбираем вкладку
«Вставка из секции COFF»
3)устанавливаем в поле «Секция COFF» открывшейся панели
имя совпадающее с именем этой секции.
4)устанавливаем в поле «Копировать всю секцию»
открывшейся панели галочку.
5)Нажимаем кнопку «Копировать».

17. Шаг 3 - Создание секций PE-файла

* Что храниться в секции “.idata”
?
• Перед загрузкой в память информация, хранящаяся в секции
.idata РЕ-файла, содержит информацию, необходимую для
того, чтобы загрузчик мог определить адреса целевых
функций и пристыковать их к отображению исполняемого
файла.
• После загрузки секция .idata содержит указатели функций,
импортируемых EXE-файлом или DLL.

18. Шаг 3 - Создание секций PE-файла

* Если это секция “.idata” то
* Предварительно подключаем таблицу импорта в заголоке.

Это смещение
(RVA)
массива
Вписываем
массив
Значение
записывается
слов.
Оно равно
IMAGE_IMPORT_DESCRIPTOR
Второй
элемент
вдвойных
обратном
порядке.
ДляOriginalFitrstThunk
этого нужно заполнить поля
Name
- это смещение
строки
VirtualAddress(секции
.idata)
++
для VirtualAddres
каждого
модуля
IMAGE_IMPORT_DESCRIPTOR.
Равно
секции
во
вкладке
FirstThunk
символов
ASCII,
оканчивающейся
адрес_на_указатель_функций
= =
Не
забудьте
выравнивание!!
смещение
на
строку
с модулем
IMAGE_IMPORT_DESCRIPTOR
Это
смещение
массива
нулем
иOriginalFitrstThunk
имена
3000
+содержащей
B0 =+ 30B0
Равно
+ 0fh
3000
60
двойных слов
импортируемых
DLL
Вписываем все
подключаемые
Вписываем
все
А
в
строках
D0
и
модули
с помощью
Теперь
в строках
B0E0
и делаем
С0 делаем
используемые
ссылки
на
вставки
ASCIIZ модуля
ссылки
на функции
функции
модуля вв
функции
с помощью
строке
50(kernel32.dll)
строке 60(user32.dll)
вставки ASCIIZ

20. Шаг 4 – Разрешение статических и внешних ссылок

* Очень важный этап компоновки - разрешение статических и
внешних ссылок.
* На этапе компиляции неизвестны реальные адреса
переменных и функций API, поэтому компилятор превращает
адреса переменных в статические, а адреса функций API - во
внешние ссылки.
* Информация о неразрешенных ссылках хранится в двух
местах в объектном модуле: в COFF-таблице символов и в
списках привязок для каждой секции.

21. Шаг 4 – Разрешение статических и внешних ссылок

Для разрешения ссылок для каждой секции COFF-файла
используется следующий алгоритм:
1)найти первую, еще не разрешенную ссылку в списке привязок
данной секции. Если таких нет, то алгоритм завершен;
2)найти символ в COFF-таблице, на который ссылается данная
привязка;
3)если символ является внешним(тип EXTERNAL), то перейти к
пункту 9;
4)если данный символ имеет тип STATIC, то данная ссылка является
разрешимой;
5)найти секцию PE, соответствующую секции с номером
SectionNumber COFF-Файла;
6)сосчитать неизвестный адрес по следующей формуле:
Искомый_адрес = Адрес_загрузки(см.шаг 1) +
RVA_секции_из_пункта_5_алгоритма +
Поле_Value_из_COFF-символа

22. Шаг 4 – Разрешение статических и внешних ссылок

7)
в секции PE-файла, соответствующей данной секции COFFфайла, по смещению Address из привязки вставить
значение, полученное в пункте 6 алгоритма;
8)
9)
перейти к пункту 1.
сосчитать неизвестный адрес по следующей формуле:
Искомый_адрес = Адрес_загрузки + RVA элемента массива
FirstThunk описывающего данную функцию
10)в секции PE-файла, соответствующей данной секции COFFфайла, по смещению Address из привязки вставить
значение, полученное в пункте 5 алгоритма;
11)перейти к пункту 1.

23. Шаг 4 – Разрешение статических и внешних ссылок

24. Шаг 5 – Компановка

* Если все шаги сделаны правильно, то после компоновки
(CTRL+F9) в каталоге проекта появится исполняемый файл,
работоспособность которого необходимо проверить, запустив
его на выполнение (F9).
* Запустить программу в дебаггере.

Common Object File Format ( COFF ) представляет собой формат для исполняемого , объектного кода , и разделяемые библиотеки компьютерных файлов используется на Unix системах. Он был представлен в Unix System V , заменил ранее использовавшийся формат a.out и лег в основу расширенных спецификаций, таких как XCOFF и ECOFF , прежде чем был в значительной степени заменен ELF , представленным в SVR4 . COFF и его варианты продолжают использоваться в некоторых Unix-подобных системах, в Microsoft Windows ( Portable Executable ), в средах UEFI и в некоторых встроенных системах разработки.

СОДЕРЖАНИЕ

История

Исходный формат объектного файла Unix a.out не может адекватно поддерживать совместно используемые библиотеки , идентификацию внешнего формата или явную привязку адресов. Поскольку разработка Unix-подобных систем продолжалась как внутри, так и за пределами AT&T, появлялись различные решения этих и других проблем.

COFF был представлен в 1983 году в UNIX System V компании AT&T для 32-разрядных платформ, отличных от VAX, таких как 3B20 . Усовершенствования по сравнению с существующим форматом AT&T a.out включают произвольные разделы, явные объявления процессоров и явную привязку адресов.

Однако дизайн COFF был слишком ограничен и не полностью определен: существовал предел на максимальное количество разделов, ограничение на длину имен разделов, включенные исходные файлы, а символьная отладочная информация была неспособна поддерживать языки реального мира, такие как как C , тем более новые языки, такие как C ++ , или новые процессоры. В результате все реализации COFF в реальном мире неизбежно нарушали стандарт. Это привело к многочисленным расширениям COFF. IBM использовала формат XCOFF в AIX ; DEC , SGI и другие использовали ECOFF ; и многочисленные порты SysV и цепочки инструментов, предназначенные для разработки встраиваемых систем, создают свои собственные несовместимые варианты.

С выпуском SVR4 AT&T заменила COFF на ELF .

В то время как расширенные версии COFF продолжают использоваться для некоторых Unix-подобных платформах, в первую очередь в встраиваемых системах, возможно , наиболее широкое применение формата COFF сегодня находится в Microsoft «s Portable Executable формат (PE). Формат PE, разработанный для Windows NT (иногда обозначаемый как PE / COFF), использует заголовок COFF для объектных файлов и как компонент заголовка PE для исполняемых файлов.

Функции

Основным улучшением COFF по сравнению с a.out было введение нескольких именованных разделов в объектный файл. В разных объектных файлах может быть разное количество и типы разделов.

Символьная отладочная информация

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

Символьные имена хранятся в таблице символов COFF. Каждая запись таблицы символов включает имя, класс хранения, тип, значение и номер раздела. Краткие имена (8 символов или меньше) хранятся непосредственно в таблице символов; более длинные имена сохраняются как смещение в таблице строк в конце объекта COFF.

Классы хранения описывают типовой объект, который представляет символ, и могут включать внешние переменные (C_EXT), автоматические (стековые) переменные (C_AUTO), регистровые переменные (C_REG), функции (C_FCN) и многие другие. Тип символа описывает интерпретацию значения объекта символа и включает значения для всех типов данных C.

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

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

Относительный виртуальный адрес

Когда создается файл COFF, обычно неизвестно, куда он будет загружен. Виртуальный адрес , где будет загружен первый байт файла изображения, называется базовый адрес . Остальная часть файла не обязательно загружается в непрерывный блок, а в разные разделы .

Относительные виртуальные адреса (RVA) не следует путать со стандартными виртуальными адресами. Относительный виртуальный адрес является виртуальным адресом объекта из файла , когда он будет загружен в память, минус базовый адрес файл изображения. Если бы файл отображался буквально с диска в память, RVA было бы таким же, как у смещения в файле, но на самом деле это довольно необычно.

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

Проблемы

Заголовок файла COFF хранит дату и время создания объектного файла в виде 32-битного двоичного целого числа, представляющего количество секунд, прошедших с эпохи Unix , 1 января 1970 г., 00:00:00 UTC. Даты, наступившие после 19 января 2038 года, не могут быть сохранены в этом формате.

На рис. 2.5 приведена структура исполняемого файла формата COFF. Исполняемый файл содержит два основных заголовка — заголовок COFF и стандартный заголовок системы UNIX — a.out. Далее следуют заголовки разделов и сами разделы файла, в которых хранятся инструкции и данные программы. Наконец, в файле также хранится символьная информация, необходимая для отладки.


Рис. 2.5. Структура исполняемого файла в формате COFF

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

Символьная информация состоит из таблицы символов (symbol table) и таблицы строк (string table). В первой таблице хранятся символы, их адреса и типы. Например, мы можем определить, что символ locptr является указателем и его виртуальный адрес равен 0x7feh0. Далее, используя этот адрес, мы можем выяснить значение символа для выполняющегося процесса. Записи таблицы символов имеют фиксированный размер. Если длина символа превышает восемь знаков, его имя хранится во второй таблице — таблице строк. Обычно обе эти таблицы присутствуют в объектных и исполняемых файлах, если они явно не удалены, например, командой strip(1).

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

Таблица 2.5. Поля заголовка COFF-файла

Поле Описание f_magic Аппаратная платформа, для которой создан файл f_nscns Количество разделов в файле f_timdat Время и дата создания файла f_symptr Расположение таблицы символов в файле f_nsyms Количество записей в таблице символов f_opthdr Размер заголовка f_flags Флаги, указывающие на тип файла, присутствие символьной информации и т.д.

Заголовок COFF присутствует в исполняемых файлах, промежуточных объектных файлах и библиотечных архивах. Каждый исполняемый файл кроме заголовка COFF содержит заголовок a.out, хранящий информацию, необходимую ядру системы для запуска программы[16] (табл. 2.6).

Таблица 2.6. Поля заголовка a.out

Поле Описание vstamp Номер версии заголовка tsize Размер раздела инструкций (text) dsize Размер инициализированных данных (data) bsize Размер неинициализированных данных (bss) entry Точка входа программы text_start Адрес в начала сегмента инструкций виртуальной памяти data_start Адрес в начала сегмента данных виртуальной памяти

Все файлы формата COFF имеют один или более разделов, каждый из которых описывается своим заголовком. В заголовке хранится имя раздела (.text, .data, .bss или любое другое, установленное соответствующей директивой ассемблера), размер раздела, его расположение в файле и виртуальной адрес после запуска программы на выполнение. Заголовки разделов следуют сразу за заголовком файла.

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

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

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

Данный текст является ознакомительным фрагментом.

Продолжение на ЛитРес

Формат ELF

Формат ELF Формат ELF имеет файлы нескольких типов, которые до сих пор мы называли по-разному, например, исполняемый файл или объектный файл. Тем не менее стандарт ELF различает следующие типы:1. Перемещаемый файл (relocatable file), хранящий инструкции и данные, которые могут быть

3.3.1. Формат RSS

Формат чисел

Формат чисел Наконец-то добрались до формата чисел. Я уже не раз о нем упоминала, теперь разложу все по полочкам (хотя общий смысл вы уже могли понять).Числа в Excel могут отображаться в различных форматах. В этом разделе мы поговорим о том, какие существуют форматы чисел и как

5.2.3. Формат Cookie-Jar

5.2.3. Формат Cookie-Jar Формат cookie-jar используется программой fortune(1) для собственной базы данных случайных цитат. Он подходит для записей, которые представляют собой просто блоки неструктурированного текста. В качестве разделителя записей в данном формате применяется символ

5.2.2. Формат RFC 822

5.2.6. Формат Windows INI

5.2.6. Формат Windows INI Многие программы в Microsoft Windows используют текстовый формат данных, подобный фрагменту, приведенному в примере 5.6. В данном примере необязательные ресурсы с именами account, directory, numeric_id и developer связываются с именованными проектами python, sng, fetchmail и py-howto. В записи

Формат проекта

Формат проекта При создании нового фильма в Pinnacle Studio создается проект, в файлах которого (нас не сильно должно волновать, какие это файлы) сохраняются настройки, данные используемых в проекте видео– и аудиофрагментов, просчитанный материал и многое другое.Pinnacle Studio

Формат PDF

Формат PDF PDF расшифровывается как Portable Document Format (портативный формат документа). Этот формат был создан специально для ликвидации проблем с отображением информации в файлах. Его преимущество состоит в том, что, во-первых, документ, сохраненный в формате PDF, будет одинаково

Формат DJVU

Формат DJVU Несколько лет назад появился новый формат хранения оцифрованных текстов – формат DJVU (дежавю). Технология была разработана в 1996 году компанией AT&amp;T Labs. При создании формата была изначально поставлена задача достичь наилучшего сжатия при минимальных потерях в

Формат WAV

Формат WAV Формат WAV (от английского wave — волна) был создан фирмой Microsoft еще в начале 90-х годов прошлого века в качестве стандартного формата хранения звуковых данных в операционной системе Windows. Сейчас используется также для записи звука, предназначенного для последующей

Формат MP3

Формат MP3 Формат MP3 был создан для распространения музыкальных файлов, сжатых кодеком MPEG 1 level 3. В настоящее время — самый популярный формат распространения музыки через Интернет, и не только. Поддерживается абсолютно всеми программами записи и обработки звука, за

Формат MP3

Формат MP3 Метод сжатия звука, а также формат сжатых звуковых файлов, предложенный международной организацией MPEG (Moving Pictures Experts Group – Экспертная группа по видеозаписи), основан на перцептуальном кодировании звука. Работы по созданию эффективных алгоритмов кодирования

Недавно я поддерживал старый проект, написанный на VС++ 6.0. В коде используется так много уникальных характеристик этого компилятора, что перенос его на более современный стандартный компилятор оказался задачей для herculean.

предупреждение LNK4033: преобразование формата объекта из OMF в COFF

Библиотека работает так, как ожидалось, но мне интересно, какие различия между этими двоичными форматами, или если я должен ожидать от этого преобразования что-то уродливое.

Отключен ответ "FAQ MetaWINDOW - OMF vs COFF Object File Formats.htm"

С самого начала цивилизации ПК до тех пор, пока не появились инструменты программирования Microsoft Win32, почти все компиляторы ПК создавали объектные файлы с использованием стандарта Intel Object Module Format (OMF). Позже Intel представила 386 процессоров и 32-битный защищенный режим, после чего они также расширили спецификацию OMF для 32-разрядных версий, что привело к "OMF-386", который стал стандартом для большинства сред с защищенным режимом ПК. Примерно в это же время оригинальная команда разработчиков Windows NT также разрабатывала код не только для процессоров Intel, но и для поддержки процессоров других производителей. Команда Microsoft NT выбрала более переносимый формат объектного модуля, известный как формат общих файлов объектов (COFF), полученный из официального формата объектного кода для UNIX System V. Объектные модули COFF впоследствии стали стандартом дефакто для всех инструментов разработки Microsoft Win32 и получили преимущество в том, чтобы быть намного ближе в формате Portable Executable files - собственный исполняемый формат для Win32 (у компоновщика в формате COFF гораздо меньше работы для создания 32-разрядной EXE или DLL из файла COFF, чем из файла формата OMF).

Так же, как и объектные файлы формата OMF и COFF (.obj's), есть также файлы библиотеки формата OMF и COFF (.lib). К счастью, библиотеки - это всего лишь коллекция объектных файлов, а также информация заголовка, которая позволяет компоновщику определять, какие файлы объектов использовать из библиотеки. Однако, чтобы сделать все сложнее, и OMF, и COFF используют те же расширения имен файлов,.obj и .lib, чтобы ссылаться на два разных типа форматов файлов объектов и библиотек (из-за этого вы не можете просто посмотреть на расширение имени файла чтобы указать, является ли объектный модуль или файл библиотеки OMF или COFF).

Проблема со смешением объектных файлов и файлов библиотек от разных поставщиков компиляторов заключается в том, что некоторые поставщики поддерживают COFF, другие производители используют OMF, а некоторые из них могут обрабатывать оба. Borland, например, по-прежнему использует объектные файлы и библиотеки OMF, в то время как 32-битные компиляторы Microsoft создают файлы формата COFF. Watcom C/С++ v11.0, похоже, предпочитает COFF при компиляции и связывании приложений Windows, но генерирует объектные файлы OMF для использования с DOS-расширителем DOS4GW с 32-битным защищенным режимом. Наряду с этим, Microsoft MASM 6.13 создает файлы OMF по умолчанию, но вместо этого переключатель /coff может испускать объектные файлы COFF.

Когда приходит время связывать файлы с различными форматами, разные линкеры делают разные вещи. Например, компоновщик Microsoft Visual C/С++ предназначен для объектных файлов и библиотек формата COFF, но при необходимости попытается преобразовать объектные файлы OMF в файлы COFF. Это работает в некоторых случаях, но, к сожалению, Microsoft LINK не поддерживает все типы записей OMF, поэтому во многих ситуациях компоновщик может по-прежнему терпеть неудачу при предоставлении объектных файлов формата OMF. Кроме того, хотя Microsoft LINK пытается поддерживать объектные файлы OMF, он откажется обрабатывать любые библиотеки формата OMF. Другие линкеры, такие как Borland TLINK, предназначены для объектных файлов OMF и аналогичным образом отказываются работать с объектами или файлами формата COFF. Некоторые разработчики DOS и встроенные системные поставщики, такие как Phar Lap, предоставляют свои собственные линкеры, которые поддерживают как OMF, так и COFF, что дает вам выбор.

Читайте также: