当前位置: 首页 > news >正文

关于 dex2oat 以及 vdex、cdex、dex 格式转换

版权归作者所有,如有转发,请注明文章出处:https://cyrus-studio.github.io/blog/

dex2oat

dex2oat 是 Android 系统中的一个核心工具,负责将应用中的 .dex(Dalvik Executable)字节码编译为本地机器代码(native code),以提高运行效率。它的全称是 DEX to OAT(Optimized Android Transport)。

dex2oat 的作用

word/media/image1.png

在 Android 系统中,Java/Kotlin 编写的应用在编译时会被转换为 .dex 文件。为了提高性能,Android 会将 .dex 文件进一步编译为 .oat 文件(或 .odex/.vdex 文件),以便设备可以直接执行本地代码而不是解释执行 .dex 字节码。

工作原理(简要流程)

输入:一个或多个 .dex 文件(通常来自 APK 中的 classes.dex)。

输出:生成 .oat(Optimized Android Executable)、.vdex(Verified DEX)和 .art(Android Runtime)文件。

过程:

  • 验证并优化 .dex。

  • 使用 AOT(Ahead-Of-Time)方式将 .dex 转为本地机器码。

  • 生成平台相关的可执行文件,用于加快应用启动速度。

编译模式:

  • AOT(Ahead-Of-Time):安装或开机前就编译好,提高运行速度。

  • JIT(Just-In-Time):运行时动态编译,节省空间但牺牲性能。

  • Hybrid(混合):Android 7.0+ 默认模式,结合 AOT 与 JIT。

执行时机

  • 第一次开机:系统会对预装的应用使用 dex2oat 编译。

  • App 安装时:根据编译策略(speed, quicken, interpret-only 等)选择是否编译。

  • 系统升级/补丁后:部分 DEX 文件会重新编译。

文件说明

  • .dex:Dalvik 字节码文件,APK 中的代码格式。

  • .oat / .odex:包含从 dex 编译来的 优化后的中间表示代码。

  • .vdex:包含验证后的 dex 和优化信息。

  • .art:Android Runtime 中的预编译执行数据

vdexExtractor

vdexExtractor 是一个用于从 .vdex 文件中提取 DEX 文件的工具,它由 Google 安全团队成员 anestisb 开发。它支持将 Android 9 及以后版本中引入的 CompactDex (cdex) 格式转换为标准的 DEX 格式,方便我们使用常规反编译工具(如 jadx、dex2jar等)进行分析。

开源地址:https://github.com/anestisb/vdexExtractor

编译 vdexExtractor

先把 vdexExtractor clone 到本地。

由于 是在 Windows 的 WSL 中编译,所有要转换换行符

cyrus@cyrus:/mnt/d/Python/anti-app/vdexExtractor$ ./tools/deodex/run.sh -i /mnt/d/Python/anti-app/frida_dex_dump/dumped_dex -o /mnt/d/Python/anti-app/frida_dex_dump/dumped_dex_out
/usr/bin/env: ‘bash\r’: No such file or directory

执行下面命令转换 .sh 文件中的换行符为 Unix 格式的换行符

dos2unix make.sh
dos2unix ./tools/deodex/run.sh
dos2unix ./tools/deodex/constants.sh

执行 make.sh 开始编译,报错如下:

cyrus@cyrus:/mnt/d/Python/anti-app/vdexExtractor$ ./make.sh
make: Entering directory '/mnt/d/Python/anti-app/vdexExtractor/src'
rm -f *.o
rm -f */*.o
rm -f vdexExtractor
make: Leaving directory '/mnt/d/Python/anti-app/vdexExtractor/src'
make: Entering directory '/mnt/d/Python/anti-app/vdexExtractor/src'
gcc -c -std=c11 -D_GNU_SOURCE -Wall -Wextra -Werror -DVERSION=\"dev-78f283b\" -c dex.c -o dex.o
gcc -c -std=c11 -D_GNU_SOURCE -Wall -Wextra -Werror -DVERSION=\"dev-78f283b\" -c dex_instruction.c -o dex_instruction.o
dex_instruction.c:655:43: error: argument 2 of type ‘u4[kMaxVarArgRegs]’ {aka ‘unsigned int[kMaxVarArgRegs]’} declared as a variable length array [-Werror=vla-parameter]655 | void dexInstr_getVarArgs(u2 *code_ptr, u4 arg[kMaxVarArgRegs]) {|                                        ~~~^~~~~~~~~~~~~~~~~~~
In file included from dex_instruction.c:23:
dex_instruction.h:278:32: note: previously declared as an ordinary array ‘u4[]’ {aka ‘unsigned int[]’}278 | void dexInstr_getVarArgs(u2 *, u4[]);|                                ^~~~
cc1: all warnings being treated as errors
make: *** [Makefile:56: dex_instruction.o] Error 1
make: Leaving directory '/mnt/d/Python/anti-app/vdexExtractor/src'
[-] build failed

改为通过 make 命令编译:

  • -Wno-error=vla-parameter:关闭 vla-parameter 警告(某些编译器会默认把这个警告当作错误)。

  • ${CFLAGS}:保留已有的 CFLAGS(确保不覆盖其他选项)。

make CFLAGS="${CFLAGS} -Wno-error=vla-parameter" -C src

参考:https://github.com/anestisb/vdexExtractor/issues/82

编译成功

cyrus@cyrus:/mnt/d/Python/anti-app/vdexExtractor$ make CFLAGS="${CFLAGS} -Wno-error=vla-parameter" -C src
make: Entering directory '/mnt/d/Python/anti-app/vdexExtractor/src'
cc -Wno-error=vla-parameter -c dex.c -o dex.o
cc -Wno-error=vla-parameter -c dex_instruction.c -o dex_instruction.o
cc -Wno-error=vla-parameter -c log.c -o log.o
cc -Wno-error=vla-parameter -c out_writer.c -o out_writer.o
cc -Wno-error=vla-parameter -c utils.c -o utils.o
cc -Wno-error=vla-parameter -c vdexExtractor.c -o vdexExtractor.o
cc -Wno-error=vla-parameter -c vdex_api.c -o vdex_api.o
cc -Wno-error=vla-parameter -c hashset/hashset.c -o hashset/hashset.o
cc -Wno-error=vla-parameter -c vdex/vdex_006.c -o vdex/vdex_006.o
cc -Wno-error=vla-parameter -c vdex/vdex_010.c -o vdex/vdex_010.o
cc -Wno-error=vla-parameter -c vdex/vdex_019.c -o vdex/vdex_019.o
cc -Wno-error=vla-parameter -c vdex/vdex_021.c -o vdex/vdex_021.o
cc -Wno-error=vla-parameter -c vdex/vdex_backend_006.c -o vdex/vdex_backend_006.o
cc -Wno-error=vla-parameter -c vdex/vdex_backend_010.c -o vdex/vdex_backend_010.o
cc -Wno-error=vla-parameter -c vdex/vdex_backend_019.c -o vdex/vdex_backend_019.o
cc -Wno-error=vla-parameter -c vdex/vdex_backend_021.c -o vdex/vdex_backend_021.o
cc -Wno-error=vla-parameter -c vdex/vdex_decompiler_006.c -o vdex/vdex_decompiler_006.o
cc -Wno-error=vla-parameter -c vdex/vdex_decompiler_010.c -o vdex/vdex_decompiler_010.o
cc -Wno-error=vla-parameter -c vdex/vdex_decompiler_019.c -o vdex/vdex_decompiler_019.o
cc -Wno-error=vla-parameter -c vdex/vdex_decompiler_021.c -o vdex/vdex_decompiler_021.o
cc  dex.o  dex_instruction.o  log.o  out_writer.o  utils.o  vdexExtractor.o  vdex_api.o  hashset/hashset.o  vdex/vdex_006.o  vdex/vdex_010.o  vdex/vdex_019.o  vdex/vdex_021.o  vdex/vdex_backend_006.o  vdex/vdex_backend_010.o  vdex/vdex_backend_019.o  vdex/vdex_backend_021.o  vdex/vdex_decompiler_006.o  vdex/vdex_decompiler_010.o  vdex/vdex_decompiler_019.o  vdex/vdex_decompiler_021.o -lm -lz -o vdexExtractor
cp vdexExtractor ../bin/vdexExtractor
make: Leaving directory '/mnt/d/Python/anti-app/vdexExtractor/src'

编译成功后可以看到 bin 目录下多了一个 vdexExtractor 文件

word/media/image2.png

vdexExtractor 的作用就是从 vdex 中抽取 cdex 文件。还需要 compact_dex_converter 把 cdex 转换成标准的 dex。

cdex

Android 9 引入 CompactDex(.cdex,magic 为 cdex001),是 DEX 的压缩优化版本。

优化后的 dex/cdex 通常存放在:

/data/app/package_name/oat/arm64/base.odex
/data/app/package_name/oat/arm64/base.vdex

在 Android 9(Pie)中,APP 的 .cdex 文件 是由 dex2oat 优化生成的,通常以 odex, vdex 或直接优化后的 .art 文件形式存在。

compact_dex_converter

下载 compact_dex_converter (把 CompactDexFile 转换为标准 Dex)

https://github.com/anestisb/vdexExtractor?#compact-dex-converter

word/media/image3.png

由于 constants.sh 中下载链接已经失效了。我们手动把下载的 compact_dex_converter 放到下面路径:

vdexExtractor\tools\deodex\hostTools\Linux\api-API_29\bin\compact_dex_converter

word/media/image4.png

注释掉 /tools/deodex/run.sh 中 deps_prepare_env “$apiLevel” 的方调用,去掉自动下载 compact_dex_converter

word/media/image5.png

vdex 转换 dex

执行 run.sh 开始转换

cyrus@cyrus:/mnt/d/Python/anti-app/vdexExtractor$ ./tools/deodex/run.sh -i ./test -o ./test
[INFO]: Processing 1 input Vdex files
[INFO]: 1 binaries have been successfully deodexed

cdex 转换 dex

通过 compact_dex_converter 把 cdex 转换 dex

./tools/deodex/hostTools/Linux/api-API_29/bin/compact_dex_converter -w ./test ./test/base.cdex

调用示例

进入 /data/app 目录下找到目标 app 的 oat 文件存放路径

wayne:/data/app # ls
com.android.chrome-b1d3YEy1eVrwwjPOa1oq5A==       com.iflytek.inputmethod-s1r9JFv0-eKNskzHyrh_vQ==
com.cyrus.example-uIsySv7lFm21qMVPnPJ-pw==        com.shizhuang.duapp-fTxemmnM8l6298xbBELksQ==
com.cyrus.example.plugin-YsXrxPvfWYdsWHxFKjcusw== com.tencent.mm-ql7ajyK9JqKXli5pgu88nw==
com.cyrus.example.test-R06ZNyf5doqJFOcZ6EaYHQ==   com.xingin.xhs-HeYr1dfB-rU7NjxJiLiDeg==

进入目标目录,找到 base.art base.odex base.vdex

wayne:/data/app # cd com.shizhuang.duapp-fTxemmnM8l6298xbBELksQ==
wayne:/data/app/com.shizhuang.duapp-fTxemmnM8l6298xbBELksQ== # ls
base.apk lib oat
wayne:/data/app/com.shizhuang.duapp-fTxemmnM8l6298xbBELksQ== # cd oat
wayne:/data/app/com.shizhuang.duapp-fTxemmnM8l6298xbBELksQ==/oat # ls
arm64
wayne:/data/app/com.shizhuang.duapp-fTxemmnM8l6298xbBELksQ==/oat # cd arm64/
wayne:/data/app/com.shizhuang.duapp-fTxemmnM8l6298xbBELksQ==/oat/arm64 # ls
base.art base.odex base.vdex

拉取到本地

adb pull /data/app/com.shizhuang.duapp-fTxemmnM8l6298xbBELksQ==/oat/arm64 ./test

执行 run.sh 把 vdex 转换为 dex

./tools/deodex/run.sh -i ./test -o ./test

输出如下:

cyrus@cyrus:/mnt/d/Python/anti-app/vdexExtractor$ ./tools/deodex/run.sh -i ./test -o ./test
[INFO]: Processing 1 input Vdex files
[INFO]: 1 binaries have been successfully deodexed

转换完成后的 dex 文件

word/media/image6.png

拖入 jadx 能正常识别

word/media/image1.png

相关文章:

  • Sui 上线两周年,掀起增长「海啸」
  • 一、Hadoop历史发展与优劣势
  • 项目成本管理_挣得进度ES
  • osquery在网络安全入侵场景中的应用实战(二)
  • 【AND-OR-~OR锁存器设计】2022-8-31
  • 深度学习中学习率调整:提升食物图像分类模型性能的关键实践
  • 山东大学项目实训-创新实训-法律文书专家系统-项目报告(三)
  • Linux常用命令31——groupmod更改群组属性
  • 分析 Docker 磁盘占用
  • 浙大:基于内在偏好的LLM个性化对齐
  • 基于EFISH-SCB-RK3576/SAIL-RK3576的自助服务终端技术方案‌(国产化替代J1900的全场景技术解析)
  • 神经网络在专家系统中的应用:从符号逻辑到连接主义的融合创新
  • Git 第一讲---基础篇 git基础概念与操作
  • Kdump 收集器及使用方式
  • 对ubuntu的简单介绍
  • WebRTC 服务器之SRS服务器概述和环境搭建
  • Qwen2_5-Omni-3B:支持视频、音频、图像和文本的全能AI,可在本地运行
  • Linux的时间同步服务器(附加详细实验案例)
  • OpenCV进阶操作:图像直方图、直方图均衡化
  • 【最新Python包管理工具UV的介绍和安装】
  • 特朗普称美军舰商船应免费通行苏伊士运河,外交部:反对任何霸凌言行
  • 商务部:自5月7日起对原产于印度的进口氯氰菊酯征收反倾销税
  • 言短意长|党政主官如何塑造流量城市?
  • 涉“子宫肌瘤”论文现55例男性对照观察患者?山大齐鲁医院:正在调查
  • 当AI开始谋财害命:从骗钱到卖假药,人类该如何防范?
  • 魔都眼|上海环球马术冠军赛收官,英国骑手夺冠