100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > 【Java 虚拟机原理】Dalvik 虚拟机 ( 打包 Jar 文件和 Dex 文件 | 反编译

【Java 虚拟机原理】Dalvik 虚拟机 ( 打包 Jar 文件和 Dex 文件 | 反编译

时间:2022-11-11 00:42:08

相关推荐

【Java 虚拟机原理】Dalvik 虚拟机 ( 打包 Jar 文件和 Dex 文件 | 反编译

文章目录

前言一、打包 Jar 文件和 Dex 文件1、示例代码2、打包 Jar 文件3、打包 Dex 文件二、反编译 Dex 文件三、分析 Dex 文件1、Student 类相关信息2、User 类相关信息

前言

Dalvik 虚拟机运行的是 Dex 文件 ; Dex 文件并不是最终 DVM 运行的文件 , Dex 文件还需要再次优化为 Odex 文件 , 这才是最终运行在 DVM 上的文件 ;

安装 APK 完毕后 , 运行时 , 或者 使用类加载器加载 Dex 文件时 , 才会生成 Odex 文件 ;

Odex 文件会存放在 /data/dalvik-cache 目录下 ;

一、打包 Jar 文件和 Dex 文件

Dalvik 虚拟机中运行的是 Dex 文件 , Java 虚拟机运行的是 Jar 文件 ;

1、示例代码

示例代码 :

代码 111 :

public class Student {private String name;private int age;public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public void ageIncrease(){synchronized(this) {this.age++;}}}

代码 222 :

public class User {private int age = 0;public synchronized void increase() {this.age++;}}

2、打包 Jar 文件

打包 Jar 文件 :

使用如下命令 , 将 Class 字节码文件打成 Jar 包 :

jar cvf main.jar Student.class User.class

输出结果 :

D:\002_Project\004_Java_Learn\Main\out\production\Main>jar cvf main.jar Student.class User.class已添加清单正在添加: Student.class(输入 = 889) (输出 = 478)(压缩了 46%)正在添加: User.class(输入 = 356) (输出 = 251)(压缩了 29%)

3、打包 Dex 文件

打包 Dex 文件 :

首先配置下环境变量 , 将编译工具目录配置到环境变量中 , 这里选择使用 30.0.3 版本的编译工具 ( build-tools ) ;

D:\001_Develop\001_SDK\Sdk\build-tools\30.0.3

配置到环境变量 Path 中 ;

执行

dx --dex --output main.dex main.jar

命令 , 打包 Dex 文件 , 命令行输出 :

打包后的 main.dex 文件 ;

二、反编译 Dex 文件

使用如下命令 , 反编译 Dex 文件 :

dexdump -d -l plain main.dex

输出 Dex 文件的内容 :

D:\002_Project\004_Java_Learn\Main\out\production\Main>dexdump -d -l plain main.dexProcessing 'main.dex'...Opened 'main.dex', DEX version '035'Class #0 -Class descriptor : 'LStudent;'Access flags: 0x0001 (PUBLIC)Superclass : 'Ljava/lang/Object;'Interfaces -Static fields-Instance fields -#0 : (in LStudent;)name: 'age'type: 'I'access : 0x0002 (PRIVATE)#1 : (in LStudent;)name: 'name'type: 'Ljava/lang/String;'access : 0x0002 (PRIVATE)Direct methods -#0 : (in LStudent;)name: '<init>'type: '()V'access : 0x10001 (PUBLIC CONSTRUCTOR)code-registers: 1ins : 1outs: 1insns size : 4 16-bit code units0001b8:|[0001b8] Student.<init>:()V0001c8: 7010 0800 0000|0000: invoke-direct {v0}, Ljava/lang/Object;.<init>:()V // method@00080001ce: 0e00|0003: return-voidcatches : (none)positions:0x0000 line=1locals :0x0000 - 0x0004 reg=0 this LStudent;Virtual methods -#0 : (in LStudent;)name: 'ageIncrease'type: '()V'access : 0x0001 (PUBLIC)code-registers: 2ins : 1outs: 0insns size : 12 16-bit code units0001d0:|[0001d0] Student.ageIncrease:()V0001e0: 1d01|0000: monitor-enter v10001e2: 5210 0000|0001: iget v0, v1, LStudent;.age:I // field@00000001e6: d800 0001|0003: add-int/lit8 v0, v0, #int 1 // #010001ea: 5910 0000|0005: iput v0, v1, LStudent;.age:I // field@00000001ee: 1e01|0007: monitor-exit v10001f0: 0e00|0008: return-void0001f2: 0d00|0009: move-exception v00001f4: 1e01|000a: monitor-exit v10001f6: 2700|000b: throw v0catches : 10x0001 - 0x000b<any> -> 0x0009positions:0x0000 line=220x0001 line=230x0007 line=240x0008 line=250x0009 line=24locals :0x0000 - 0x000c reg=1 this LStudent;#1 : (in LStudent;)name: 'getAge'type: '()I'access : 0x0001 (PUBLIC)code-registers: 2ins : 1outs: 0insns size : 3 16-bit code units000204:|[000204] Student.getAge:()I000214: 5210 0000|0000: iget v0, v1, LStudent;.age:I // field@0000000218: 0f00|0002: return v0catches : (none)positions:0x0000 line=14locals :0x0000 - 0x0003 reg=1 this LStudent;#2 : (in LStudent;)name: 'getName'type: '()Ljava/lang/String;'access : 0x0001 (PUBLIC)code-registers: 2ins : 1outs: 0insns size : 3 16-bit code units00021c:|[00021c] Student.getName:()Ljava/lang/String;00022c: 5410 0100|0000: iget-object v0, v1, LStudent;.name:Ljava/lang/String; // field@0001000230: 1100|0002: return-object v0catches : (none)positions:0x0000 line=6locals :0x0000 - 0x0003 reg=1 this LStudent;#3 : (in LStudent;)name: 'setAge'type: '(I)V'access : 0x0001 (PUBLIC)code-registers: 2ins : 2outs: 0insns size : 3 16-bit code units000234:|[000234] Student.setAge:(I)V000244: 5901 0000|0000: iput v1, v0, LStudent;.age:I // field@0000000248: 0e00|0002: return-voidcatches : (none)positions:0x0000 line=180x0002 line=19locals :0x0000 - 0x0003 reg=0 this LStudent;0x0000 - 0x0003 reg=1 age I#4 : (in LStudent;)name: 'setName'type: '(Ljava/lang/String;)V'access : 0x0001 (PUBLIC)code-registers: 2ins : 2outs: 0insns size : 3 16-bit code units00024c:|[00024c] Student.setName:(Ljava/lang/String;)V00025c: 5b01 0100|0000: iput-object v1, v0, LStudent;.name:Ljava/lang/String; // field@0001000260: 0e00|0002: return-voidcatches : (none)positions:0x0000 line=100x0002 line=11locals :0x0000 - 0x0003 reg=0 this LStudent;0x0000 - 0x0003 reg=1 name Ljava/lang/String;source_file_idx : 7 (Student.java)Class #1 -Class descriptor : 'LUser;'Access flags: 0x0001 (PUBLIC)Superclass : 'Ljava/lang/Object;'Interfaces -Static fields-Instance fields -#0 : (in LUser;)name: 'age'type: 'I'access : 0x0002 (PRIVATE)Direct methods -#0 : (in LUser;)name: '<init>'type: '()V'access : 0x10001 (PUBLIC CONSTRUCTOR)code-registers: 2ins : 1outs: 1insns size : 7 16-bit code units000264:|[000264] User.<init>:()V000274: 7010 0800 0100|0000: invoke-direct {v1}, Ljava/lang/Object;.<init>:()V // method@000800027a: 1200|0003: const/4 v0, #int 0 // #000027c: 5910 0200|0004: iput v0, v1, LUser;.age:I // field@0002000280: 0e00|0006: return-voidcatches : (none)positions:0x0000 line=10x0003 line=2locals :0x0000 - 0x0007 reg=1 this LUser;Virtual methods -#0 : (in LUser;)name: 'increase'type: '()V'access : 0x20001 (PUBLIC DECLARED_SYNCHRONIZED)code-registers: 2ins : 1outs: 0insns size : 12 16-bit code units000284:|[000284] User.increase:()V000294: 1d01|0000: monitor-enter v1000296: 5210 0200|0001: iget v0, v1, LUser;.age:I // field@000200029a: d800 0001|0003: add-int/lit8 v0, v0, #int 1 // #0100029e: 5910 0200|0005: iput v0, v1, LUser;.age:I // field@00020002a2: 1e01|0007: monitor-exit v10002a4: 0e00|0008: return-void0002a6: 0d00|0009: move-exception v00002a8: 1e01|000a: monitor-exit v10002aa: 2700|000b: throw v0catches : 10x0001 - 0x0007<any> -> 0x0009positions:0x0000 line=50x0007 line=60x0009 line=5locals :0x0000 - 0x000c reg=1 this LUser;source_file_idx : 8 (User.java)D:\002_Project\004_Java_Learn\Main\out\production\Main>

三、分析 Dex 文件

1、Student 类相关信息

#0号 Class 类 , 类描述符是LStudent;, 父类Ljava/lang/Object;

Processing 'main.dex'...Opened 'main.dex', DEX version '035'Class #0 -Class descriptor : 'LStudent;'Access flags: 0x0001 (PUBLIC)Superclass : 'Ljava/lang/Object;'

该类中有 222 个字段 , 分别是 name 和 age ;

Instance fields -#0 : (in LStudent;)name: 'age'type: 'I'access : 0x0002 (PRIVATE)#1 : (in LStudent;)name: 'name'type: 'Ljava/lang/String;'access : 0x0002 (PRIVATE)

构造函数方法 :

Direct methods -#0 : (in LStudent;)name: '<init>'type: '()V'access : 0x10001 (PUBLIC CONSTRUCTOR)code-registers: 1ins : 1outs: 1insns size : 4 16-bit code units

增加年龄方法 :

public void ageIncrease(){synchronized(this) {this.age++;}}

对应

Virtual methods -#0 : (in LStudent;)name: 'ageIncrease'type: '()V'access : 0x0001 (PUBLIC)code-registers: 2ins : 1outs: 0insns size : 12 16-bit code units

其它方法省略 ;

2、User 类相关信息

第 222 个类 编号#1, 是 User 类 , 类描述符LUser;, 有age字段 ;

Class #1 -Class descriptor : 'LUser;'Access flags: 0x0001 (PUBLIC)Superclass : 'Ljava/lang/Object;'Interfaces -Static fields-Instance fields -#0 : (in LUser;)name: 'age'type: 'I'access : 0x0002 (PRIVATE)

构造方法反编译内容如下 :

Direct methods -#0 : (in LUser;)name: '<init>'type: '()V'access : 0x10001 (PUBLIC CONSTRUCTOR)code-registers: 2ins : 1outs: 1insns size : 7 16-bit code units

void increase()方法对应反编译内容 :

Virtual methods -#0 : (in LUser;)name: 'increase'type: '()V'access : 0x20001 (PUBLIC DECLARED_SYNCHRONIZED)code-registers: 2ins : 1outs: 0insns size : 12 16-bit code units

【Java 虚拟机原理】Dalvik 虚拟机 ( 打包 Jar 文件和 Dex 文件 | 反编译 Dex 文件 | 分析 Dex 文件反编译结果 )

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。