Android ELF文件PLT和GOT
2013-04-02 10:08
309 查看
之前分析了x86平台ELF文件PLT和GOT,这里来看一些Android的ELF文件。因为Android智能手机使用的是ARM架构的CPU,所以本文关注的ELF文件也可以认为是ARM平台的ELF。
测试代码依然是经典的hello world
?
在Android源码环境下编译,需要Android.mk文件:
Android源码中提供了几个和x86平台类似的ELF文件查看工具,比如objdump和readelf,位置分别是:
然后使用arm-eabi-objdump看看plt表中的内容,如下
按照顺序,从0×8318到0×8320的三条指令,是puts函数对应的PLT表项:
这三条指令到底做了什么,还需要进一步分析。
1. 0×8318: e28fc600 add ip, pc, #0 ; 0×0
ARM采用三级流水线,PC寄存器中取到的指令地址是当前执行指令的地址加8。当前指令的地址为0×8318,因此PC = 0×8318 + 0×8 = 0×8320。IP = PC + 0 = 0×8320
2. 0x831c: e28cca00 add ip, ip, #0 ; 0×0
IP = IP + 0 = 0×8320 + 0 = 0×8320
3. 0×8320: e5bcfdd4 ldr pc, [ip, #3540]!
PC = IP + 3540(dec) = 0×8320 + 0xdd4 = 0x90f4 这是一个间接寻址后跳转的语句,跳转的目的地址是0x90f4中存储的数值。
0x90f4这个地址附近的内容如下:
已经到了GOT中,0x90f4就是puts对应的GOT表项的地址,而上一步跳转的目的地,就是0x90f4中存储的数值,即0×8304。再看一下之间的PLT,发现0×8304正是PLT第0项的地址。至此,完成了和x86平台类似的功能,然后下一步就是具体的符号解析过程。
当找到puts的真正地址时,修改对应的GOt表项,再次调用puts就不再需要重新解析符号了
[/code]
测试代码依然是经典的hello world
?
LOCAL_PATH:=$(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := \ hello.c LOCAL_MODULE_TAGS := debug LOCAL_MODULE := hello LOCAL_SHARED_LIBRARIES := libc LOCAL_MODULE_PATH := ./custom_out include $(BUILD_EXECUTABLE)
Android源码中提供了几个和x86平台类似的ELF文件查看工具,比如objdump和readelf,位置分别是:
./prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/arm-eabi-objdump ./prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin/arm-eabi-readelf
然后使用arm-eabi-objdump看看plt表中的内容,如下
Disassembly of section .plt: 00008304 <.plt>: 8304: e52de004 push {lr} ; (str lr, [sp, #-4]!) 8308: e59fe004 ldr lr, [pc, #4] ; 8314 <__exidx_start-0x81> 830c: e08fe00e add lr, pc, lr 8310: e5bef008 ldr pc, [lr, #8]! 8314: 00000dd4 ldrdeq r0, [r0], -r4 8318: e28fc600 add ip, pc, #0 ; 0x0 831c: e28cca00 add ip, ip, #0 ; 0x0 8320: e5bcfdd4 ldr pc, [ip, #3540]! 8324: e28fc600 add ip, pc, #0 ; 0x0 8328: e28cca00 add ip, ip, #0 ; 0x0 832c: e5bcfdcc ldr pc, [ip, #3532]! 根据指令的重复特征可以看到,从0×8318开始的六条指令,是PLT中的两个表项,每个表项有三条指令。 使用arm-eabi-readelf看.rel.plt节区的内容如下,确实只有两个符号需要使用PLT进行重定位: [code] Relocation section '.rel.plt' at offset 0x2f4 contains 2 entries: Offset Info Type Sym.Value Sym. Name 000090f4 00000416 R_ARM_JUMP_SLOT 00008318 puts 000090f8 00000716 R_ARM_JUMP_SLOT 00008324 __libc_init
按照顺序,从0×8318到0×8320的三条指令,是puts函数对应的PLT表项:
8318: e28fc600 add ip, pc, #0 ; 0x0 831c: e28cca00 add ip, ip, #0 ; 0x0 8320: e5bcfdd4 ldr pc, [ip, #3540]!
这三条指令到底做了什么,还需要进一步分析。
1. 0×8318: e28fc600 add ip, pc, #0 ; 0×0
ARM采用三级流水线,PC寄存器中取到的指令地址是当前执行指令的地址加8。当前指令的地址为0×8318,因此PC = 0×8318 + 0×8 = 0×8320。IP = PC + 0 = 0×8320
2. 0x831c: e28cca00 add ip, ip, #0 ; 0×0
IP = IP + 0 = 0×8320 + 0 = 0×8320
3. 0×8320: e5bcfdd4 ldr pc, [ip, #3540]!
PC = IP + 3540(dec) = 0×8320 + 0xdd4 = 0x90f4 这是一个间接寻址后跳转的语句,跳转的目的地址是0x90f4中存储的数值。
0x90f4这个地址附近的内容如下:
Disassembly of section .got: 000090e8 <.got>: 90e8: 00009020 andeq r9, r0, r0, lsr #32 ... 90f4: 00008304 andeq r8, r0, r4, lsl #6 90f8: 00008304 andeq r8, r0, r4, lsl #6
已经到了GOT中,0x90f4就是puts对应的GOT表项的地址,而上一步跳转的目的地,就是0x90f4中存储的数值,即0×8304。再看一下之间的PLT,发现0×8304正是PLT第0项的地址。至此,完成了和x86平台类似的功能,然后下一步就是具体的符号解析过程。
当找到puts的真正地址时,修改对应的GOt表项,再次调用puts就不再需要重新解析符号了
[/code]
相关文章推荐
- Android ELF文件PLT和GOT
- Android ELF文件中.got .plt .rel.plt .rel.dyn节的区别和联系
- android ELF文件PLT和GOT
- ELF文件动态链接时 GOT,PLT 的变化过程
- ELF 文件中的 GOT 表和 PLT 表解读
- 基于Android的ELF PLT/GOT符号重定向过程及ELF Hook实现(by 低端码农 2014.10.27)
- 基于Android的ELF PLT/GOT符号重定向过程及ELF Hook实现(by 低端码农 2014.10.27)
- elf文件中的.plt .rel.dyn .rel.plt .got .got.plt的关系
- 基于Android的ELF PLT/GOT符号重定向过程及ELF Hook实现(by 低端码农 2014.10.27)
- ELF文件动态链接时 GOT,PLT 的变化过程
- ELF文件动态链接时 GOT,PLT 的变化过程
- 基于Android的ELF PLT/GOT符号和重定向过程ELF Hook实现(by 低端农业代码 2014.10.27)
- 基于Android的ELF PLT/GOT符号重定向过程及ELF Hook实现
- ELF文件动态链接时 GOT,PLT 的变化过程
- 基于Android的ELF PLT/GOT符号重定向过程及ELF Hook实现
- 基于Android的ELF PLT/GOT符号重定向过程及ELF Hook实现
- 基于Android的ELF PLT/GOT符号重定向过程
- Android ART VM可执行文件格式-ELF(二)
- Android逆向之旅---SO(ELF)文件格式详解
- Android逆向分析——ELF文件格式