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

Linux 访问附加到ELF二进制文件的数据,linux,gcc,build,elf,Linux,Gcc,Build,Elf,我有一个从zipfile读取数据的静态ELF二进制文件。为了简化分发,我想将zipfile附加到二进制文件中,如下所示: $ cat mydata.zip >> mybinary 我知道这样做不会损坏mybinary,但我不知道如何访问mydata.zip的内容。可能吗?如果是,怎么做 在过去,我使用了追加数据然后追加数据长度的技巧,因此我所要做的就是打开二进制文件,读取流的最后一个int,倒带该长度然后开始解压缩,但由于各种原因,这在这里不起作用(例如,当需要zipfile时,我

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

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

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


如果解决方案可以跨OS X和MinGW运行,则会产生额外的doubleplus点数。

假设在应用程序开始执行时您可以访问该文件,那么打开该文件的句柄应该可以防止操作系统在关闭对该文件的最后一次引用之前删除磁盘上的文件您可以使用该文件句柄毫无顾虑地查找文件中的内容

创建全局变量:

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上,则可以移动它)。

如果将ELF文件和zip文件连接起来,则生成的文件是(AFAIU)一个有效的ELF文件和一个有效的zip文件

演示:

许多库(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;
}

.exe不在磁盘上的原因是它正在从打包机/保护器运行时提取?可能是的。我当时无法控制。打开(argv[0])技巧是我开始的,所以如果你愿意的话,这是我的默认设置。一旦你了解了objcopy设置,将zip文件映射到内存是相对简单的,但它对应用程序源的侵入性比理想的要大,这就是为什么我要寻找第三种方法…正如我在最后一段第二段中提到的,它将是一种侵入性的如果您无法通过文件描述符或名称访问基础文件,则依赖于平台。但是,只要编写一次,从文件访问节的例程就可以作为库调用重用。。。
#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