访问附加到ELF二进制文件的数据

时间:2011-04-14 09:00:14

标签: linux gcc build elf

我有一个静态ELF二进制文件,它从zip文件中读取数据。为了简化分发,我想将zipfile附加到二进制文件中,如下所示:

$ cat mydata.zip >> mybinary

我知道这样做不会损害mybinary,但我不知道如何访问mydata.zip的内容。可能吗?如果是这样,怎么样?

在过去,我使用附加数据然后附加数据长度的技巧,这样我所要做的就是打开二进制文件,读取流的最后一个int,然后回退那个长度然后开始解压缩,但由于各种原因在这里不起作用(例如,我不能保证在需要zipfile时文件仍然在光盘上。)

如果解决方案适用于OS X和MinGW,

超级双倍加分。

2 个答案:

答案 0 :(得分:2)

假设在应用程序执行开始时您可以访问该文件,然后打开它的句柄应该可以防止操作系统在磁盘上删除该文件,直到文件的最后一个引用被关闭为止。这样您就可以毫无顾虑地使用该文件句柄来查找文件中的内容。

创建一个全局变量:

int app_fd;

大多数这些过程都是相同的,在主程序中,只需发出:

app_fd = open(argv[0], O_RDONLY);

在执行开始时。当谈到执行中需要访问zip文件时,只需使用文件描述符,而不是文件名。

在运行时,如果您对应用程序的原始内容没有某种形式的句柄,那么您可能无法访问zip文件的内容。这是因为加载器仅映射到预期的文件部分。二进制文件末尾的内容将被视为垃圾而未映射。

要完成zip文件到内存的映射,您需要遵循不同的方法。您需要将.zip嵌入到二进制文件的ELF(linux)/ COFF(Windows)/ Mach-O(Mac OS X)部分中,该部分具有设置的属性,以确保它映射到应用程序中(这需要应用程序中的大量前期工作,以及处理中的更多后期工作)。这不是微不足道的,可能需要进行相当多的编码才能使每个平台都正确。

另外,在应用程序运行时从Windows系统中删除应用程序并不是一件容易的事情(我认为如果它位于NTFS上,你可以移动它)。

答案 1 :(得分:0)

如果连接ELF文件和zip文件,生成的文件 (AFAIU)是有效的ELF文件和有效的zip文件。

演示:

$ gcc hello.c -o hello
$ ./hello
Hello
$ (cat hello ; test.zip) > hello2
$ chmod u+x hello2
$ ./hello2
Hello
$ unzip ./hello2
Archive:  ./hello2
warning [./hello2]:  6704 extra bytes at beginning or within zipfile
(attempting to process anyway)
  Length      Date    Time    Name
---------  ---------- -----   ----
   119458  1999-11-24 13:08   hello.txt

许多库(zlib,zzip)(错误地?)不能将这样的文件识别为有效的zip文件,但是libminizip可以这样做:

#include <stdio.h>
#include <errno.h>
#include <minizip/unzip.h>

int main(int argc, char** argv)
{
  unzFile uf = unzOpen(argv[0]);
  unzGoToFirstFile(uf);
  char filename_inzip[256] = {0};
  unz_file_info64 file_info = {0};
  const char *string_method = NULL; 
  unzGetCurrentFileInfo64(uf, &file_info, filename_inzip, sizeof(filename_inzip), NULL, 0, NULL, 0);
  printf("%s\n", filename_inzip);    
  return 0;
}

给出:

$ ./unzipme2
foo.txt