Есть ли какой-нибудь стандартный способ встраивания ресурсов в исполняемый образ 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 из каталога, в котором вся ваша программа хранит файлы ресурсов в исполняемом файле оболочки. И когда пользователь запускает исполняемый файл, он извлекает файлы и запускает произвольную команду (может быть основным исполняемым файлом программы). Недостатком является то, что каждый раз, когда пользователь запускает исполняемый файл, ему требуется время для загрузки / извлечения файлов, прежде чем запускать настоящую программу.