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

歡迎訪問 生活随笔!

生活随笔

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

java

解读Java Class文件格式

發布時間:2025/6/15 java 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 解读Java Class文件格式 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1.目的

大型軟件系統開發時,某些Java組件可能涉及到多種數據庫或中間件系統的連接和應用,例如一個數據傳遞組件需要從DB2中讀取數據,并將數據通過中間件WebSphere MQ發送到其他系統,這類組件功能單一,但卻需要連接多種第三方產品,使得程序員的單元測試變的非常不便,程序員不得不注視或修改部分源代碼,或者在本地安裝所需第三方產品。無疑這兩種選擇都是痛苦的。

基于以上的不便,本文開發了解析Java Class文件程序,目的是將第三方產品APIClass文件轉換為Java源文件(不包括Java類的方法實現),在源文件的各種程序所需的方法里實現一些簡單的語句,例如數據庫連接方法永遠返回true,獲得數據方法永遠返回?”Hello world”?等,用JDK重新編譯轉換后的Java源文件,來替換真正的API?文件,這樣程序員在UT測試時,無需修改源代碼,也無需安裝任何產品,并且能通過修改替換的API Java源文件實施各種UT測試。

為了實現以上需求,必須先要了解Java Class文件格式。Java虛擬機識別的class文件格式包含Java虛擬機指令(或者bytecodes)和一個符號表以及其他的輔助信息。本文將使用VC++語言解析Java Class文件符號表,逆向生成Java源代碼結構。如圖1

??????????????????????????????????????????????????????????????????????????????????????????圖1

之所以使用VC++而不使用Java的主要是因為VC++界面開發簡單;運行速度快,不需要虛擬機;需要用指針建立復雜的數據結構。

2.實現

實現該工具的過程如下:

1.解析Class文件,從Class文件中讀取數據并保存到稱為ClassFile結構體中;

2.解析ClassFile結構體,生成源代碼字符串;

3.將字符串顯示到視圖中。

2.1?解析Class文件

為實現第1步,首先需要了解Class文件格式規范,參考《Java虛擬機規范》第四章class文件格式,總結class文件的數據結構如圖2

2.1.1?Class文件格式

Class文件格式ClassFile結構體的C語言描述如下:

struct?ClassFile

{

??????????????u4 magic;?????????????????????????????????//識別Class文件格式,具體值為0xCAFEBABE

??????????????u2 minor_version;????????????// Class文件格式副版本號,

??????????????u2 major_version;????????????// Class文件格式主版本號,

??????????????u2 constant_pool_count;?//??常數表項個數,

??????????????cp_info **constant_pool;//?常數表,又稱變長符號表,

??????????????u2 access_flags;???????????????//Class的聲明中使用的修飾符掩碼,

??????????????u2 this_class;???????????????????//常數表索引,索引內保存類名或接口名,

??????????????u2 super_class;????????????????//常數表索引,索引內保存父類名,

??????????????u2 interfaces_count;????????//超接口個數,

??????????????u2 *interfaces;?????????????????//常數表索引,各超接口名稱,

??????????????u2 fields_count;???????//類的域個數,

??????????????field_info **fields;??????????//域數據,包括屬性名稱索引,

//域修飾符掩碼等,

??????????????u2 methods_count;??????????//方法個數,

??????????????method_info **methods;//方法數據,包括方法名稱索引,方法修飾符掩碼等,

??????????????u2 attributes_count;????????//類附加屬性個數,

??????????????attribute_info **attributes;?//類附加屬性數據,包括源文件名等。

};

?

其中u2unsigned shortu4unsigned long

typedef unsigned char???u1;

typedef unsigned short??u2;

typedef unsigned long???u4;

?

cp_info **constant_pool是常量表的指針數組,指針數組個數為constant_pool_count,結構體cp_info

struct?cp_info

{

??????????????u1 tag;???????//常數表數據類型

??????????????u1 *info;???//常數表數據

};

常數表數據類型Tag定義如下:

#define?CONSTANT_Class?????????????????????????????????????????7?????

#define?CONSTANT_Fieldref?????????????????????????????????????9

#define?CONSTANT_Methodref????????????????????????????????10

#define?CONSTANT_InterfaceMethodref??????????????????11

#define?CONSTANT_String??????????????????????????????????????????????????????8

#define?CONSTANT_Integer??????????????????????????????????????????????????3

#define?CONSTANT_Float???????????????????????????????????????????????????????4

#define?CONSTANT_Long???????????????????????????????????????????????????????5

#define?CONSTANT_Double??????????????????????????????????????6

#define?CONSTANT_NameAndType?????????????????????????12

#define?CONSTANT_Utf8????????????????????????????????????????????????????????1

每種類型對應一個結構體保存該類型數據,例如CONSTANT_Class?info指針指向的數據類型應為CONSTANT_Class_info

struct?CONSTANT_Class_info

{

??????????????u1 tag;

??????????????u2 name_index;

};

2

CONSTANT_Utf8info指針指向的數據類型應為CONSTANT_Utf8_info

struct?CONSTANT_Utf8_info

{

??????????????u1 tag;

??????????????u2 length;

??????????????u1 *bytes;

};

Taginfo的詳細說明參考《Java虛擬機規范》第四章4.4節。

access_flags為類修飾符掩碼,域與方法都有各自的修飾符掩碼。

#define?ACC_PUBLIC????????????????????????????????0x0001?

#define?ACC_PRIVATE?????????????????????????????0x0002

#define?ACC_PROTECTED???????????????????????????????????0x0004

#define?ACC_STATIC????????????????????????????????0x0008

#define?ACC_FINAL??????????????????????????????????????????????0x0010

#define?ACC_SYNCHRONIZED?????????????????????????0x0020

#define?ACC_SUPER????????????????????????????????????????????????0x0020

#define?ACC_VOLATILE????????????????????????????????????????0x0040

#define?ACC_TRANSIENT??????????????????????????????????????0x0080?

#define?ACC_NATIVE???????????????????????????????0x0100

#define?ACC_INTERFACE??????????????????????????????????????0x0200?

#define?ACC_ABSTRACT???????????????????????????????????????0x0400?

#define?ACC_STRICT??????????????????????????????????????0x0800

例如類的修飾符為public abstractaccess_flags的值為ACC_PUBLIC | ACC_ABSTRACT=0x0401

this_class的值是常數表的索引,索引的info內保存類或接口名。例如類名為com.sum.java.swing.SwingUtitlities2info保存為com/sum/java/swing/SwingUtitlities2

super_class的值是常數表的索引,索引的info內保存超類名,在info內保存形式和類名相同。

interfaces是數組,數組個數為interfaces_count,數組內的元素為常數表的索引,索引的info內保存超接口名,在info內保存形式和類名相同。

field_info **fields是類域數據的指針數組,指針數組個數為fields_count,結構體field_info定義如下:

struct?field_info

{

??????????????u2 access_flags;?????????????????//域修飾符掩碼

??????????????u2 name_index;?????????????????//域名在常數表內的索引

??????????????u2 descriptor_index;??????????//域的描述符,其值是常數表內的索引

??????????????u2 attributes_count;???????????//域的屬性個數

??????????????attribute_info **attributes;?//域的屬性數據,即域的值

?

};

例如一個域定義如下:

private final static byte UNSET=127;

則該域的修飾符掩碼值為:ACC_PRIVATE | ACC_STATIC | ACC_FINAL=0x001A

常數表內name_index索引內保存數據為UNSET,常數表內descriptor_index索引內保存的數據為BB表示byte,?其他類型參考《Java虛擬機規范》第四章4.3.2節)。attributes_count的值為1,其中attributes是指針數組。指針數組個數為attributes_count,在此為1attribute_info結構體如下:

struct?attribute_info

{

??????????????u2 attribute_name_index;???//常數表內索引

??????????????u4 attribute_length;????????????//屬性長度

??????????????u1 *info;?????????????????????????????//根據屬性類型不同而值不同

};?

attribute_info可以轉換(cast)為多種類型ConstantValue_attributeExceptions_attributeLineNumberTable_attributeLocalVariableTable_attributeCode_attribute等。

因為域的屬性只有一種:ConstantValue_attribute,因此此結構體轉換為

struct?ConstantValue_attribute

{

??????????????u2 attribute_name_index;????????//常數表內索引

??????????????u4 attribute_length;?????????????????//屬性長度值,永遠為2

??????????????u2 constantvalue_index;?????????//常數表內索引,保存域的值

//在此例中,常數表內保存的值為127

};

method_info **methods是方法數據的指針數組,指針數組個數為methods_count,結構體method_info定義如下:

struct?method_info

{

??????????????u2 access_flags;???????????????????//方法修飾符掩碼

??????????????u2 name_index;???????????????????//方法名在常數表內的索引

??????????????u2 descriptor_index;????????????//方法描述符,其值是常數表內的索引

??????????????u2 attributes_count;?????????????//方法的屬性個數

??????????????attribute_info **attributes;??//方法的屬性數據,

//保存方法實現的Bytecode和異常處理

};

例如一個方法定義如下:

public static boolean?canAccessSystemClipboard(){

??????????????...

}

access_flags的值為?ACC_PUBLIC | ACC_STATIC =0x0009,常數表內name_index索引內保存數據為canAccessSystemClipboard,常數表內descriptor_index索引內保存數據為()Z(括號表示方法參數,Z表示返回值為布爾型,詳細說明參照《Java虛擬機規范》第四章4.3.2)attribute_info **attributes是方法的屬性指針數組,個數為attributes_count,數組內保存的是常數表索引,infoCode_attributeExceptions_attribute

本文不解析方法內容,因此忽略Code_attributeExceptions_attribute的內容。

?

ClassFile結構體中的attribute_info **attributes是附加屬性數組指針,個數為attributes_count,本文只識別SourceFile屬性。

struct?SourceFile_attribute

{

??????????????u2 attribute_name_index;?//常數表內索引

??????????????u4 attribute_length;??????????//屬性長度值,永遠為2

??????????????u2 sourcefile_index;?????????//常數表內索引,info保存源文件名

};

例如com.sum.java.swing.SwingUtitlities2類的源文件名為SwingUtitlities2.java

??????????????以上是本文需要解析的Class文件格式。

2.1.2?讀取數據

定義CJavaClass類完成解析Class文件,生成Java源程序字符串。使用VC++MFCCFileClass文件讀取數據。例如:用16進制編輯器打開Class文件,如圖3,前4byte分別是CA FE BA BE,使用CFile::Read(tmp,sizeof(u4))讀取后,tmp的值為0xBEBAFECA,所以需要位轉換。定義以下方法從文件讀取定長數據:

????????????????????????????void?readu1(u1 *buff);

??void?readu2(u2 *buff);

??void?readu4(u4 *buff);

定義如下方法讀取變長數據。

void?readun(void *buff,u4 len)

讀取的u2u4的數據需要位轉換:

U1??[0]

U1 [1]

U1???[1]

U1 [0]

U2

U1??[0]

U1 [1]

U1???[3]

U4

U1 [2]

U1??[3]

U1 [2]

U1???[0]

U1 [1]

調用void?readu4(u4 *buff);buff的值為0xCAFEBABE,該值為ClassFilemagic,識別該文件是Java Class文件。

3

??????????????magic的后面是Class格式的版本號,圖3的版本為0x00000030=0.48。版本后面是常數表的元素個數,圖3的常數表的元素個數為0xD2=210個。常數表的元素個數之后如ClassFile結構體定義的常數表,類信息,接口信息,域信息,方法信息和附加屬性等。

2.2?生成Java源文件

??????????????解析Class文件后,生產ClassFile結構體。遍歷該結構體數據,則可根據Java語言規范生成Java源文件。例如根據ClassFileaccess_flags值獲得Java類的修飾符,其中accessCArray<CString,CString&>,保存類所有的修飾符:

??????????????if((flag & ACC_PUBLIC )==ACC_PUBLIC)

??????????????{

??????????????????????????????????????????access.Add(CString("public"));

??????????????}

??????????????if((flag & ACC_PRIVATE)==ACC_PRIVATE)

??????????????{

??????????????????????????????????????????access.Add(CString("private"));

?

??????????????}

??????????????if((flag & ACC_PROTECTED)==ACC_PROTECTED)

??????????????{

??????????????????????????????????????????access.Add(CString("protected"));

?

??????????????}

2.3顯示視圖

??????????????將獲得的Java源代碼顯示在MFCCScrollView視圖非常簡單,可以添加一些關鍵字顏色,例如注釋顯示為草綠色等,如圖4

4

3.總結

??????????????本文根據《Java虛擬機規范》開發了解析Java Class文件格式,并生成Java源代碼結構的工具。其優點是:

1.脫離Java?虛擬機或Java開發環境;

2.可查閱沒有Java源代碼的Class文件的內容;

3.為一些復雜的Java Jar包生成相同類名的替代類,方便開發調試。例如,用返回固定字符串的java源文件更換需要網絡鏈接的相同java類,有助于本地運行與調試。

缺點是:

1.由于沒有反編譯Bytecode,工具生成的部分Java源文件需要手動添加一些Java屬性值;

2.Java源文件內的所需要使用的Java方法內容需要程序員手動實現

《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

總結

以上是生活随笔為你收集整理的解读Java Class文件格式的全部內容,希望文章能夠幫你解決所遇到的問題。

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

主站蜘蛛池模板: 亚洲高清资源 | 久久性感美女视频 | 久久刺激 | 爱情岛亚洲首页论坛 | 国产在线视频在线观看 | 福利片av | videos另类灌满极品另类 | 大陆日韩欧美 | 秋霞午夜鲁丝一区二区老狼 | 天天干网站 | 久久丫精品国产亚洲av不卡 | 国产一区成人 | 黄色片网站免费在线观看 | 午夜免费网址 | 午夜性生活片 | 久久这里有精品视频 | 色婷婷a | www.热久久| 成人免费看片&#39; | 国产一级黄色大片 | 理论片大全免费理伦片 | 2022精品国偷自产免费观看 | 自拍超碰在线 | 亚洲精品播放 | 精品免费在线视频 | 久草手机在线视频 | 熊猫电影yy8y全部免费观看 | 三级免费黄 | 亚洲福利网址 | 亚洲精品无码成人 | 久精品视频 | 一级高清毛片 | 国产男女无套 | 欧美一级二级在线观看 | 久久久久久久综合 | 91视频免费在线观看 | 在线视频成人 | 精品免费看 | 日韩网站在线 | 亚洲第一二区 | 一级特级片 | 欧美日本韩国一区 | 欧美精品一区二区三区久久久竹菊 | 亚洲天堂午夜 | 国产美女无遮挡免费视频 | 黄色成人免费观看 | 亚洲一区二区三区欧美 | 日本色综合网 | www性| 无码国产精品高潮久久99 | 久草久草 | 国产裸体视频网站 | 神马午夜国产 | 久久久免费电影 | av黄色av| 免费观看成人毛片 | 免费在线观看的黄色网址 | 一级片视频免费 | 午夜婷婷丁香 | 国产一线二线三线女 | mm1313亚洲精品 | 不卡日本视频 | 久草福利网 | 久草视频在线播放 | 午夜影院日本 | 色福利在线 | www.色播| 99久久人妻无码精品系列 | 亚洲色图综合网 | 国产做受高潮动漫 | 国产视频网站在线观看 | 精品少妇爆乳无码av无码专区 | 国产精品嫩草久久久久 | 一本高清dvd在线播放 | 国产在线久久久 | 国产高清www | 亚洲永久精品ww.7491进入 | av每日更新 | 中文字幕久久久久久久 | 亚洲成人黄色影院 | 东北少妇高潮抽搐 | 好男人www社区 | 中文字幕另类 | 国产91综合 | 激情影音| 夜夜躁狠狠躁日日躁av | 精品国产一区二区三区久久久蜜臀 | 果冻av在线 | 性做久久久久久免费观看 | 黄色一级免费观看 | 日本阿v视频在线观看 | www.日韩| 美女啪啪国产 | 国产91精选 | 麻豆视频在线观看免费网站 | 日本免费色 | 精品人妻一区二区免费 | 日韩欧美国产成人精品免费 | 嫩草影院av |