安全矩阵

 找回密码
 立即注册
搜索
查看: 666|回复: 0

android逆向基础之文件格式

[复制链接]

141

主题

153

帖子

517

积分

高级会员

Rank: 4

积分
517
发表于 2022-11-2 16:36:38 | 显示全部楼层 |阅读模式
android逆向基础之文件格式原创 编码安全 [url=]编码安全[/url] 2022-10-28 08:30 发表于福建

编辑
编码安全
专注于编程安全技术的分享。
53篇原创内容
公众号



背景



android逆向分析、脱壳破解分析过程中免不了和android的各种文件格式打交道(so、dex、xml、art、oat等等)。Android下的两个最重要的文件是DEX文件和SO文件,下面重点对这两个文件及关联文件进行下文的梳理总结,以此用于温故知新。




DEX文件


DEX它是android虚拟机的可执行字节码文件,我们知道java文件需要经过javac编译成class文件,dx工具会将所有的class文件合并处理最终生成dex文件。

dex文件分为四大部分: DEX文件头,索引结构区,data数据区,静态链接数据区。

在dex文件中所有的代码和数据都放在data数据区中,索引结构区中存放的是data中各种数据的对应的偏移和索引。






ODEX文件


ODEX它的英文全称为Optimized DEX;即优化过的DEX。
在android5.0之前,Android采用的是JIT(just-in-time)即时编译,也就是程序边执行边编译。为了增加程序执行的效率,android在APK第一次安装的时候将程序的dex文件进行优化生成odex文件,并将其放在了/data/dalvik-cache目录下,等待下次apk运行时直接加载这个目录中经过优化的odex文件(优化基于当前系统的dalvik虚拟机版本,不同版本上的odex文件无法进行兼容),避免重复验证提高执行效率,加快APK的响应时间。



OAT文件



在android5.0之后,android使用的是AOT(Ahead-of-time)事前编译,也就是程序在运行前先编译。oat是ART虚拟机运行的文件,是ELF格式二进制文件,包含DEX和编译的本地机器指令,oat文件包含DEX文件,因此比ODEX文件占用空间更大。

程序在首次安装的时候,dex2oat默认会把classes.dex翻译成本地机器指令,生成ELF格式的OAT文件,并将其放在了/data/dalvik-cache或者是/data/app/packagename/目录下。ART加载OAT文件后不需要经过处理就可以直接运行,它在编译时就从字节码装换成机器码了,因此运行速度更快。

在android5.0之后oat文件的后缀还是odex,但是已经不是android5.0之前的文件格式,而是ELF格式封装的本地机器码,可以认为oat在dex上加了一层壳,可以从oat里提取出dex。

编辑
(elf格式的oat)

因为此时的oat文件是一个标准的elf文件,识别其实其是不是oat文件的标准就是看其符号表。
编辑
oatdata指向的是ELF文件的.rodata节区,存放了OAT文件头OATHeader,OAT的DEX文件头,原始DEX文件的DexFile等信息。

oatexec指向的是ELF文件的.text节区,这里存放的是编译生成的指定平台的二进制代码。

oatlastword指向的是对应oat文件的结尾。

OAT文件大小差不多= dex文件+art文件
编辑



vdex文件


android8.0(Android O)之前dex文件嵌入到oat文件本身中,在Android 8.0之后dex2oat将classes.dex优化生成两个文件oat文件(.odex)和vdex文件(.vdex),其中包含APK的未压缩DEX代码,以及一些旨在加快验证速度的元数据。

odex文件中包含了本机代码的OAT
vdex文件包含了原始的DEX文件副本



ART文件


ART虚拟机在执行dex文件时,需要将dex文件中使用的类,字符串等信息转换为自定义的结构。art文件就是保存APK中使用的一些类,字符串等信息的ART内部表示,可以加快APK程序启动的速度。




ELF文件


ELF文件格式提供了两种不同的视,在汇编器和链接器看来,ELF文件是由Section Header Table描述的一系列Section的集合,而执行一个ELF文件时,在加载器(Loader)看来它是由Program Header Table描述的一系列Segment的集合。

ELF它是 Executable and Linking Format 的缩写,它是android平台上通用的二进制文件格式。在 Android 的 NDK 开发中,几乎都是和 ELF 打交道。
比如:
1、c / c++ 文件编译得到的 .o(或者 .obj)文件就是 ELF 格式的文件;
2、动态库(.so)文件、可执行文件也是 ELF 文件;
3、动态库的字符串擦除、动态库加壳、动态库修复等都离不开 ELF;

ELF文件名称中的Executable和 Linking表明 ELF 有两种重要的特性。
1、Executable表示可执行的。ELF 文件将参与程序的执行(Execution)过程。包括二进制程序的运行以及动态库 .so 文件的加载。
2、Linking表示可连接的。ELF 文件参与编译链接过程。
编辑





文件加载



Android中Java层通过System.load或System.loadLibrary来加载一个so文件,它的定义在Android源码中的路径
为/libcore/luni/src/main/java/java/lang/System.java,执行流程如下:

加载so的两种方式
1、System.loadLibrary(path),只能加载jniLIbs目录下的so文件,这个的执行流程
    1.1、先读取so文件的.init_array段
    1.2、执行JNI_OnLoad函数
    1.3、JNI_ONLoad是.so文件的初始函数
    1.4、最后调用具体的native方法

2、System.load(path),可以加载任意路径下的so

这两种方式最终都会调用Android底层的dlopen来打开so
编辑

dlopen用来打开一个动态链接库,并将其装入内存。它的定义在Android源码中的路径为/bionic/linker/dlfcn.cpp,执行流程如下:
编辑

So文件的入口为init_array、init_func这些初始化函数。这部分在dlopen的过程中就会执行,再之后的是JNI_Onload方法的调用。这里面可以注册一些本地方法,也可以继续做些变量的初始化等操作。

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|安全矩阵

GMT+8, 2024-3-28 22:56 , Processed in 0.012405 second(s), 18 queries .

Powered by Discuz! X4.0

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表