我有以下简单的hello-world
程序,它使用gcc在标准的elf二进制文件中编译:
#include<stdio.h>
void hello() {
printf("Preinit hello!\n");
}
int main() {
printf("Hello World\n");
return 0;
}
我如何使用libelf(或其他建议的C库用于此类操作来创建新的elf文件,以便添加一个调用.preinit_array
的hello()
节?
我的最终目标是“模拟”编译器将执行以下操作:
__attribute__((section(".preinit_array"))) typeof(hello) *hello_p = hello;
我读了libelf by example
,但我发现它完全是晦涩的,仅使用32位示例已过时。
我也发现了this相关的SO问题。 objcopy
几乎可以完成我想做的事情,但是显然我不想从我的C程序中调用objcopy
。另外,由于代码非常复杂且相互关联,我尝试从objcopy
复制here的源代码几乎没有成功。
我的最终目标是“模拟”编译器对以下内容的处理
那个最终目标(本身)对我来说毫无意义:为什么不那么做:添加.preinit_array
,重建程序,获利。
您的real最终目标可能是其他东西(另请参阅XY Problem)。
您的问题的简单答案是:您不能(或至少是非常艰巨的任务,您很可能在成功解决此[[real问题之前找到其他解决方案)方法)。
原因:ELF
文件格式具有很多交叉引用(文件的某些部分记录了文件的其他部分所在的位置),并且在链接期间会丢弃正确更新所有此类交叉引用所需的信息。过程。即,大多数UNIX链接程序将a.out
或foo.so
视为链接的
final
乘积,并且后续的更新都不可行。不是全部
正确:某些部分可能会在链接后更新,例如chrpath和patchelf可以进行这种有限的编辑。但是一般情况下确实很难。