在修复节表过程中,我们需要准确定位到PLT和GOT这样,可以快速让反编译器快速识别节;
以下内容,都测试过Android原生的libc、linker以及自己编译的ndk程序,没有测试obj;
在ELF的非obj文件中,PLT位于.rel.plt的(文件)屁股后面,紧挨着,定位.rel.plt的屁股用段表的DT_PLTRELSZ和DT_JMPREL即可;
而GOT节需要遍历.rel.dyn;
准确表达是.rel.dyn节的所有项的r_offset中(注意这个是内存偏移),大于.dynmanic节(内存)屁股的最小值(命名为GOT_ADDR);
这个GOT_ADDR就是GOT节的内存偏移;
至于上面提到的文件和内存偏移,有个简便方法就是头个内存加载段中的所有地址,内存偏移=文件偏移;
后面的内存加载段 内存偏移 = 文件偏移 “加上” 上一个加载段的段表中的 p_align
接着是关于长度问题;
GOT节的屁股通过段定位DT_PLTGOT,往后数3个int(都是0),然后遍历到前后不一致的特征那里就是屁股;
PLT节的屁股,通过拿OEP定位.text节头往低地址数到非零,那里就是屁股,注意如果是用GCC编译成可执行文件,.text的定位要往低地址减0x0C个字节,因为那里是生成的入口函数的退出地;