(接上篇)反编译两种可执行文件
上篇地址:http://blog.****.net/eliot_shao/article/details/78648314
上篇主要内容回顾:
上篇内容介绍了静态编译生成静态库,然后链接静态库生成可执行文件的过程;也对比介绍了动态编译生成动态库然后链接动态库生成可执行文件的过程。我们也得出了结论:
链接静态库生成的可执行文件main运行不依赖与静态库是否存在,而链接动态库生成的可执行文件main2是依赖于动态库的存在的。
下面我们使用反编译手段分析上面的结论。
1:链接静态链接库,生成可执行文件
gcc main.c -static -L. -lstruct -o main
反编译可执行文件 objdump -D main > static_obj.txt
2:链接动态链接库,生成可执行文件
gcc main.c -L. -lstruct -o main2
反编译可执行文件 objdump -D main > shard_obj.txt
对比大图:
链接静态库(该库只有hello函数)生成的可执行文件反编译结果:
链接动态库(该库只有hello函数)生成的可执行文件反编译结果,分三步查找:
查找过程1、2、3可以通过博文http://blog.****.net/eliot_shao/article/details/78549247中的一张图反映。最终还是依赖于解析器将动态库加载到内存,找到动态库对应符号(hello)的位置,然后跳转到hello,执行权利交接,hello函数得以执行!
.so本质和可执行文件一样也是elf,elf一种。.a则不是elf文件,这里没深入研究。见下图。
结论;通过反编译两个可执行文件,我们会发现二者主要区别是动态链接过程,前者已经把静态库的内容链接到可执行文件内部,不需要额外的定位库文件,而后者则需要“解析器”去通过PLT和GOT去加载动态库文件(.so)到内存然后在去定位要访问函数的位置。