【问题标题】:Inject a .preinit_array section in an ELF file with libelf使用 libelf 在 ELF 文件中注入 .preinit_array 部分
【发布时间】:2020-06-11 22:13:15
【问题描述】:

我在标准 elf 二进制文件中使用 gcc 编译了以下简单的 hello-world 程序:

#include <stdio.h>

void hello() {
  printf("Preinit hello!\n");
}

int main() {
    printf("Hello World\n");
    return 0;
}

如何使用 libelf(或任何其他建议的用于此类操作的 C 库)创建新的 elf 文件,以添加调用 hello().preinit_array 部分?

我的最终目标是“模拟”编译器将如何处理以下内容:

__attribute__((section(".preinit_array"))) typeof(hello) *hello_p = hello;

我阅读了libelf by example,但我发现它完全神秘,并且仅使用 32 位示例已过时。

我还发现了this 相关的 SO 问题。 objcopy 正在做我想做的事情,但显然我不想从我的 C 程序中调用 objcopy。此外,我尝试从here 复制objcopy 的源代码,但收效甚微,因为代码非常复杂且相互关联。

【问题讨论】:

    标签: c linux elf


    【解决方案1】:

    我的最终目标是“模拟”编译器将如何处理以下内容

    那个最终目标(本身)对我来说毫无意义:为什么不直接这样做:添加.preinit_array,重建程序,获利。

    你的真正最终目标可能是别的东西(另见XY Problem)。

    您的问题的简单答案是:您不能(或者至少,这项任务非常重要,而且您很可能在很久以前就找到解决您的真正问题的其他解决方案你用这种方法成功了)。

    原因:ELF 文件格式有很多交叉引用(文件的一部分记录了文件的其他部分在哪里),并且正确更新所有此类交叉引用所需的信息在链接过程。

    也就是说,大多数 UNIX 链接器将a.outfoo.so 视为链接的最终 产品,并且后续更新都不可行。

    这并非完全正确:某些部分可能会在链接后更新,例如chrpathpatchelf 可以进行这种有限的编辑。但是一般情况下真的很难。

    【讨论】:

    • 我试图让读者从“为什么”的细节中解脱出来,因​​为它有点无关紧要。我正在研究一个使用二进制重写来拦截系统调用github.com/srg-imperial/SaBRe 的研究项目。在这个项目中,我需要加载一个任意 elf 文件并在标题中注入一个.preinit_array,这样我就可以调用一些任意符号。
    猜你喜欢
    • 1970-01-01
    • 2012-02-11
    • 1970-01-01
    • 2016-06-20
    • 1970-01-01
    • 2012-10-30
    • 1970-01-01
    • 2012-05-27
    • 1970-01-01
    相关资源
    最近更新 更多