通过Windows API将二进制资源嵌入到PE映像(EXE,DLL)中非常容易(请参阅http://msdn.microsoft.com/en-us/library/ms648008(v=VS.85).aspx)。
Linux中是否有类似的标准API?
或者某种事实上的资源嵌入方法?
目标是将一些静态二进制和/或文本数据嵌入到可执行文件中,例如,图片,HTML等..所以程序二进制分发就像制作一个文件一样简单? (假设所有库依赖项都正常)
更新:
按照 bdk 的建议,我尝试了Embedding binary blobs using 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>
答案 0 :(得分:27)
让自己成为汇编程序文件,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进行编译 现在可以在C程序中使用以下命令访问blob:
extern uint8_t blob[];
extern int blob_size;
使用bin2c转换器通常可以正常工作,但如果blob很大,则incbin解决方案要快得多,并且使用的内存要少得多(编译时)
答案 1 :(得分:7)
objcopy --add-section允许您将任意文件添加为ELF可执行文件中的一个部分。 (objcopy手册页)。然而,这只是解决方案的一半,因为除了通过使用ELF库加载和解析ELF二进制文件之外,我还没有找到从C程序内部访问此数据的方法。
修改其他信息:
如果你有一个名为MyProgram的编译程序和一个你希望嵌入到MyProgram中的资源文件MyResource.dat,你可以像这样使用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 在我的研究中,我遇到了这个问题:Embedding binary blobs using gcc mingw
哪个适用于gcc以及mingw,并显示了一种使用ld而不是objcopy来添加数据并能够将其作为符号访问的方法。看起来很有希望
答案 2 :(得分:4)
不确定。尝试类似Bin2Hex converter的内容。将二进制数据转换为C ++ char数组,然后将其作为常量变量嵌入到代码中。
答案 3 :(得分:1)
它将从一个目录中创建一个tar存档,其中所有程序,资源文件都放入一个可执行的shell文件中。 当用户运行可执行文件时,它将提取文件并运行任意命令(可能是程序主可执行文件)。 有一个缺点,即每次用户启动可执行文件时,在启动真实程序之前,首先加载/提取文件需要时间。