是否有将资源嵌入 Linux 可执行映像的标准方法?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5479691/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-05 03:27:20  来源:igfitidea点击:

Is there any standard way of embedding resources into Linux executable image?

c++linuxembedded-resource

提问by Andrey

It is quite easy to embed binary resources into PE images (EXE, DLL) via Windows API (refer to http://msdn.microsoft.com/en-us/library/ms648008(v=VS.85).aspx).

通过 Windows API(请参阅http://msdn.microsoft.com/en-us/library/ms648008(v=VS.85).aspx)将二进制资源嵌入到 PE 图像(EXE、DLL)中非常容易。

Is there any similar standard API in Linux?

Linux 中是否有类似的标准 API?

or maybe some kind of de-facto approach to resource embedding?

或者也许是某种事实上的资源嵌入方法?

The goal is to embed some static binary and/or textual data into executable, e.g. pictures, HTMLs, etc.. so that program binary distribution is as simple as making one file copy? (assuming all library dependencies are ok)

目标是将一些静态二进制和/或文本数据嵌入到可执行文件中,例如图片、HTML 等。这样程序二进制分发就像制作一个文件副本一样简单?(假设所有库依赖项都正常

Update:

更新:

following bdk's suggestion, I've tried solution described in Embedding binary blobs using gcc mingwand it worked for me. Though, there were some issues that are worth mentioning: my project (in Code::Blocks) consists of a number of C++ files and adding binary data into any of corresponding object files rendered them useless breaking the build - objdump -xwould show that most of the symbols have gone after embedding (and I didn't find how to fix it). To overcome this issue I added an empty dummy .cpp file into the project with the only purpose of providing an object file to play with and wrote the following custom build step for that file which did the job nicely (example uses Code::Blocks macros):

按照bdk的建议,我尝试了使用 gcc mingw 嵌入二进制 blob 中描述的解决方案,它对有用。不过,有一些问题值得一提:我的项目(在 Code::Blocks 中)由许多 C++ 文件组成,并将二进制数据添加到任何相应的目标文件中,使它们变得无用,破坏了构建 -objdump -x将表明大部分符号在嵌入后消失了(我没有找到如何修复它)。为了解决这个问题,我在项目中添加了一个空的虚拟 .cpp 文件,其唯一目的是提供一个对象文件来使用,并为该文件编写了以下自定义构建步骤,该步骤很好地完成了工作(示例使用 Code::Blocks 宏):

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

采纳答案by Simon Edlund

Make yourself an assembler file, blob.S:

使自己成为一个汇编程序文件 blob.S:

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

Compile with gcc -c blob.S -o blob.o The blob can now be accessed from within your C program with:

使用 gcc -c blob.S -o blob.o 编译 现在可以从 C 程序中访问 blob:

extern uint8_t blob[];
extern int blob_size;

Using a bin2c converter usually works fine, but if the blob is large, the incbin solution is much faster, and uses much less memory (compile time)

使用 bin2c 转换器通常可以正常工作,但如果 blob 很大,则 incbin 解决方案要快得多,并且使用的内存要少得多(编译时间)

回答by littleadv

Sure. Try something like Bin2Hex converter. Convert the binary data into a C++ char array, and then embed it into your code as a constant variable.

当然。试试像Bin2Hex 转换器这样的东西。将二进制数据转换为 C++ char 数组,然后将其作为常量变量嵌入到您的代码中。

回答by bdk

objcopy --add-section allows you to add an arbitrary file as a section in an ELF executable. (objcopy man page). However this is only half a solution, as I have not yet found a way to access this data from inside a C Program other than by loading and parsing the ELF Binary using an ELF Library.

objcopy --add-section 允许您将任意文件添加为 ELF 可执行文件中的一个部分。(objcopy 手册页)。然而,这只是解决方案的一半,因为除了使用 ELF 库加载和解析 ELF 二进制文件之外,我还没有找到从 C 程序内部访问这些数据的方法。

EditAdditional Information:

编辑附加信息:

If you have a compiled program called MyProgram and a resource file MyResource.dat which you want embedded into MyProgram, you can use the objcopy command like this:

如果您有一个名为 MyProgram 的已编译程序和一个要嵌入 MyProgram 的资源文件 MyResource.dat,则可以使用 objcopy 命令,如下所示:

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

Now if you look at your program using the command objdump -x MyProgram

现在,如果您使用命令 objdump -x MyProgram 查看您的程序

You will see a section called MyResource which contains the contents of MyResource.dat. The file is now embedded inside of your executable.

您将看到一个名为 MyResource 的部分,其中包含 MyResource.dat 的内容。该文件现在嵌入在您的可执行文件中。

The trick now, is how do you access the data from inside your program. My instinct tells me that the loader should place the file into memory somewhere and you should be able to get a pointer to it, however I'm not sure how to do that simply. Ideally I'd want to be able to dlopen my exeutable and dlsym the section, but that doesn't work because its a section and not a symbol.

现在的诀窍是如何从程序内部访问数据。我的直觉告诉我,加载程序应该将文件放入内存中的某个地方,您应该能够获得指向它的指针,但是我不确定如何简单地做到这一点。理想情况下,我希望能够 dlopen 我的可执行文件和 dlsym 部分,但这不起作用,因为它是一个部分而不是一个符号。

The only alternative I know of to access the section from inside the program is to use the libelf library or something similar which is a little like using a sledgehammer to tap in a nail. You can use it in your application to load itself as an ELF Resource and retrieve the sections. Documentation is sparse, but here's an example

我知道从程序内部访问该部分的唯一替代方法是使用 libelf 库或类似的东西,有点像使用大锤敲入钉子。您可以在应用程序中使用它来将自身加载为 ELF 资源并检索部分。文档很少,但这里有一个例子

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

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

I'd love if someone could chime in with an easier way to access the data from --add-section.

如果有人能以更简单的方式从 --add-section 访问数据,我会很高兴。

Edit 2In My research I encoutered this question: Embedding binary blobs using gcc mingw

编辑 2在我的研究中,我遇到了这个问题:Embedding binary blob using gcc mingw

Which should work for gcc as well as mingw and shows a way to use ld instead of objcopy to add the data and be able to access it as a symbol. Looks promising

这应该适用于 gcc 和 mingw,并显示了一种使用 ld 而不是 objcopy 来添加数据并能够将其作为符号访问的方法。看起来很有希望

回答by technomage

how about makeself

让自己怎么

it will make a tar archive from a directory where all your program,resources files into an executable shell file. And when the user run the executable file, it will extract the files and run an arbitrary command (could be the program main executable). There's a drawback, that every time user launch the executable, it will takes time to load/extract the files first, before launching the real program.

它会将所有程序资源文件的目录中的 tar 归档文件转换为可执行的 shell 文件。当用户运行可执行文件时,它会提取文件并运行任意命令(可能是程序主可执行文件)。有一个缺点,每次用户启动可执行文件时,在启动真正的程序之前,首先加载/提取文件需要时间。