ART深入浅出5--了解Dex文件格式(2)

ART虚拟机 | Dex Verify实现详解 Dex Verify是Android 系统对Dex文件进行合法性与安全性校验的核心流程。在介绍Dex Verify实现原理之前,先介绍下Dex文件,便于理解Verify实现原理。将多个.class字节码文件编译合成一个.dex字节码文件。Dex指令:Dex指令是Android虚拟机执行的底层操作码,通过寄存器架构直接操作数据和控制逻辑。每条指令由opcode和操作数组成。如,常见的opcode如const、move、invoke等,const/4表示将立即数存入寄存器。 阅读详情

本文基于Android 7.1,不过因为从BSP拿到的版本略有区别,所以本文提到的源码未必与读者找到的源码完全一致。本文在提供源码片断时,将按照 <源码相对android工程的路径>:<行号> <类名> <函数名> 的方式,如果行号对不上,请参考类名和函数名来找到对应的源码。

本节介绍ClassDef的格式。ClassDef是Dex文件内部表示一个类的结构。包含了类的基本数据,如类的名称,访问级别,Field列表,Method列表等信息。

如何找到一个ClassDef?

在dex文件的header中,有一个class_defs_off_和class_defs_size_的成员,表示classdef的位置与ClassDef的数量。
art/runtime/dex_file.h:90

  // Raw header_item.
  struct Header { 
  ....
    uint32_t class_defs_size_;  // number of ClassDefs
    uint32_t class_defs_off_;  // file offset of ClassDef array
    ....
};

如果要获取一个ClassDef数据,只需要用dex文件的base地址加上偏移即可:

ClassDef * pclassDef = ((ClassDef*)(base + header->class_defs_off_))[class_def_index];

这个base是包括了Header在内的整个dex文件的开头。

ClassDef的格式

ClassDef格式的定义如下:
art/runtime/dex_file.h:210

  // Raw class_def_item.
  struct ClassDef {                                                                                                                  
    uint16_t class_idx_;  // index into type_ids_ array for this class
    uint16_t pad1_;  // padding = 0
    uint32_t access_flags_;
    uint16_t superclass_idx_;  // index into type_ids_ array for superclass
    uint16_t pad2_;  // padding = 0
    uint32_t interfaces_off_;  // file offset to TypeList
    uint32_t source_file_idx_;  // index into string_ids_ for source file name
    uint32_t annotations_off_;  // file offset to annotations_directory_item
    uint32_t class_data_off_;  // file offset to class_data_item
    uint32_t static_values_off_;  // file offset to EncodedArray
....
  • class_idx_: 指向typeIds数组的索引,一个TypeId结构,包含的是类的名称。比如一个类Activity,
    这个类的名称就是“android/app/Activity”;
  • access_flags_: 访问权限,是个掩码值,可以是kAccPublic/kAccPrivate/kAccProtected, kAccInterface/kAccAbstract/ kAccAnontation/kAccEnum等值,详细见 art/runtime/modifiers.h:24
  • superclass_idx_ 这是超类的TypeId索引
  • interfaces_off_ 如果该类implements了interface,interface的信息就会放在这里
  • source_file_idx_:所属的源文件的stringId索引
  • annotations_off_: 该类内部用到的声明的偏移
  • class_data_off_: 类数据的偏移,类数据主要指field和method的定义
  • static_values_off_: static final值的列表,只包括基本类型的值(如int, long, char, byte,float, double,short)

interfaces_off_相关的结构

DexFile::GetInterfaceList函数能够获得一个Interface列表,它的实现很简单:
art/runtime/dex_file.h:717
c++
const TypeList* GetInterfacesList(const ClassDef& class_def) const {
if (class_def.interfaces_off_ == 0) {
return nullptr;
} else {
const uint8_t* addr = begin_ + class_def.interfaces_off_;
return reinterpret_cast<const TypeList*>(addr);
}
}

TypeList是在上篇文章中,介绍Method的参数列表时提到过,这里也用到了这个结构:
art/runtime/dex_file.h:245
c++
// Raw type_item.
struct TypeItem {
uint16_t type_idx_; // index into type_ids section
....
};
// Raw type_list.
class TypeList {
...
private:
uint32_t size_; // size of the list, in entries
TypeItem list_[1]; // elements of the list
DISALLOW_COPY_AND_ASSIGN(TypeList);
};

可以很容易看出,interfaces_off_指出了一个interface类名索引的数组

Class_data_off_

class_data实际上是Field和Method的数据列表,但是因为数据长度不固定,所以不能用一个结构直接给出。class data使用了LEB128编码(详细参阅这里)
ART提供了一个ClassDataItemIterator的类,可以遍历其中的数据。它的重要函数有:

  • void Next(): 获取下个数据
  • bool HasNext():是否有下个数据,这个数据可能是field或者method
  • HasNextStaticFiled/HasNextInstanceFiled, HasNextDirectMethod, HasNextVirtualMethod
  • GetMemberIndex 获取Field在FieldIds中的索引,或者Method在MethodIds中的索引。用这个索引可以得到一个FieldId对象或者MethodId对象
  • GetRawMemberAccessFlags 获取Field或者Method的访问标志
  • GetFieldAccessFlags 获取Field的访问标志,实际上就是从GetRawMemberAccessFlags中获取和Field相关的标志
  • GetMethodAccessFlags,与GetFieldAccessFlags类似,获取的是Method相关的标志
  • GetMethodInvokeType,获取Method调用的方式。Method有以下几种调用方式:
    • invoke-virtual: 调用虚函数专用
    • invoke-direct: 调用private函数、构造函数专用
    • invoke-super: 调用super函数专用
    • invoke-static: 调用静态函数专用
    • invoke-interface: 调用interface的函数时专用
  • GetMethodCodeItem 获取mehtod的代码信息

实际上,上面只是一个封装类的用法,下面我们解析下class_data的各个部分及结构。我们可以用DexFile::GetClassData方法得到一个class_def的class data数据,这个数据包含下面几个部分:(注意,它们都是LEB128编码格式)

Header LEB128 int static field size 静态域的大小,以字节为单位
LEB128 int instance field size 实例域的大小,以字节为单位
LEB128 int direct method size 直接method的大小,包括super method, static method, private method, 构造函数等
LEB128 int virtual method size 虚函数的大小
Field 结构 LEB128 int field index delta 相对于上个field index的差值
LEB128 unsigned int access_flags 访问标志
Method 结构 LEB128 int Method index delta 相对于上个Method index的差值
LEB128 unsigned int access_flags 访问标志 LEB128 int
code_off 代码CodeItem数据结构的编译,相对于dex文件的

static_values_off

通过DexFile::GetEncodedStaticFieldValuesArray就可以获得一个uint8_t*指针,保存的就是static value的数据。这也是一个LEB128编码格式,ART同样提供了一个EncodedStaticFieldValueIterator类来迭代获取对应的值。它的结构是这样的

header LEB128 unsigned int array size 以字节为单位的数组的长度
一个元素的结构 uint8_t value type 值的类型,值必须是 kBoolean, kByte, kShort, kChar, kInt, kLong, kFloat, kDouble, kString, kType或者kNull中的一个
LEB128 int/longvalue 保存的具体value值

这个表的用法要和上面class_data内部的static field配合使用。在这里,一个static field对应一个 static value,它们按照顺序严格对应。如果:

  • static field没有值,就会有一个kNull对应;
  • static field是一个指向一个class,就会有一个kType对应
  • static field是一个Object,需要通过new或者访问其他类的静态域来实现,这里则直接给出kNull值,而在类初始化的时候,才调用相关的代码来进行赋值。

annotations_off

这一部分是介绍java的声明的数据。声明有些时候是编译时用的,有些时候是运行时用的,因为结构复杂但是用的却不多,我们这里就不详细展开了,后面将专门开辟一篇文章介绍它。

至此,ClassDef的主体内容就介绍完成了,下面的文章,我将详细介绍CodeItem的结构。

Android(Android Runtime,ART)如何加载dex文件; 什么是主dex? Android Runtime (ART) 和 Dalvik\ dex2oat 主要 DEX 文件 (classes.dex)当您构建应用时,Android 构建工具会根据需要构造主要 DEX 文件 (classes.dex) 和辅助 DEX 文件(classes2.dex 和 classes3.dex 等)。然后,构建系统会将所有 DEX 文件打包到 APK 中。在运行时,MultiDex API 使用特殊的类加载器来搜索适用于您的方法的所有 DEX 文件,而不是只在主 classes.dex 文件中搜索。 阅读详情

相关推荐

Android运行时文件格式解析:DEX、ODEX、OAT、VDEX与ART

Android应用的运行依赖于多种特殊的二进制文件格式,其中DEX文件作为基础字节码容器,包含了Java/Kotlin代码编译后的Dalvik指令集。随着ART运行时的引入,Android采用了AOT编译技术,将字节码转换为本地机器码,显著提升了执行效率。这一过程生成了OAT文件(ELF格式的本地代码容器)和优化后的ODEX文件。在Android 8.0及更高版本中,系统进一步引入了VDEX文件来分离验证信息,优化应用更新流程。理解这些文件格式的工作原理对于性能优化、存储空间管理和兼容性处理都至关重要,特别

weixin_31856057的博客 265

【Android 逆向】ART 脱壳 ( InMemoryDexClassLoader 脱壳 | DexFile 构造函数及相关调用函数 | Android 源码中查找 native 函数 )

一、DexFile 构造函数、 二、DexFile.openInMemoryDexFile 函数、 三、Android 源码中查找 native 函数、

让 学习 成为一种 习惯 ( 韩曙亮 の 技术博客 ) 1681

ART深入浅出(7) - OAT文件的格式

本文基于Android 7.1,不过因为从BSP拿到的版本略有区别,所以本文提到的源码未必与读者找到的源码完全一致。本文在提供源码片断时,将按照 : 的方式,如果行号对不上,请参考类名和函数名来找到对应的源码。 从本章开始,我将介绍OAT文件的格式 以ELF文件格式作为外壳 从手机上下载一个oat文件。一般我都是研究boot.oat。比如,用命令 adb pull /data/da

doon的专栏 4086

Java虚拟机ART 读书笔记 第3章 深入理解Dex文件格式

Java平台上,字节序采用的是Big Endian,class文件也是,而Android平台上的Dex文件默认的字节序是Little Endian(这可能是因为ARM CPU(也包括X86CPU)采用的也是Little endian字节序的原因吧)。参数组合的格式也有要求,不同的字符代表不同的参数,参数的比特位长度又是由字符的个数决定。比如:A表示一个占4比特的参数,AA代表一个占8比特的参数,AAAA代表一个16比特长的参数。比如øø表示这样一个参数,这个参数长度为8位,每位的取值都是0。

Godam 1089

一篇文章让你清楚DVM、JVM、ART、JIT、ODEX、VDEX、DEX、oat

DVM 和 JVM的区别 1、DVM基于寄存器,JVM基于栈。 DVM效率要更高 解释为什么寄存器效率更高? a、 因为寄存器是CPU中的一部分, 堆栈是内存的一种结构。 内存是CPU和硬盘之间的通道。 寄存器是CPU的储存器,速度快。 b、 一个是直接对CPU进行操作,一个是对内存操作,然后在转化成CPU指令操作。所以寄存器效率更...

weixin_39079048的博客 2558

Android逆向工程-基础概念:Arm、Art、Dalvik、Smali、dex、NDK、JNI之间的关系

Android逆向工程-基础概念:Arm、Art、Dalvik、Smali、dex、NDK、JNI之间的关系 接触逆向以来遇到过Smali、dex几个概念,接触脱壳的时候又遇到ART、Dalvik、的概念,.so文件逆向的时候接触到Arm汇编、NDK、JNI的概念,今天简单梳理下这几者的关系。 一、Dalvik虚拟机 安卓(Android)是google收购的...

siphre 1556

[原创]FART正餐前甜点:ART下几个通用简单高效的dump内存中dex方法--第二篇

FART正餐前甜点:ART下几个通用简单高效的dump内存中dex方法 本篇是对FART后续的补充,以及在实现FART过程中偶然发现的几个通用简单高效的脱壳方法,在FART后续的实现中,对内存中整体dex的dump也已经换成该方法来实现。该方法可以说简单高效并且实现也较为简单,可以很轻松通过xposed或者frida等hook框架通过很短的代码便能够实现对加固应用的脱壳。同时,该方法通用性较强。...

zhangmiaoping23的专栏 749

【Android4.4.4.4_r1系统源码】DexFile.h

/* * Access .dex (Dalvik Executable Format) files. The code here assumes that * the DEX file has been rewritten (byte-swapped, word-aligned) and that * the contents can be directly accessed as a collection of C arrays. Please * see docs/dalvik/dex-format.html for a detailed description. * * The structure and field names were chosen to match those in the DEX spec. * * It's generally assumed that the DEX file will be stored in shared memory, * obviating the need to copy code and constant pool entries into newly * allocated storage. Maintaining local pointers to items in the shared area * is valid and encouraged. * * All memory-mapped structures are 32-bit aligned unless otherwise noted. */

分享一个自己做的函数抽取壳

一、概述 项目中慢慢开始,写一些简单的 kotlin类了,挺方便的一个语言,借鉴了不少脚本语言的特点。刚开始用,有些点经常要翻越,特别记录下。 二、常用的几个复合符号 《Kotlin 实战》小人系列,的这本书里 画的图很清晰了,我又重画了一遍。 2.1、 ?.安全调用符 !这里写图片描述 if (foo != null){ return foo.bar() }else{ return null } 1 2 3 4 5 6 2.2、 ?: 2.3、 as? 2.4、 !! ...

zhangmiaoping23的专栏 1329

关于RT-Thread中PWM无法正常输出的学习

按照官方的PWM配置,并没有输出PWM,网上有比较多的办法,试了很多,有些还是不能实现输出,这里做个记录。记录自己完成PWM输出的过程,以及修改的地方。 关于STM32CubeMX配置就不多说了,网上有很多。 首先必定是按照流程来,一定一定按照流程来!!! 需要注意的是加上通道数!!!! 这是流程上没有的,也是RTT的一点小BUG吧 配上board.c中添加的代码,我用的是PA2定时2的通道3,需要使用的朋友修改对应定时器和GPIO! void HAL_TIM_Base_MspInit(TIM_Han

weixin_42566346的博客 3554

F280049C Buffered Digital-to-Analog Converter (DAC)

使用DAC模块很简单,只需要配置参考电压,并写入DACVALS寄存器一个数字值即可。参考电压可配置为外部参考VDAC和内部参考电压1.65V和2.5V,并结合增益作为DAC模块最终的参考电压DACREF。举个例子,配置参考电压为内部参考电压1.65V,增益设置为2,则参考电压DACREF=3.3V,若向DACVALS写入数字值2048,则输出的DAC模块的输出带电压DACOUT=DACVALS×DACREF4096=1.65VDACOUT=

xht2403267701的博客 2369

从Android运行时出发,打造我们的脱壳神器

0x00 前言 之前对Android的两个运行时的源码做了一些研究,又加上如火如荼的Android加固服务的兴起,便产生了打造一个用于脱壳的运行时,于是便有了DexHunter的诞生(源码:https://github.com/zyq8709/DexHunter/)。今天,我就通过这篇小文聊聊我的一些简单的思路,供大家参考和讨论。 0x02 相关机制 首先,先来看一看An

燕十二的BLOG 2434

10X Visium空间转录组学入门:从芯片结构到数据分析全流程解析(附避坑指南)

本文全面解析10X Visium空间转录组学技术,从芯片物理结构、探针化学原理到湿实验全流程操作与避坑指南,并详细介绍了从FASTQ数据到空间可视化的核心分析流程。文章旨在帮助科研人员跨越从理论到实操的鸿沟,掌握从样本准备、文库构建到使用Space Ranger和Seurat进行数据分析与可视化的完整路径,为组织生物学研究提供清晰的实践指引。

weixin_29306011的博客 163

Android[art]-Android dex,odex,oat,vdex,art文件结构学习总结

参考学习博客: Android Dex文件格式(一):https://blog.youkuaiyun.com/p312011150/article/details/80501690 dex文件解析(第三篇) :https://blog.youkuaiyun.com/tabactivity/article/details/78950379 Android安全–Dex文件格式详解:https://www.cnblogs.co...

TaylorPotter的博客 9952

Qwen2.5-7B大模型实战:从零部署到高效推理全流程解析

本文详细解析了Qwen2.5-7B大模型从零部署到高效推理的全流程。内容涵盖环境准备、模型下载、使用Transformers进行核心对话推理,并深入介绍了vLLM与TGI生产级服务部署、GPTQ/AWQ量化技术以降低显存消耗,以及llama.cpp、Ollama等本地推理方案。旨在帮助开发者快速掌握部署技巧,实现大模型在消费级硬件上的高效运行。

weixin_29061425的博客 490

纯JS实现SM3加密算法(兼容IE浏览器)

纯JS实现SM3加密,IE、谷歌、火狐等浏览器可以直接使用。

qianpou的博客 7352

Android dex、odex、oat、vdex、art区别

1.dex java程序编译成class后,dx工具将所有class文件合成一个dex文件,dex文件是jar文件大小的50%左右. 2.odex(Android5.0之前)全称:Optimized DEX;即优化过的DEX. Android5.0之前APP在安装时会进行验证和优化,为了校验代码合法性及优化代码执行速度,验证和优化后,会 产生ODEX文件,运行Apk的时候,直接加载ODEX,避...

Android系统攻城狮 8126

Open3D (C++) 泊松重建【2025最新版】

使用C++版本的Open3D实现点云的泊松重建

点云侠的博客 3073

Android Dex文件详解

前言 相信大家都熟悉dex文件,把一个apk给解压缩,就会得到一堆dex文件,但是这些dex文件是怎么来的,又有什么用,为什么这样设计,有进行思考过吗 俗话说知其然,知其所以然,本篇文章开始探究一下这些底层实现细节。 正文 不同的虚拟机 JVM JVM是Java Virtual Machine的简称,即Java虚拟机,它本质是一层软件抽象,在这之上才可以运行Java程序。Java文件经过编译后会生成JVM字节码,和C语言编译后生成的汇编语言不同,C编译成的汇编语言可以直接在硬件上跑,但是Java编译生成的字

Misdirection_XG的博客 8283

【中国大学生计算机设计大赛信息可视化赛道】国奖项目深入剖析—中国古代奇异怪兽移动端可视化应用项目

【中国大学生计算机设计大赛信息可视化赛道】国奖项目深入剖析—中国古代奇异怪兽移动端可视化应用项目 注:本文主要目的是对于往年国奖项目案例-可视化项目的深入剖析讲解,对源码、项目特点、要点、特色继续深入分析。帮助大家学习技术,掌握规律。

一键难忘的博客 3729

Nova — GPU/vGPU 虚拟机

目录 文章目录目录云主机使用显卡的实现方式虚拟显卡物理显卡直通物理显卡虚拟化 云主机使用显卡的实现方式 采用虚拟显卡 采用物理显卡直通 采用物理显卡虚拟化 虚拟显卡 虚拟显卡技术,主要用于虚拟机 Remote Console 领域,如:VNC(Virtual Network Computing,虚拟网络计算机),它能将完整的窗口界面通过网络,传输到另一台计算机的屏幕上。 VNC 主要由 VNC server 和 VNC viewer 两部分组成。用户需先将 VNC server 安装在被远程操控的计算

烟云的计算 2426

Android .dex、.odex、Dalvik、ART、AOT、OAT

文章来源:https://www.jianshu.com/p/e52b7e460748 https://zhuanlan.zhihu.com/p/53723652 目的 理清 .dex、.odex、ART、AOT、OAT 等近似名称的概念和意义。 APK 生成 最终 apk 内的代码文件为 .dex 文件。 APK 安装运行 基础概念 **AOT:**编译方式,运行前编译。AOT是指"Ahead Of Time",与"Just In Time"不同,从字面来看是说提前编译。JIT是运行时编译,是动态编译,

u013750244的博客 2249

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

android studio 输出apk过程,apk中的文件格式(bsh文件,dex文件),JVM、DVM、ART的区别,IOS与安卓的区别,ART和Dalvik

目录 android studio 输出apk过程 bsh文件: dex文件: Android 知识:JVM、DVM、ART的区别: ART虚拟机 将apk文件使用360加压边可以看到Android studio 打包后输出的apk内在文件 IOS与安卓的区别: android studio 输出apk过程 1.通过aapt打包res资源文件,生成R.java、res...

ZhangJiqun&191cm&85kg 2243

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

android odex版本调试_android 基础-Dalvik ,ART,JIT,AOT,Dex,Odex

Dalvik 和 ARTDalvik:Dalvik 虚拟机,android 5.0 以前所使用的虚拟机,可执行文件为 dex 格式,基于寄存器的虚拟机(jvm 基于堆栈)。通过 dx 工具将 .class 文件转换为 .dex 格式。ART:android rutime,android 5.0 以后使用的虚拟机。关于这个虚拟机的点,希望了解的关注点在于虚拟机这块。ios 和 android对比,a...

weixin_39929254的博客 743

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

浅谈 Android Dex 文件

概述 为什么要了解 Dex 文件 了解了 Dex 文件以后,对日常开发中遇到一些问题能有更深的理解。如:APK 的瘦身、热修复、插件化、应用加固、Android 逆向工程、64 K 《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》开源 方法数限制。 什么是 Dex 文件 在明白什么是 Dex 文件之前,要先了解一下 JVM,Dalvik 和 ART。JVM 是 JAVA 虚拟机,用来运行 JAVA 字节码程序。Dalvik 是 Google 设计的用于 Android平

m0_54851114的博客 2653

apk dex vdex odex art 区别

APK(Android package):android安装包,由aapt(Android Assert Packaging Tool)把AndroidManifest.xml、资源文件、dex(二进制字节码)文件组合而成。将apk文件修改扩展名为rar,然后解压可已看到目录如下: apk METE-INF:存放应用签名证书等信息 res:存放资源文件 AndroidManifest....

c_z_w的博客 2036
上一篇: ART深入浅出4--了解Dex文件格式(1)
下一篇: ART深入浅出6--了解Dex文件格式(3)
漂流的代码
博客等级 码龄23年 188粉丝 99原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值