Android逆向分析——ELF文件格式

ELF(Executable and Linking Format)是一种可执行链接格式,详细学习可以参考北大实验室这个文档——ELF文件格式分析,看完真是受益匪浅。

网上关于ELF文件格式的讲解已经特别多了,这里就不详细讲了,做个学习总结吧。

这个ELF格式文件,有三种类型:

1.可重定位的对象文件(Relocatable file)
也就是编译器编译过程中生成的.o文件,它保存了代码和数据,可以与其他目标文件链接,创建可执行文件或者共享目标文件。

2.可执行的对象文件(Executable file)
就是一个可执行的程序,它定义了exec(),如何创建一个程序的进程映像。

Linux里面的可执行文件,除了这种可执行的对象文件,另一种就是可执行脚本。脚本是文本文件,通过解释器执行,这里的解释器也是一种可执行的对象文件。

3.共享目标的对象文件(Shared object file)
也就是所谓的动态库,即.so文件。它包含可以在两种上下文中链接的代码和数据。一方面,他可以通过链接编辑器与其他可重定位文件和共享目标文件一起,生成另外一个目标文件;另一方面,动态链接器(linker)可以将它与其他共享目标文件和某个可执行文件一起,创建进程映像。

区别于前面提到的静态库,生成的可执行程序中,每个可执行程序运行时在内存中都会保存一份库代码的拷贝,导致资源占用问题;而动态库则可以避免这个情况,程序编译过程中,动态库不会被链接到目标代码中,而是在程序运行时进行动态载入。

基于上面提到的三种类型,ELF文件也提供了两种视图,链接视图和执行视图。
Android逆向分析——ELF文件格式_第1张图片

ELF头位于目标文件的起始位置,用于描述整个文件组织结构。
在链接视图下,ELF文件以节为单位,节是ELF文件处理过程中的基本单元。通过节头表描述各节区的信息,包括节区名称、大小等,文件中的每一个节区对应一个节头描述。
在执行试图下,ELF文件以段为单位,段是节的集合,是链接或执行时映射到内存映像的基本单元。程序头表描述了各段的信息,包括类型、文件偏移、加载时的虚拟地址等,它指明了程序创建进程映像所需信息,每一个段对应一个程序头描述。

具体结构不详细说了,可以参考上面提到的文档。另外,有两个很好的分析工具,一个是linux平台readelf命令,另一个是一个十六进制编辑器,010 Editor,它提供了很多文件格式的模板,直接把二进制文件拖进去完成解析。

总结下常用的几个readelf命令:

  • readelf -h libXXX.so 查看文件头(ELF Header)信息
  • readelf -S libXXX.so 查看节区头(Section Header)表信息
  • readelf -l libXXX.so 查看程序头(Program Header)表信息
  • readelf -e == readelf -h -S -l
  • readelf -s libXXX.so 查看符号表(symbol table)信息
  • readelf -r libXXX.so 查看重定位表(relocation table)信息
  • readelf -d libXXX.so 查看动态节区(dynamic section)信息

解析的代码网上也有很多资源,可以参考http://blog.csdn.net/jiangwei0910410003/article/details/49336613

另外,还有一些其他可能用到的命令:

objcopy 把目标文件复制到另一种类型目标文件
objcopy -R[移除] [段名] [源文件] [新文件]
如,objcopy -R .comment -R .note hello hellonew

objdump 查看目标/可执行文件,它是一个GCC工具
-h 输出段信息 == readelf -S
-t 输出符号表
-x 以分类形式输出目标文件数据组织 == readelf -l -d -S -s
-j 反汇编功能
如objdump -j .text -S main

nm 查看库符号
nm libXXX.so (grep | printf)

ldd 查看依赖项
ldd hello


你可能感兴趣的:(android逆向)