2014-09-14 2 views
1

Я прочитал PE and COFF specification, Matt Pietrek's "Peering Inside the PE: A Tour of the Win32 Portable Executable File Format" и "An In-Depth Look into the Win32 Portable Executable File Format", а также несколько других источников по этому вопросу.
Мне удалось прочитать таблицу разделов COFF, а также таблицу символов COFF из объектного файла, сгенерированного MinGW GCC 4.7 (я собирал статическую библиотеку в режиме отладки).
Моя конечная цель - получить доступ ко всем функциям, определенным в данном объектном файле (COFF), и прочитать все байты, составляющие их машинный код.Считать код функции из COFF-файла объекта

Вопрос 1: Как рассчитать начальный адрес одной функции внутри файла COFF? Я полагаю, что мне нужно как-то использовать поле «Значение» в символьной записи в качестве смещения в раздел, указанный в «SectionNumber».

Вопрос 2: Как узнать длину любой заданной функции (сколько байтов мне нужно было бы прочитать)?

Вопрос 3: Согласно PE & спецификации Microsoft, COFF должна быть вспомогательной таблицы символов записи после каждой записи символа, который определяет функцию. Почему в моем объектном файле (извлеченном из файла .a, который был скомпилирован в режиме отладки) из трех определенных функций только один имеет такую ​​вспомогательную запись? И это также полностью заполнено нулями?

ответ

1

Q1: Да, это кажется разумным.

Q2: Наверное, сложно. Зависит от архитектуры процессора. Нет никакой гарантии, что есть какая-либо информация о функции, предоставляющая длину функции вообще - в частности, нет ничего доступного для x86 (32-разрядная версия), а информация о длине иногда доступна только на других архитектурах [когда требуется отменить последующие исключения].

Лучшим способом, вероятно, является просто загрузить таблицу символов и найти, где находится функция NEXT в адресном порядке, а затем предположить, что длина начинается с начала функции до байта непосредственно перед следующей функцией. Для последней функции, очевидно, «до конца раздела». Много лет назад я использовал метод распознавания возвращаемых инструкций для определения длины функций, но современные компиляторы часто генерируют код, который имеет более одной команды возврата, помещает if/else код после возврата с возвратом к основному коду функции , и т. д., поэтому он не может быть надежным методом [и, конечно, если кто-то делает x = $0xc3;, то 0xc3 будет выглядеть как команда возврата, но это фактически данные ...;)

Q3: Вспомогательные записи полностью необязательны:

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

Если имеются записи вспомогательных таблиц символов, они указываются со смещением 17 в записи таблицы символов.

Это может быть запутанным, если вы читаете только позже текст:

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

Я думаю, что это следует рассматривать как «Если есть вспомогательная запись в виде таблицы символов, это происходит сразу же после стандартной записи таблицы».

+0

Что касается раздела 4.5.1 в спецификации PE/COFF: «Записи символа определения функции сопровождаются дополнительной записью в формате, описанном в следующей таблице». ? – AndiNo

+0

Также говорит: «Запись таблицы символов знаменует начало определения функции, если она имеет все следующее: класс хранения EXTERNAL (2), значение типа, указывающее, что это функция (0x20) и номер раздела, который больше нуля », что заставляет меня думать, что« не у всех функций есть это ». –

Смежные вопросы