Как «связать» объектный файл с исполняемым / скомпилированным двоичным файлом?

Проблема

Я хочу вставить объектный файл в существующий двоичный файл. В качестве конкретного примера рассмотрим источник Hello.c :

#include 

int main(void)
{
    return EXIT_SUCCESS;
}

Он может быть скомпилирован в исполняемый файл с именем Hello через gcc -std = gnu99 -Wall Hello.c -o Привет . Кроме того, теперь рассмотрим Embed.c :

func1(void)
{
}

Из него можно создать объектный файл Embed.o с помощью gcc -c Embed.c . У меня вопрос, как вообще вставить Embed.o в Привет таким образом, что необходимые перемещения выполнены и соответствующие внутренние таблицы ELF (например, таблица символов, PLT и т. д.) исправлены правильно?


Допущения

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


Текущие попытки / идеи

  • Используйте libbfd , чтобы скопировать разделы из объектного файла в двоичный файл. Прогресс, которого я добился в этом, заключается в том, что я могу создать новый объект с разделами из исходного двоичного файла и разделами из объектного файла. Проблема в том, что, поскольку объектный файл можно перемещать, его разделы нельзя правильно скопировать в выходной файл без предварительного перемещения.
  • Преобразуйте двоичный файл обратно в объектный файл и повторно установите связь с ld . До сих пор я пытался использовать objcopy для преобразования objcopy --input elf64-x86-64 --output elf64-x86-64 Hello Hello.o . Очевидно, это не работает так, как я предполагал, поскольку ld -o Hello2 Embed.o Hello.o затем приведет к ld: error: Hello.o: неподдерживаемый тип файла ELF 2 . Я думаю, этого следовало ожидать, поскольку Hello не является объектным файлом.
  • Найти существующий инструмент, который выполняет такого рода вставку?

Обоснование (Необязательное чтение)

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

  1. Внедрение объектного файла (содержащего определенные пользователем процедуры) в двоичный файл. Это обязательный шаг, и его нельзя обойти с помощью альтернатив, таких как внедрение общего объекта.
  2. Выполнение статического анализа нового двоичного файла и его использование для статического обхода подпрограмм от исходного кода к новому добавленному коду.

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

12
задан Mike Kwan 29 February 2012 в 21:48
поделиться