def read(self, class_reader): self.read_and_check_magic(class_reader) self.read_and_check_version(class_reader) self.constant_pool = ConstantPool() self.constant_pool.read_constant_pool(class_reader) self.access_flags = int.from_bytes(class_reader.read_unit16(), byteorder="big") self.this_class = int.from_bytes(class_reader.read_unit16(), byteorder="big") self.super_class = int.from_bytes(class_reader.read_unit16(), byteorder="big") self.interfaces = class_reader.read_unit16s() member_info = MemberInfo(self.constant_pool) self.fields = member_info.read_members(class_reader, self.constant_pool) self.methods = member_info.read_members(class_reader, self.constant_pool) self.attributes = AttributeInfo.read_attributes(class_reader, self.constant_pool)
class ConstantMemberRefInfo(ConstantInfo): def __init__(self, constant_pool): from ch08.classfile.ConstantPool import ConstantPool self.cp = ConstantPool(constant_pool) self.class_index = 0 self.name_and_type_index = 0 def read_info(self, class_reader): self.class_index = int.from_bytes(class_reader.read_unit16(), byteorder="big") self.name_and_type_index = int.from_bytes(class_reader.read_unit16(), byteorder="big") @property def class_name(self): return self.cp.get_class_name(self.class_index) @property def name_and_descriptor(self): return self.cp.get_name_and_type(self.name_and_type_index)
class ConstantClassInfo(ConstantInfo): def __init__(self, constant_pool): from ch08.classfile.ConstantPool import ConstantPool self.cp = ConstantPool(constant_pool) self.name_index = 0 def read_info(self, class_reader): self.name_index = int.from_bytes(class_reader.read_unit16(), byteorder="big") @property def name(self): return self.cp.get_utf8(self.name_index)
class ConstantStringInfo(ConstantInfo): def __init__(self, constant_pool): from ch08.classfile.ConstantPool import ConstantPool self.cp = ConstantPool(constant_pool) self.string_index = "" # 读取常量池索引 def read_info(self, class_reader): self.string_index = int.from_bytes(class_reader.read_unit16(), byteorder="big") # 按索引从常量池中查找字符串 def __str__(self): return self.cp.get_utf8(self.string_index)
def new_constant_pool(clazz, cfConstantPool: ConstantPool): from ch08.classfile.CpNumeric import ConstantDoubleInfo, ConstantLongInfo, ConstantFloatInfo, ConstantIntegerInfo from ch08.classfile.ConstantStringInfo import ConstantStringInfo from ch08.classfile.ConstantClassInfo import ConstantClassInfo from ch08.classfile.ConstantMemberRefInfo import ConstantFieldRefInfo, ConstantMethodRefInfo, \ ConstantInterfaceMethodRefInfo from ch08.rtda.heap.CpClassRef import ClassRef from ch08.rtda.heap.CpFieldRef import FieldRef from ch08.rtda.heap.CpMethodRef import MethodRef from ch08.rtda.heap.CpInterfaceMethodRef import InterfaceMethodRef cp_count = len(cfConstantPool.cp) consts = [None for _ in range(cp_count)] rt_constant_pool = ConstantPool(clazz, consts) for i in range(1, cp_count): cp_info = cfConstantPool.cp[i] if isinstance(cp_info, ConstantIntegerInfo): consts[i] = cp_info.val elif isinstance(cp_info, ConstantFloatInfo): consts[i] = cp_info.val elif isinstance(cp_info, ConstantLongInfo): consts[i] = cp_info.val elif isinstance(cp_info, ConstantDoubleInfo): consts[i] = cp_info.val elif isinstance(cp_info, ConstantStringInfo): consts[i] = str(cp_info) elif isinstance(cp_info, ConstantClassInfo): consts[i] = ClassRef(rt_constant_pool, cp_info) elif isinstance(cp_info, ConstantFieldRefInfo): consts[i] = FieldRef(rt_constant_pool, cp_info) elif isinstance(cp_info, ConstantMethodRefInfo): consts[i] = MethodRef(rt_constant_pool, cp_info) elif isinstance(cp_info, ConstantInterfaceMethodRefInfo): consts[i] = InterfaceMethodRef(rt_constant_pool, cp_info) # rt_constant_pool.consts = consts return rt_constant_pool
class ClassFile: def __init__(self): # 小版本号 self.minor_version = "" # 主版本号 self.major_version = "" # 常量池 self.constant_pool = None # 类访问标志,用于指出class文件定义的是类还是接口,访问级别是public还是private self.access_flags = "" # 类索引 self.this_class = "" # 超类索引 self.super_class = "" # 接口索引表 self.interfaces = [] # 变量 self.fields = [] # 方法 self.methods = [] # 属性 self.attributes = [] def parse(self, class_data): try: class_reader = ClassReader(class_data) self.read(class_reader) return self, None except Exception as err: return self, err def read(self, class_reader): self.read_and_check_magic(class_reader) self.read_and_check_version(class_reader) self.constant_pool = ConstantPool() self.constant_pool.read_constant_pool(class_reader) self.access_flags = int.from_bytes(class_reader.read_unit16(), byteorder="big") self.this_class = int.from_bytes(class_reader.read_unit16(), byteorder="big") self.super_class = int.from_bytes(class_reader.read_unit16(), byteorder="big") self.interfaces = class_reader.read_unit16s() member_info = MemberInfo(self.constant_pool) self.fields = member_info.read_members(class_reader, self.constant_pool) self.methods = member_info.read_members(class_reader, self.constant_pool) self.attributes = AttributeInfo.read_attributes(class_reader, self.constant_pool) # 读取并检查Class文件的起始字节,必须以0xCAFEBABE固定字节开头 @staticmethod def read_and_check_magic(class_reader): magic = class_reader.read_unit32() if magic != b'\xca\xfe\xba\xbe': raise RuntimeError("java.lang.ClassFormatError: magic!") # 读取并检查版本号,由于采用java1.8的编译器,故支持版本号为45.0~52.0的class文件 def read_and_check_version(self, class_reader): self.minor_version = int.from_bytes(class_reader.read_unit16(), byteorder='big') self.major_version = int.from_bytes(class_reader.read_unit16(), byteorder='big') if self.major_version == 45: return elif self.major_version in {46, 47, 48, 49, 50, 51, 52}: if self.minor_version == 0: return raise RuntimeError("java.lang.UnsupportedClassVersionError!") # 从常量池中查找类名 @property def class_name(self): return self.constant_pool.get_class_name(self.this_class) # 从常量池中查找超类类名 @property def super_class_name(self): if self.super_class > 0: return self.constant_pool.get_class_name(self.super_class) # 只有java.lang.Object没有超类 return "" # 从常量池中查找接口名 @property def interface_names(self): return [self.constant_pool.get_class_name(cpName) for cpName in self.interfaces]
def __init__(self, constant_pool): from ch08.classfile.ConstantPool import ConstantPool self.cp = ConstantPool(constant_pool) self.class_index = 0 self.name_and_type_index = 0
def __init__(self, constant_pool): from ch08.classfile.ConstantPool import ConstantPool self.cp = ConstantPool(constant_pool) self.string_index = ""