C语言 如何读取嵌入到程序自身ELF中的数据?

agyaoht7  于 6个月前  发布在  其他
关注(0)|答案(1)|浏览(32)

objcopy工具可以轻松地将任意文件嵌入到ELF可执行文件中:

objcopy --add-section program.file1=file1.dat \
        --add-section program.file2=file2.dat \
        program program+files

字符串
在我看来,program+files应该可以在不打开和阅读任何外部文件的情况下以编程方式访问file1file2。然而,似乎没有简单的方法从运行的程序中获得这些信息。
这些文件是作为ELF可执行文件的命名节添加的。但是,Linux只加载ELF程序头表描述的段。这些节从不出现在该集中,因为它们不是执行所必需的。
因此,虽然可以获得指向当前运行程序的ELF头的指针,但这是毫无意义的,因为这些部分根本没有加载。

uintptr_t address = getauxval(AT_PHDR) & -4096;
Elf64_Ehdr *elf = (Elf64_Ehdr *) address;

// dangling pointer, sections aren't loaded by the OS
Elf64_Shdr *sections = ((unsigned char *) elf) + elf->e_shoff;


我的意图是在运行时按名称搜索这些部分,找到前缀为program.的部分,并计算指向它们的指针,这样我的代码就可以像使用普通内存块一样使用它们。
我不能使用预定义的符号,因为我想支持任意数量的嵌入式文件,包括没有嵌入式文件。我需要在运行时查找这些部分。
Linux只会加载标记为PT_LOAD的段。这些段可以以某种方式放置在PT_LOAD段中吗?objcopy似乎没有编辑程序头表和添加新PT_LOAD段的能力。如何做到这一点?

sg2wtvxw

sg2wtvxw1#

我的意图是在运行时按名称搜索这些部分,找到以program.为前缀的部分,并计算指向它们的指针,这样我的代码就可以像使用普通内存块一样使用它们。
您可以在磁盘上找到program(使用/proc/self/exe),mmap it 1,解码节头(参见this answer),然后计算指向感兴趣的节的指针,并根据需要使用它们。
这些部分可以以某种方式放置在PT_LOAD段中吗?
否:这将需要重建可执行文件的某些部分,而这些部分在不重新链接整个程序的情况下是无法重建的。

更新:

如果您不太关心程序的内存使用情况,那么可以修改最后一个LOAD段以“覆盖”* 整个 * program+files,然后可以跳过单独的mmap--这些文件已经在内存中了。
你只需要增加.p_filesz.p_memsz,使phdr.p_offset + phdr.p_filesz == file_size
代价是你会导致通常不会加载到内存中的数据(例如节头、调试节(如果有的话))占用内存。但是使用请求分页,代价可能非常小--没有任何东西会访问这些“额外”的内存区域,因此没有任何东西会导致它们被分页。
P.S.我知道没有标准的实用程序可以更新.p_filesz等,但在CPython中编写这样的修补程序非常容易。
1您不必mmap整个program,只需其中包含所需部分的部分。

相关问题