最近重读了一下深入安卓虚拟机,有很多以前看不太明白的地方都明白了许多,简单总结一下一些dex文件的重要项,之后再把其他一些格式详细总结一下。
java源码
public class HelloWorld {
public static int age;
private String name;
public HelloWorld(int age, String name){
this.age=age;
this.name=name;
};
public static void main(String[] args) {
HelloWorld hw = new HelloWorld(8, "Lic");
System.out.println(hw.name);
System.out.println(hw.age);
System.out.println("Hello World");
};
public static void add(int a, int b){
int res = a+b;
}
}
将上述java源码编译成class文件后再用d8工具转为dex文件后之,进行分析
header
主要就是魔术头,校验和和签名,修改之后需要重新和签名

string_id_item
这个结构的成员为string_data_off和string_data_item,string_data_off是偏移
我们找一个字符串进行位置分析:
由于这里采用LEB128 ( little endian base 128 ) 的格式 ,是基于 1 个 Byte 的一种不定长度的编码方式 。若第一个 Byte 的最高位为 1 ,则表示还需要下一个 Byte 来描述 ,直至最后一个 Byte 的最高位为 0 。每个 Byte 的其余 Bit 用来表示数据 。所以码的每个字节有效部分只有低7bits,每个字节的最高bit用来指示是否是最后一个字节。
所以下图中有一个string_data_off的value为661,0x296的十进制数是662,这就是因为最高位是无效的。(但是其他地方是指的准的,不用+1)

method_id_item
class_idx :表示本 method 所属的 class 类型 , class_idx 的值是 type_ids 的一个 index , 并且必须指向一个 class 类型 。
proto_idx :描述该 method 的原型 ,指向 proto_ids 的一个 index 。
name_idx :表示本 method 的名称 ,它的值是 string_ids 的一个 index 。
同样找一个method来分析

code_item
在class_def较深的一层,和.class文件的code项意思差不多,这里最重要的就是可以对insns这些虚拟机指令做函数抽取和恢复,
