目的拆解分析反編譯字節碼 解析成人能夠理解的結構 ,然后再對字節碼文件進一步分析
源代碼
- public class test {
- private static int classV =2;
- public static void main(String[] args) {
- classV =200;
- int localV =4;
- localV =400;
- }
- }
二進制 idea bin_ed插件查看。
看不懂 那就使用人能看的懂的匯編語言查看類文件結構和代碼指令。
javap 指令和選項
0:無選項
- 打印package, protected and public fields, and methods
- public class com.example.test {
- public com.example.test();
- public static void main(java.lang.String[]);
- static {};
- }
1:輔助指令
-help –help -?
2:代碼行號和方法的局部變量表
-l
- public class com.example.test {
- //默認構造方法
- public com.example.test();
- //代碼行號:命令偏移位置
- LineNumberTable:
- line 3: 0
- //局部變量表
- LocalVariableTable:
- Start Length Slot Name Signature
- 0 5 0 this Lcom/example/test;
- public static void main(java.lang.String[]);
- //代碼行號:命令偏移位置
- LineNumberTable:
- line 6: 0
- line 7: 6
- line 8: 8
- line 9: 12
- //局部變量表
- LocalVariableTable:
- Start Length Slot Name Signature
- 0 13 0 args [Ljava/lang/String; //方法參數
- 8 5 1 localV I。/局部變量localV
- //靜態代碼塊
- static {};
- LineNumberTable:
- line 4: 0
- }
3 用級別過濾方法 屬性 類
-public -protected -private -p
4.反匯編 出匯編指令
javap -c
- //純匯編指令
- public class com.example.test {
- public com.example.test();
- Code:
- 0: aload_0
- 1: invokespecial #1 // Method java/lang/Object."<init>":()V
- 4: return
- public static void main(java.lang.String[]);
- Code:
- 0: sipush 200
- 3: putstatic #2 // Field classV:I
- 6: iconst_4
- 7: istore_1
- 8: sipush 400
- 11: istore_1
- 12: return
- static {};
- Code:
- 0: iconst_2
- 1: putstatic #2 // Field classV:I
- 4: return
- }
5 顯示verbose詳細信息
javap -v
- Classfile /Users/zhangshanxue/Downloads/akka-quickstart-java/target/classes/com/example/test.class
- //javap -sysinfo顯示下面3行
- Last modified 2021-4-5; size 507 bytes
- MD5 checksum 24a0c74751aafd61d0f7f69be9c161db
- Compiled from "test.java"
- public class com.example.test
- //即1.8 對照表和原因見附錄1
- //u2類型 即每個占用兩個字節
- minor version: 0
- major version: 52
- //類標志 見附錄2
- //u2類型access_flags 通過位與表示多個權限
- flags: ACC_PUBLIC, ACC_SUPER
- //常量池。class文件結構重點
- //u2 2兩個字節 表示數量
- //pool 常量池
- //constant_pool_count 和constant_pool[]表示為常量池中內容
- //后面大部分內容依賴此常量池
- Constant pool:
- #1 = Methodref #4.#22 // java/lang/Object."<init>":()V
- #2 = Fieldref #3.#23 // com/example/test.classV:I
- #3 = Class #24 // com/example/test
- #4 = Class #25 // java/lang/Object
- #5 = Utf8 classV
- #6 = Utf8 I
- #7 = Utf8 <init>
- #8 = Utf8 ()V
- #9 = Utf8 Code
- #10 = Utf8 LineNumberTable
- #11 = Utf8 LocalVariableTable
- #12 = Utf8 this
- #13 = Utf8 Lcom/example/test;
- #14 = Utf8 main
- #15 = Utf8 ([Ljava/lang/String;)V
- #16 = Utf8 args
- #17 = Utf8 [Ljava/lang/String;
- #18 = Utf8 localV
- #19 = Utf8 <clinit>
- #20 = Utf8 SourceFile
- #21 = Utf8 test.java
- #22 = NameAndType #7:#8 // "<init>":()V
- #23 = NameAndType #5:#6 // classV:I
- #24 = Utf8 com/example/test
- #25 = Utf8 java/lang/Object
- {
- public com.example.test();
- descriptor: ()V
- flags: ACC_PUBLIC
- Code:
- //代碼匯編指令
- stack=1, locals=1, args_size=1
- 0: aload_0
- 1: invokespecial #1 // Method java/lang/Object."<init>":()V
- 4: return
- //Javap -l顯示下面信息
- //行號和上面對應的指令偏移位置
- LineNumberTable:
- line 3: 0
- LocalVariableTable:
- //局部變量表 在指令偏移位置start start+length之間有效
- Start Length Slot Name Signature
- 0 5 0 this Lcom/example/test;
- public static void main(java.lang.String[]);
- descriptor: ([Ljava/lang/String;)V
- flags: ACC_PUBLIC, ACC_STATIC
- Code:
- //代碼匯編指令
- stack=1, locals=2, args_size=1
- 0: sipush 200
- 3: putstatic #2 // Field classV:I
- 6: iconst_4
- 7: istore_1
- 8: sipush 400
- 11: istore_1
- 12: return
- //Javap -l顯示下面信息
- //行號和上面對應的指令偏移位置
- LineNumberTable:
- line 6: 0
- line 7: 6
- line 8: 8
- line 9: 12
- LocalVariableTable:
- Start Length Slot Name Signature
- 0 13 0 args [Ljava/lang/String;
- 8 5 1 localV I
- static {};
- descriptor: ()V
- flags: ACC_STATIC
- Code:
- stack=1, locals=0, args_size=0
- 0: iconst_2
- 1: putstatic #2 // Field classV:I
- 4: return
- //行號和上面對應的指令偏移位置
- LineNumberTable:
- line 4: 0
- }
附錄1
1.1從45開始因為正式發布之前可能 其他版本號可能已經被用了 1.5改為5.0 也是差不多原因 為了表示重要性更名
Corresponding major version 指定版本 和"Supported major versions"兼容范圍
附錄2
附錄3
直接分析字節碼塊
1為了方便交流表達class文件的結構
使用u1 u2 u4 u8無符號數表示字節數使用*_info 結尾表示池(數組cp_info、field_info、method_info、attribute_info
- ClassFile {
- //表示java class的文件格式 固定為cafe baby 4個字節
- u4 magic;
- //主版本號和次版本號共同決定了類文件格式的版本
- //u2類型 即每個占用兩個字節
- //56包含56以后support for N.0 and N.65535
- u2 minor_version;
- //主版本號56(java12)之前 minjor只支持0
- u2 major_version;
- //常量池數量
- u2 constant_pool_count;
- cp_info constant_pool[constant_pool_count-1];
- u2 access_flags;
- //this_class、super_class、interfaces指向常量池的CONSTANT_Class_info
- u2 this_class;
- u2 super_class;
- u2 interfaces_count;
- u2 interfaces[interfaces_count];
- u2 fields_count;
- //指向常量池structures:CONSTANT_Fieldref_info 結構
- field_info fields[fields_count];
- u2 methods_count;
- //指向常量池CONSTANT_Methodref_info 結構
- method_info methods[methods_count];
- u2 attributes_count;
- attribute_info attributes[attributes_count];
- }
附錄4
常量池字節碼結構和常量池結構部分對應關系
以上就是拆解字節碼文件javap命令的詳細內容,更多關于拆解字節碼文件javap命令的資料請關注服務器之家其它相關文章!
原文鏈接:https://blog.csdn.net/zt011052/article/details/115445687