从上面的信息中我们可以知道这个文件的类型是ELF64, 也就是64位的可执行程序, 并且有9个程序头和31个节头, 各个节的作用大家可以在网上找到资料, 这篇文章中只涉及到以下的节
.init 程序初始化的代码
.rela.dyn 需要重定位的变量列表
.rela.plt 需要重定位的函数列表
.plt 调用动态链接函数的代码
.text 保存了主要的程序代码
.init 保存了程序的初始化代码, 用于初始化全局变量等
.fini 保存了程序的终止代码, 用于析构全局变量等
.rodata 保存了只读的数据,例如字符串(const char*)
.data 保存了可读写的数据,例如全局变量
.dynsym 动态链接的符号表
.dynstr 动态链接的符号名称字符串
.dynamic 动态链接所需要的信息,供程序运行时使用(不需要访问节头)
什么是动态链接上面的程序中调用了printf函数, 然而这个函数的实现并不在./a.out中, 那么printf函数在哪里, 又是怎么被调用的?
printf函数的实现在glibc库中, 也就是/lib/x86_64-linux-gnu/libc.so.6中, 在执行./a.out的时候会在glibc库中找到这个函数并进行调用, 我们来看看这段代码
执行以下命令反编译./a.out
objdump -c -S ./a.out
我们可以看到以下的代码