欢迎访问昆山宝鼎软件有限公司网站! 设为首页 | 网站地图 | XML | RSS订阅 | 宝鼎邮箱 | 后台管理


新闻资讯

MENU

软件开发知识

ClassAnalyzer的目的是能让我们对Ja CAD加密 va Class文件的设计与结构能够有一个深入的理解

点击: 次  来源:宝鼎软件 时间:2017-07-29

原文出处: tinylcy

最近在写一个私人项目,名字叫做ClassAnalyzer,ClassAnalyzer的目标是能让我们对Java Class文件的设计与布局可以或许有一个深入的领略。主体框架与根基成果已经完成,尚有一些细节成果日后再增加。实际上JDK已经提供了呼吁行东西javap来反编译Class文件,但本篇文章将阐发我实现理会器的思路。

Class文件

作为类可能接口信息的载体,每个Class文件都完整的界说了一个类。为了使Java措施可以“编写一次,随处运行”,Java虚拟机类型对Class文件举办了严格的划定。组成Class文件的根基数据单元是字节,这些字节之间不存在任何脱离符,这使得整个Class文件中存储的内容险些全部是措施运行的须要数据,单个字节无法暗示的数据由多个持续的字节来暗示。

按照Java虚拟机类型,Class文件回收一种雷同于C语言布局体的伪布局来存储数据,这种伪布局中只有两种数据范例:无标记数和表。Java虚拟机类型界说了u1、u2、u4和u8来别离暗示1个字节、2个字节、4个字节和8个字节的无标记数,软件开发,无标记数可以用来描写数字、索引引用、数量值可能是字符串。表是由多个无标记数可能其它表作为数据项组成的复合数据范例,表用于描写有条理干系的复合布局的数据,因此整个Class文件本质上就是一张表。在ClassAnalyzer中,byte、short、int和long别离对应u1、u2、u4和u8数据范例,Class文件被描写为如下Java类。

java; gutter: true">public class ClassFile {
    public U4 magic;                            // magic
    public U2 minorVersion;                     // minor_version
    public U2 majorVersion;                     // major_version
    public U2 constantPoolCount;                // constant_pool_count
    public ConstantPoolInfo[] cpInfo;           // cp_info
    public U2 accessFlags;                      // access_flags
    public U2 thisClass;                        // this_class
    public U2 superClass;                       // super_class
    public U2 interfacesCount;                  // interfaces_count
    public U2[] interfaces;                     // interfaces
    public U2 fieldsCount;                      // fields_count
    public FieldInfo[] fields;                  // fields
    public U2 methodsCount;                     // methods_count
    public MethodInfo[] methods;                // methods
    public U2 attributesCount;                  // attributes_count
    public BasicAttributeInfo[] attributes;     // attributes
}

如何理会

构成Class文件的各个数据项中,譬喻魔数、Class文件的版本、会见符号、类索引和父类索引等数据项,它们在每个Class文件中都占用牢靠命量的字节,在理会时只需要读取相应数量的字节。除此之外,需要机动处理惩罚的主要包罗4部门:常量池、字段表荟萃、要领表荟萃和属性表荟萃。字段和要领都可以具备本身的属性,Class自己也有相应的属性,因此,在理会字段表荟萃和要领表荟萃的同时也包括了属性表荟萃的理会。

常量池占据了Class文件很大一部门的数据,用于存储所有的常量信息,包罗数字和字符串常量、类名、接口名、字段名和要领名等。Java虚拟机类型界说了多种常量范例,每一种常量范例都有本身的布局。常量池自己是一个表,在理会时有几点需要留意。

  • 每个常量范例都通过一个u1范例的tag来标识。
  • 表头给出的常量池巨细(constantPoolCount)比实际大1,譬喻,假如constantPoolCount便是47,那么常量池中有46项常量。
  • 常量池的索引范畴从1开始,譬喻,假如constantPoolCount便是47,那么常量池的索引范畴为1 ~ 46。设计者将第0项空出来的目标是用于表达“不引用任何一个常量池项目”。
  • 假如一个CONSTANT_Long_info或CONSTANT_Double_info布局的项在常量池中的索引为n,则常量池中下一个有效的项的索引为n+2,此时常量池中索引为n+1的项有效但必需被认为不行用。
  • CONSTANT_Utf8_info型常量的布局中包括一个u1范例的tag、一个u2范例的length和由length个u1范例构成的bytes,软件开发,这length字节的持续数据是一个利用MUTF-8(Modified UTF-8)编码的字符串。MUTF-8与UTF-8并不兼容,主要区别有两点:一是null字符会被编码成2字节(0xC0和0×80);二是增补字符是凭据UTF-16拆分为署理对别离编码的,相关细节可以看这里(变种UTF-8)。
  • 属性表用于描写某些场景专有的信息,Class文件、字段表和要领表都有相应的属性表荟萃。Java虚拟机类型界说了多种属性,ClassAnalyzer今朝实现了对常用属性的理会。与常量范例的数据项差异,属性并没有一个tag来标识属性的范例,可是每个属性都包括有一个u2范例的attribute_name_index,attribute_name_index指向常量池中的一个CONSTANT_Utf8_info范例的常量,该常量包括着属性的名称。在理会属性时,ClassAnalyzer正是通过attribute_name_index指向的常量对应的属性名称来得知属性的范例。