Vdex Extractor
一款命令行工具,用于从Vdex文件反编译和提取Android Dex字节码的工具。
编译
克隆此存储库
如果要为Android设备进行交叉编译,请安装Android NDK
make.sh使用所需的构建目标调用bash脚本$ ./make.sh- 如果CC未从env定义,则默认使用gcc$ ./make.sh gcc – 用gcc编译$ ./make.sh clang – 用clang编译$ ./make.sh cross-android – 使用NDK交叉编译(armeabi-v7a,arm64-v8a,x86和x86_64)可执行文件复制到bin目录下,对于调试版本使用$ DEBUG=true ./make.sh
依赖关系
主机系统中应安装以下外部库:
zlib
macos:brew install zlib-devel带macports的macOS: port install zlibLinux: apt install libz-dev其他Linux / Unix系统:检查可用的包管理器或从源代码编译使用cygwin的Windows:zlib-devel从cygwin安装程序安装
用法
$ bin/vdexExtractor -h
vdexExtractor ver. 0.5.2
Anestis Bechtsoudis
Copyright 2017 - 2018 by CENSUS S.A. All Rights Reserved.
-i, --input= : 输入目录(递归搜索)或单个文件
-o, --output= : 输出路径(默认与输入相同)
-f, --file-override : 如果文件已经存在允许覆盖(默认:false)
--no-unquicken : 禁用unquicken字节码反编译器 (don't de-odex)
--deps : 转储经过验证的依赖信息
--dis : 启用字节码反汇编器
--ignore-crc-error : 反编译Dex 忽略CRC错误
--new-crc= : 提取Apk或Dex文件位置校验和文本文件
--get-api : 基于Vdex版本获取Android API级别
-v, --debug=LEVEL : 日志级别 默认: '3' (INFO)
-l, --log-file=: 保存反汇编器或验证依赖项输出到日志文件
-h, --help : 帮助信息
字节码Unquickening解码器
Vdex文件包含所有quick_info数据(旧vtable),用于恢复字节码优化过程中应用的dexto -dex转换。这里是创建一个能够快速恢复优化字节码的独立工具,不需要从AOSP构建整个libart。Vdex完全unquicken功能也作为AOSP oatdump libart工具的一部分实现。可在此处获得。如果你想在Oreo版本中使用oatdump,你可以在这里使用相应的补丁,或者在oatdump ++工具的fork和build(内部和AOSP_SRC_ROOT工作空间)中使用oreo-release分支。谷歌已经发布了提供的补丁以及ART运行时的Android Pie版本。
验证迭代器的依赖关系
当第一次编译(优化)Dex字节码文件时,dex2oat将执行验证依赖项收集器,作为方法学验证者的一部分。验证依赖项收集器类用于记录解析结果和类路径中定义的类/方法/字段的类型可赋值测试。编译驱动程序初始化类并注册正在编译的所有Dex文件。在这个集合之外的Dex文件中定义的类(或者没有关联的Dex文件的合成类)被认为在类路径中。所有记录的依赖关系都存储在生成的Vdex文件中,以及来自OatWriter类的相应Oat文件。vdexExtractor工具集成了一个Vdex依赖项walker函数,该函数能够迭代所有依赖项信息并以人类可读的格式转储它们。以下代码段演示了示例Vdex文件的依赖项转储示例。
$ bin/vdexExtractor -i /tmp/BasicDreams.vdex -o /tmp --deps -f
[INFO] Processing 1 file(s) from /tmp/BasicDreams.vdex
------- Vdex Deps Info -------
dex file #0
extra strings: number_of_strings=2
0000: 'Ljava/lang/Thread;'
0001: 'Ljava/lang/Throwable;'
assignable type sets: number_of_sets=8
0000: 'Landroid/service/dreams/DreamService;' must be assignable to 'Landroid/content/Context;'
0001: 'Landroid/view/TextureView;' must be assignable to 'Landroid/view/View;'
0002: 'Ljava/nio/FloatBuffer;' must be assignable to 'Ljava/nio/Buffer;'
...
unassignable type sets: number_of_sets=0
class dependencies: number_of_classes=34
0000: 'Landroid/graphics/Color;' 'must' be resolved with access flags '1'
0001: 'Landroid/graphics/SurfaceTexture;' 'must' be resolved with access flags '1'
...
0024: 'Ljavax/microedition/khronos/egl/EGL10;' 'must' be resolved with access flags '513'
...
field dependencies: number_of_fields=4
0000: 'Ljavax/microedition/khronos/egl/EGL10;'->'EGL_DEFAULT_DISPLAY':'Ljava/lang/Object;' is expected to be in class 'Ljavax/microedition/khronos/egl/EGL10;' and have the access flags '9'
0001: 'Ljavax/microedition/khronos/egl/EGL10;'->'EGL_NO_CONTEXT':'Ljavax/microedition/khronos/egl/EGLContext;' is expected to be in class 'Ljavax/microedition/khronos/egl/EGL10;' and have the access flags '9'
0002: 'Ljavax/microedition/khronos/egl/EGL10;'->'EGL_NO_DISPLAY':'Ljavax/microedition/khronos/egl/EGLDisplay;' is expected to be in class 'Ljavax/microedition/khronos/egl/EGL10;' and have the access flags '9'
0003: 'Ljavax/microedition/khronos/egl/EGL10;'->'EGL_NO_SURFACE':'Ljavax/microedition/khronos/egl/EGLSurface;' is expected to be in class 'Ljavax/microedition/khronos/egl/EGL10;' and have the access flags '9'
|