Считать код функции из объектного файла COFF

Я прочитал Спецификация PE и COFF, Мэтт Пьетрек «Вглядываясь в PE: обзор формата исполняемых файлов Win32» а также «Углубленный взгляд на портативный формат исполняемых файлов Win32» а также несколько других источников на эту тему.
Мне удалось прочитать таблицу разделов COFF, а также таблицу символов COFF из объектного файла, сгенерированного MinGW GCC 4.7 (я собирал статическую библиотеку в режиме отладки).
Моя конечная цель — получить доступ ко всем функциям, определенным в данном объектном файле (COFF), и прочитать все байты, составляющие их машинный код.

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

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

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

1

Решение

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

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

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

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

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

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

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

Записи таблицы вспомогательных символов всегда следуют и применяются к некоторым
стандартная запись таблицы символов.

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

1

Другие решения


По вопросам рекламы [email protected]