日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

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

發布時間:2025/6/17 java 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Java 虚拟机原理】Dalvik 虚拟机 ( 打包 Jar 文件和 Dex 文件 | 反编译 Dex 文件 | 分析 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.dex Processing '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 units 0001b8: |[0001b8] Student.<init>:()V 0001c8: 7010 0800 0000 |0000: invoke-direct {v0}, Ljava/lang/Object;.<init>:()V // method@0008 0001ce: 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 units 0001d0: |[0001d0] Student.ageIncrease:()V 0001e0: 1d01 |0000: monitor-enter v1 0001e2: 5210 0000 |0001: iget v0, v1, LStudent;.age:I // field@0000 0001e6: d800 0001 |0003: add-int/lit8 v0, v0, #int 1 // #01 0001ea: 5910 0000 |0005: iput v0, v1, LStudent;.age:I // field@0000 0001ee: 1e01 |0007: monitor-exit v1 0001f0: 0e00 |0008: return-void 0001f2: 0d00 |0009: move-exception v0 0001f4: 1e01 |000a: monitor-exit v1 0001f6: 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 units 000204: |[000204] Student.getAge:()I 000214: 5210 0000 |0000: iget v0, v1, LStudent;.age:I // field@0000 000218: 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 units 00021c: |[00021c] Student.getName:()Ljava/lang/String; 00022c: 5410 0100 |0000: iget-object v0, v1, LStudent;.name:Ljava/lang/String; // field@0001 000230: 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 units 000234: |[000234] Student.setAge:(I)V 000244: 5901 0000 |0000: iput v1, v0, LStudent;.age:I // field@0000 000248: 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 units 00024c: |[00024c] Student.setName:(Ljava/lang/String;)V 00025c: 5b01 0100 |0000: iput-object v1, v0, LStudent;.name:Ljava/lang/String; // field@0001 000260: 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 units 000264: |[000264] User.<init>:()V 000274: 7010 0800 0100 |0000: invoke-direct {v1}, Ljava/lang/Object;.<init>:()V // method@0008 00027a: 1200 |0003: const/4 v0, #int 0 // #0 00027c: 5910 0200 |0004: iput v0, v1, LUser;.age:I // field@0002 000280: 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 units 000284: |[000284] User.increase:()V 000294: 1d01 |0000: monitor-enter v1 000296: 5210 0200 |0001: iget v0, v1, LUser;.age:I // field@0002 00029a: d800 0001 |0003: add-int/lit8 v0, v0, #int 1 // #01 00029e: 5910 0200 |0005: iput v0, v1, LUser;.age:I // field@0002 0002a2: 1e01 |0007: monitor-exit v1 0002a4: 0e00 |0008: return-void 0002a6: 0d00 |0009: move-exception v0 0002a8: 1e01 |000a: monitor-exit v1 0002aa: 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 文件反编译结果 )的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。