dex & oat & ELF & art

本文介绍了Android平台上的DEX文件及其优化方法,并详细解释了OAT文件的作用及生成过程。此外,还探讨了ART运行时的工作原理,以及它是如何替代Dalvik虚拟机的。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

dex - Android平台上可执行文件的类型。
    对于Android DEX文件进行优化,需要注意的一点是DEX文件的结构是紧凑的,但是我们还是要想方设法的进行提高程序的运行速度,我们就仍然需要对DEX文件进行进一步优化。
调整所有字段的字节序(LITTLE_ENDIAN)和对齐结构中的每一个域 验证DEX文件中的所有类 对一些特定的类进行优化,对方法里的操作码进行优化 。优化后的文件大小会有所增加,应该是原Android DEX文件的1-4倍。 优化发生的时机有两个:对于预置应用,可以在系统编译后,生成优化文件,以ODEX结尾。
这样在发布时除APK文件(不包含DEX)以外,还有一个相应的Android DEX文件;对于非预置应用,包含在APK文件里的DEX文件会在运行时被优化,优化后的文件将被保存在缓存中。
每一个Android应用都运行在一个Dalvik虚拟机实例里,而每一个虚拟机实例都是一个独立的进程空间。虚拟机的线程机制,内存分配和管理,Mutex等等都是依赖底层操作系统而实现的。
所有Android应用的线程都对应一个Linux线程,虚拟机因而可以更多的依赖操作系统的线程调度和管理机制。
不同的应用在不同的进程空间里运行,加之对不同来源的应用都使用不同的Linux用户来运行,可以最大程度的保护应用的安全和独立运行。
Zygote是一个虚拟机进程,同时也是一个虚拟机实例的孵化器,每当系统要求执行一个 Android应用程序,Zygote就会FORK出一个子进程来执行该应用程序。这样做的好处显而易见:Zygote进程是在系统启动时产生的,它会完成虚拟机的初始化,库的加载,预置类库的加载和初始化等等操作,而在系统需要一个新的虚拟机实例时。
Zygote通过复制自身,最快速的提供个系统。另外,对于一些只读的系统库,所有虚拟机实例都和Zygote共享一块内存区域,大大节省了内存开销。Android应用开发和Dalvik虚拟机Android应用所使用的编程语言是Java语言,和Java SE一样,编译时使用Sun JDK将Java源程序编程成标准的Java字节码文件(.class文件)。
而后通过工具软件DX把所有的字节码文件转成Android DEX文件(classes.dex)。最后使用Android打包工具(aapt)将DEX文件,资源文件以及AndroidManifest.xml文件(二进制格式)组合成一个应用程序包(APK)。应用程序包可以被发布到手机上运行。

-- 来自百度百科
链接:http://blog.youkuaiyun.com/kakaxi1o1/article/details/46867539

oat:
OAT文件是一种Android私有ELF文件格式,它不仅包含有从DEX文件翻译而来的本地机器指令,还包含有原来的DEX文件内容。APK在安装的过程中,会通过dex2oat工具生成一个OAT文件。这使得我们无需重新编译原有的APK就可以让它正常地在ART里面运行,也就是我们不需要改变原来的APK编程接口。oat 文件在 /data/dalvik-cache/*@classes.dex。

ELF
  elf是一种文件格式,用于存储Linux程序. 它内部都有一些什么信息呢?大概包括编制好的计算机指令,数据,计算机在需要的时候把这个文件读取到内存中,cpu就可以从内存中一条一条的读取指令来执行了。
-- elf格式分析  http://blog.youkuaiyun.com/hhhbbb/article/details/6855004
https://en.wikipedia.org/wiki/Executable_and_Linkable_Format


ART
Kitkat最令人兴奋、却也最少见诸报端的特性之一就是ART,这个处于试验阶段的最新运行时。Google并没有发布太多有关ART的信息(http://goo.gl/9Jzgdo),尽管事实上它已经出现了。然而,我觉得这个特性可能对未来的发布产生巨大的影响,因为有了ART后Android将不再理会执行过的dalvik字节码,转而使用一种平台特有的、提前编译(AOT,ahead-of-time)二进制码。

Dalvik虚拟机遵循传统Java虚拟机的运行方式:源码编译成平台无关的字节码,随后字节码立即编译成机器码(JIT-Just in time编译)。ART使用了另一种实现方式:它使用AOT范例将代码编译成前期执行的本地代码。但是,这是如何实现的呢?

鉴于在Android市场上基于当前三大不同的体系结构(MIPS,x86,ARM)催生了多种多样的平台,应用程序之间相互可移植性(inter-portability)变得十分重要。他们不得不找到一种方式整合两个世界:互相可移植性和执行本地二进制代码。就目前所知,他们的解决方案在移动领域是独一无二的:将中间字节码装运成可执行代码,然后在目标设备上执行最后的编译步骤——“提前编译”。

对ART进一步的观察显示:他们在最后的编译步骤中使用了LLVM。这种对本地代码的编译处理过程在安装应用时可以流畅地完成。

除此之外,Android小组还面临着一个额外的挑战:兼容业已存在的Dalvik虚拟机/DEX技术。为了处理这个问题,他们引入了一种把dex格式转变成新的oat格式的方法。

-- http://www.importnew.com/8822.html
http://blog.youkuaiyun.com/luoshengyang/article/details/39307813
http://blog.youkuaiyun.com/luoshengyang/article/details/39256813
http://blog.youkuaiyun.com/zylc369/article/details/39452053
http://blog.youkuaiyun.com/cosmoslhf/article/details/40380559
<think>首先,用户的问题是:"我想了解或解决与dex2oat相关的问题 请问dex2oat 是什么以及如何使用"。这基于系统级指令,我需要遵循那些规则:所有行内数学表达式用$...$,独立公式用$$...$$,使用中文回答,生成相关问题,并在引用段落末尾添加引用标识。 系统指令还包括:"回答中引用的段落末尾自然地添加引用标识,例如:[^1]"。参考的引用是来自一个博客:"引用[1]:在 【Android 逆向】ART 脱壳 ( DexClassLoader 脱壳 | exec_utils.cc 中执行 Dex 编译为 Oat 文件的 Exec 和 ExecAndReturnC函数 ) 博客中 , 将 dex 文件编译为 oat 文件 , 编译过程是由 dex2oat 可执行程序完成的 , 这是一个有 main 函数的可执行程序 ; 一、搜索 dex2oat 源码 [^1]" 用户的问题是询问dex2oat是什么以及如何使用,所以我需要基于这个引用提供信息。引用中提到dex2oat是将dex文件编译为oat文件的可执行程序,有main函数,是编译过程的一部分。 我的回答需要结构清晰,帮助用户逐步解决问题。内容应真实可靠,基于Android开发的知识。 分解问题: 1. **什么是dex2oat?** - dex2oatAndroid运行时(ART)的一个工具,用于将DEX字节码编译成本地机器码(OAT文件),以提高应用执行效率。ARTAndroid的运行时环境,取代了Dalvik虚拟机。 2. **如何使用dex2oat?** - 通常,在Android设备上,dex2oat是系统自动运行的,例如在应用安装时。但开发者也可以手动使用它。 - 手动使用方式:通过adb shell命令在设备上执行dex2oat。命令格式如:`dex2oat --dex-file=/path/to/dex --oat-file=/path/to/output.oat` - 参数包括指定输入dex文件和输出oat文件。 从引用中,我可以提取信息:dex2oat是一个可执行程序,有main函数,用于编译dexoat。 在回答中,我需要自然地添加引用标识。既然引用是[^1],我应该在相关部分末尾添加[^1]。 系统指令说:"生成相关问题",所以我需要在回答结束时生成相关问题。 回答结构: - 先解释什么是dex2oat。 - 然后解释如何使用它。 - 确保语言是中文。 - 使用行内数学表达式如果有必要,但在这个上下文中可能不需要,因为dex2oat是编程相关,不是数学。除非有数学表达式,否则可以省略。 - 独立公式如果有,但这里可能不适用。 - 最后,生成相关问题。 可能的回答大纲: 1. 介绍dex2oat:解释其作用、在Android系统中的地位。 2. 如何使用:包括手动使用命令。 3. 引用部分:基于提供的引用,添加[^1]。 4. 生成相关问题。 相关问题示例: - dex2oat的优化选项有哪些? - 如何调试dex2oat编译过程? - dex2oatART中的作用是什么? - 等等。 确保回答真实可靠:基于Android文档或常识。 最终回答: - 开头:直接回答用户问题。 - 主体:分步骤解释。 - 结尾:生成相关问题。</think>### dex2oat 是什么以及如何使用 dex2oatAndroid 运行时(ART)环境中的一个关键工具,用于将 DEX 字节码文件编译为 OAT(Optimized Android 可执行文件)文件。OAT 文件包含本地机器码,能显著提升 Android 应用的执行效率和启动速度,因为 ART 在应用安装或运行时使用这种编译方式来优化性能(取代了旧版 Dalvik 虚拟机的即时编译)。dex2oat 本身是一个命令行可执行程序,通常位于 Android 设备的 `/system/bin/` 目录下,它基于 C++ 实现,并包含一个 `main` 函数作为入口点[^1]。在 Android 系统中,dex2oat 通常在以下场景自动运行: - 应用安装时:系统自动调用 dex2oat 将 APK 中的 DEX 文件编译为 OAT 文件。 - 系统更新时:对预装应用进行优化。 - 开发者模式下:用于手动编译和测试。 #### 如何使用 dex2oat 虽然 dex2oat 在大多数情况下由系统自动调用,但开发者或逆向工程师可以手动使用它来编译 DEX 文件,例如在调试或优化过程中。以下是基本使用步骤(基于 Android 设备或模拟器): 1. **准备工作**: - 确保设备已 root 或具有 ADB 调试权限(通过 `adb root` 或 `adb shell`)。 - 获取 DEX 文件:可以从 APK 中提取(例如使用 `unzip` 命令),或直接使用设备上的 DEX 文件(如 `/data/app/.../base.dex`)。 2. **基本命令格式**: dex2oat 通过命令行参数执行,核心语法如下: ```bash dex2oat --dex-file=<输入DEX文件路径> --oat-file=<输出OAT文件路径> [其他选项] ``` - `--dex-file`:指定输入 DEX 文件的路径(支持多个文件,用逗号分隔)。 - `--oat-file`:指定编译后 OAT 文件的输出路径。 - 常用选项: - `--instruction-set`:指定目标 CPU 架构(如 arm, arm64, x86),默认为设备当前架构。 - `--compiler-filter`:控制编译优化级别(如 `speed` 为最高优化,`verify` 仅验证)。 - `--app-image-file`:生成应用镜像文件以加速启动。 - `--runtime-arg`:传递运行时参数(如堆大小)。 3. **示例操作**: - **编译单个 DEX 文件**: 假设设备上有一个 DEX 文件 `/sdcard/test.dex`,将其编译为 OAT 文件: ```bash adb shell dex2oat --dex-file=/sdcard/test.dex --oat-file=/sdcard/output.oat ``` 编译完成后,OAT 文件将保存在 `/sdcard/output.oat`。 - **编译 APK 中的多个 DEX 文件**: 如果 APK 包含多个 DEX(如 `classes.dex`, `classes2.dex`),先提取它们,然后编译: ```bash adb shell dex2oat --dex-file=/sdcard/classes.dex,/sdcard/classes2.dex --oat-file=/sdcard/app.oat ``` - **添加优化选项**: 使用 `--compiler-filter=speed` 进行全速优化: ```bash adb shell dex2oat --dex-file=/sdcard/test.dex --oat-file=/sdcard/optimized.oat --compiler-filter=speed ``` 4. **注意事项**: - **权限问题**:手动执行时,需确保设备有足够权限(通常需要 root)。否则,使用 `adb shell run-as <包名>` 访问应用私有目录。 - **输出验证**:编译后,使用 `file /sdcard/output.oat` 检查文件类型(应为 ELF 格式)。 - **性能影响**:dex2oat 编译可能消耗较多 CPU 和内存,在低端设备上谨慎使用。 - **错误处理**:常见错误如文件路径错误或权限不足,可通过 `adb logcat | grep dex2oat` 查看日志。 在 Android 逆向工程中,dex2oat 常用于脱壳操作,例如通过修改编译过程来提取优化后的代码[^1]。但请注意,dex2oat 的使用依赖于 Android 版本(例如 Android 5.0+ 支持 ART),且不同版本命令参数可能略有差异。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值