Есть ли какой-нибудь стандартный способ встраивания ресурсов в исполняемый образ Linux?

Встраивать бинарные ресурсы в образы PE (EXE, DLL) с помощью Windows API довольно просто (см. http://msdn.microsoft.com/en-us/library/ms648008(v=VS.85).aspx).

Есть ли подобный стандартный API в Linux?

или, может быть, какой-то де-факто подход к внедрению ресурсов?

Цель состоит в том, чтобы встроить некоторые статические двоичные и / или текстовые данные в исполняемый файл, например изображения, HTML и т. Д., Чтобы двоичное распространение программы было так же просто, как сделать копию одного файла? (при условии, что все библиотечные зависимости в порядке)

Обновить:

Следуя совету bdk, я попробовал решение, описанное в разделе Встраивание двоичных двоичных объектов с использованием gcc mingw, и оно сработало для меня. Тем не менее, есть некоторые проблемы, о которых стоит упомянуть: мой проект (в Code::Blocks) состоит из нескольких файлов C++, и добавление двоичных данных в любой из соответствующих объектных файлов делает их бесполезными, нарушая сборку - objdump -x показал бы, что большинство символов ушли после встраивания (а я не нашел, как это исправить). Чтобы преодолеть эту проблему, я добавил в проект пустой фиктивный файл.cpp с единственной целью - предоставить объектный файл для воспроизведения и написал следующий пользовательский шаг сборки для этого файла, который прекрасно справился с задачей (пример использует макросы Code::Blocks):

$compiler $options $includes -c $file -o $object
ld -Ur -b binary -o $object <binary payload path>

4 ответа

Решение

Сделай себе ассемблерный файл, blob.S:

    .global blob
    .global blob_size
    .section .rodata
blob:
    .incbin "blob.bin"
1:
blob_size:
    .int 1b - blob

Скомпилируйте с помощью gcc -c blob.S -o blob.o К blob теперь можно получить доступ из вашей программы на C:

extern uint8_t blob[];
extern int blob_size;

Использование конвертера bin2c обычно работает нормально, но если большой двоичный объект большой, решение incbin намного быстрее и использует намного меньше памяти (время компиляции)

objcopy --add-section позволяет вам добавить произвольный файл как раздел в исполняемом файле ELF. (страница руководства objcopy). Однако это только половина решения, так как я еще не нашел способ получить доступ к этим данным из C-программы, кроме как путем загрузки и анализа двоичного файла ELF с использованием библиотеки ELF.

Изменить дополнительную информацию:

Если у вас есть скомпилированная программа MyProgram и файл ресурсов MyResource.dat, который вы хотите встроить в MyProgram, вы можете использовать команду objcopy, например:

objcopy MyProgram --add-section MyResource=MyResource.dat

Теперь, если вы посмотрите на свою программу с помощью команды objdump -x MyProgram

Вы увидите раздел MyResource, который содержит содержимое MyResource.dat. Файл теперь встроен в ваш исполняемый файл.

Хитрость в том, как вы получаете доступ к данным внутри вашей программы. Мой инстинкт подсказывает мне, что загрузчик должен поместить файл в память где-нибудь, и вы должны иметь возможность получить указатель на него, однако я не уверен, как это сделать просто. В идеале я хотел бы иметь возможность отделить свой исполняемый файл и выполнить dlsym раздел, но это не работает, потому что это раздел, а не символ.

Единственная известная мне альтернатива для доступа к разделу внутри программы - использовать библиотеку libelf или что-то подобное, что немного похоже на использование кувалды для забивания гвоздя. Вы можете использовать его в своем приложении, чтобы загрузить себя в качестве ресурса ELF и получить разделы. Документация скудная, но вот пример

http://em386.blogspot.com/2007/03/quick-libelf-guide.html

Я был бы рад, если бы кто-то мог подключиться с более простым способом доступа к данным из --add-section.

Редактировать 2 В моем исследовании я задал вопрос: встраивание двоичных двоичных объектов с использованием gcc mingw

Который должен работать как для gcc, так и для mingw, и показывает способ использования ld вместо objcopy для добавления данных и возможности доступа к ним как к символу. Выглядит многообещающе

Конечно. Попробуйте что-то вроде конвертера Bin2Hex. Преобразуйте двоичные данные в массив символов C++, а затем вставьте их в свой код в качестве постоянной переменной.

Как насчет себя

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

Другие вопросы по тегам