importbinasciiclassparse_dex:def __init__(self,dex_file):#由于后续各区都需要从header中获取自己的数量和偏移,所以在构造函数中调用它
self.parse_dex_header()#此函数用于解析dex文件头部
defparse_dex_header(self):#定义header结构,key是头成员名称,value是key的字节长度
#xxx_ids_off表示xxx_ids_item列表的偏移量,xxx_ids_size表示xxx_ids_item个数
#xxx_off表示xxx的偏移量,xxx_size表示xxx的字节大小
self.dex_header_struct ={#魔数
'magic': 8,#文件校验码 ,使用alder32 算法校验文件除去 maigc ,checksum 外余下的所有文件区域 ,用于检查文件错误 。
'checksum': 4,#使用 SHA-1 算法 hash 除去 magic ,checksum 和 signature 外余下的所有文件区域 ,用于唯一识别本文件 。
'signature': 20,#Dex 文件的大小 。
'file_size': 4,#header 区域的大小 ,单位 Byte ,一般固定为 0x70 常量 。
'header_size': 4,#大小端标签 ,标准 .dex 文件格式为 小端 ,此项一般固定为 0x1234 5678 常量 。
'endian_tag': 4,#链接数据的大小
'link_size': 4,#链接数据的偏移值
'link_off': 4,#map item 的偏移地址 ,该 item 属于 data 区里的内容 ,值要大于等于 data_off 的大小 。
'map_off': 4,#dex中用到的所有的字符串内容的大小
'string_ids_size': 4,#dex中用到的所有的字符串内容的偏移值
'string_ids_off': 4,#dex中的类型数据结构的大小
'type_ids_size': 4,#dex中的类型数据结构的偏移值
'type_ids_off': 4,#dex中的元数据信息数据结构的大小
'proto_ids_size': 4,#dex中的元数据信息数据结构的偏移值
'proto_ids_off': 4,#dex中的字段信息数据结构的大小
'field_ids_size': 4,#dex中的字段信息数据结构的偏移值
'field_ids_off': 4,#dex中的方法信息数据结构的大小
'method_ids_size': 4,#dex中的方法信息数据结构的偏移值
'method_ids_off': 4,#dex中的类信息数据结构的大小
'class_defs_size': 4,#dex中的类信息数据结构的偏移值
'class_defs_off': 4,#dex中数据区域的结构信息的大小
'data_size': 4,#dex中数据区域的结构信息的偏移值
'data_off': 4}#此变量用于存放读取到的dex头部
self.dex_header ={}#以二进制形式读取文件
self.fo = open(dex_file, "rb")for k, v inself.dex_header_struct.items():#size,表示个数的字段,取其十进制
if "_size" ink:
tmp=self.fo.read(v)
tmp= int.from_bytes(tmp, byteorder='little', signed=False)
self.dex_header[k]=tmp#off,表示文件偏移量的字段,为方便与以十六进制打开文件时相对比,取其十六进制
#文件中是小端模式,为方便看我们顺序取反
elif '_off' ink:
tmp=self.fo.read(v)
tmp= tmp[::-1]
self.dex_header[k]=binascii.b2a_hex(tmp).upper()#其余字段保持原本顺序,直接十六进制转字符串
else:
self.dex_header[k]=binascii.hexlify(self.fo.read(v)).upper()#int.from_bytes(binascii.a2b_hex(dex_header['string_ids_off']),byteorder='big',signed=False)
#此函数用于读取leb128格式数值
defread_uleb128(self):
values=[]
value= int.from_bytes(self.fo.read(1), byteorder='little', signed=False)
values.append(value)while value >= 0x7f:
value= int.from_bytes(self.fo.read(1), byteorder='little', signed=False)
values.append(value)
i=len(values)
result=0
values= values[::-1]for value invalues:
i= i-1result|= (value&0x7f) << (i*7)returnresult#此函数用于解析dex文件中的所有字符串;
#由于后边type等都要通过序号来获取字符串,所以独立出parse_string_by_index
defparse_strings(self):#由于已经_off顺序已取反,所以要指定为大端模式转成整数
string_ids_off = int.from_bytes(binascii.a2b_hex(self.dex_header['string_ids_off']), byteor