ART世界探险(11) - OAT文件格式分析

16 篇文章 4 订阅
7 篇文章 0 订阅

ART世界探险(11) - OAT文件格式分析(1) - ELF文件头(上)

既然是要探险,咱们就保持一定的深度,起码将来可以做个基于ART的黑客之类的。
所以我们针对细节多下一些工夫,先仔细分析一下OAT文件的格式。
ART的本质上是一个编译器,所以我们需要对编译、链接的主要环节都有一个比较深入的了解。想要绕过编译原理去学好ART,是不太现实的一件事情,我们选择可以让这个过程有趣和好玩。

闲扯不多说了,言归正传。

可执行文件

OAT是一种可执行文件,所以封装在一个ELF格式的可执行文件中。
可执行文件,我们可以借大家熟悉的Windows操作系统理解,就是Windows中的exe文件和dll文件。

  • Windows下的exe,dll文件的格式是PE(Portable Executable)
  • Linux/Android下的可执行格式是ELF(Executable Linkable Format)
  • Mac/iPhone下的可执行文件的格式是Mach-O(Mach Object)

主流操作系统的可执行文件结构图

PE和ELF都是COFF格式(Common file format)的变种。
coff

ELF文件的分类

ELF文件可以分为以下4种:
* 可重定位文件:Relocatable File,就像Windows下的.obj文件和Linux下的.o文件一样的目标文件,需要链接才可以执行。
* 真正的可执行文件:Executable File,如Windows的exe一样,是可以直接运行的程序。
* 共享目标文件:Shared Object File,像Windows的dll和Linux下的so一些,动态链接库。
* 核心转储文件:Core dump,用于意外时的地址空间的转储。

这个分类信息,在ELF文件头里面有描述,我们后面会讲到。
elf subclasses

ELF文件头

我们把ELF文件头分成两部分来分析,我们先来看前半部分:

elf头结构1

Magic Number

所谓的Magic Number,其实就是文件的一个标记。
ELF的Magic Number一共占4个字节,首字节为0x7f,后面分别为’E’,’L’,’F’.
只支持大写,必须是0x7f,0x45,0x4c,0x46

我们以Go语言为例,写一段解析Magic Number的代码来作为示例吧:

    buf, err := ioutil.ReadFile(elfFile.elfFileName)
    if err != nil {
        fmt.Println("Error reading ELF:", err)
    }

    magic := [...]byte{0x7f, 'E', 'L', 'F'}
    magic2 := buf[:4]
    if (magic[0] == magic2[0]) && (magic[1] == magic2[1]) && (magic[2] == magic2[2]) && (magic[3] == magic2[3]) {
        fmt.Println("It is an ELF")
    } else {
        fmt.Println("It is not an ELF")
        return
    }

位宽

  • 1-代表32位
  • 2-代表64位

大端还是小端

这个是在多字节的情况下,是高位在前还是低位在前。

  • 1-Little Endian,小端
  • 2-Big Endian,大端

操作系统

操作系统
0x00System V
0x03Linux
0x06Solaris
0x09FreeBSD

在Android上肯定是0x03了。

ELF子类型

这个就是我们上面画图的那4大类型

ELF子类型
0x01可重定位文件
0x02可执行文件
0x03动态链接库
0x04core dump

芯片架构

芯片架构
0x00未知
0x03x86
0x08MIPS
0x28ARM
0x3ex86_64
0xb7AArch64

ELF头分析示例

ELF文件头的结构(第一部分)

偏移量长度描述备注
0x004Magic Number
0x041位数32位还是64位
0x051大端还是小端
0x061版本号1
0x071操作系统
0x088暂时未用到
0x102ELF文件的子类型
0x122芯片架构
0x144又一个版本号设成1

我们下面解析一个实际的OAT文件看看

下面是我从一个64位arm的OAT文件截取的一部分,我们来分析一下:

7F 45 4C 46  02 01 01 03  00 00 00 00  00 00 00 00  
03 00 B7 00  01 00 00 00  00 00 00 00  00 00 00 00  
40 00 00 00  00 00 00 00  E0 3A AA 00  00 00 00 00  
00 00 00 00  40 00 38 00  07 00 40 00  12 00 11 00  
06 00 00 00  04 00 00 00  40 00 00 00  00 00 00 00  
40 00 00 00  00 00 00 00
  • 7F 45 4C 46: Magic Number,就不多说了
  • 02:64位
  • 01:Little Endian,小端
  • 01:版本号1
  • 03:Linux
  • 8个0:没用到
  • 03 00:动态链接库。注意了,我们的OAT文件是so!
  • B7 00: AArch64,arm64-v8a在AArch64状态下
  • 01 00 00 00: 版本号1

一些参考资料

  1. 一种ELF参考规范的文档:
    http://www.cs.princeton.edu/courses/archive/fall05/cos318/docs/ELF_Format.pdf

  2. ELF格式的wiki
    https://en.wikipedia.org/wiki/Executable_and_Linkable_Format

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jtag特工

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值