def encodeutf(string): str_data = [] str_count = 0 if config.get_value('XMLFLAG') == 0: str_data.append(hex(len(string))) str_data.append(hex(0)) for str_i in string: encod_str = hex(ord(str_i.encode("utf-8"))) str_data.append(encod_str) str_data.append(hex(0)) str_data.append(hex(0)) str_data.append(hex(0)) elif config.get_value('XMLFLAG') == 1: #此时为XML资源文件格式 str_data.append(hex(len(string))) str_data.append(hex(len(string))) for str_i in string: encod_str = hex(ord(str_i.encode("utf-8"))) str_data.append(encod_str) str_data.append(hex(0)) #和4倍对齐,所以最多循环3次 for i in range(3): if (str_count + 1 + 2) % 4 == 0: return str_data else: str_count += 1 str_data.append(hex(0)) # print str_data return str_data
def am_resourceidchunk(data, pc): # ChunkType:ResourceId Chunk类型,固定四个字节0x00080180 ChunkType = ApUtils.little_endian(data[pc:pc + 4]) if ApUtils.printhex(ChunkType) == "0x00080180": ApUtils.apprint("===========Resolve ResourceId Chunk=============") ApUtils.apprint("[Resource]ChunkType is : " + ApUtils.printhex(ChunkType)) else: ApUtils.apprint("[Error]ResourceId Chunk resolve error!") exit(-1) # ResourceId Chunk的大小(4) ChunkSize = ApUtils.little_endian(data[pc + 4:pc + 8]) ApUtils.apprint("[Resource]ChunkSize is : " + ApUtils.printhex(ChunkSize)) # ResourcesId的个数为(大小-头部8字节)/4 ResourcesId_num = int((int(ApUtils.printhex(ChunkSize), 16) - 8) / 4) for i in range(ResourcesId_num): tmp_hex = ApUtils.printhex( ApUtils.little_endian(data[pc + 8 + i * 4:pc + 8 + i * 4 + 4])) tmp = int(tmp_hex, 16) ApUtils.apprint("[Resource][" + str(i) + "]Id : " + str(tmp) + ",hex : " + tmp_hex) config.global_list['RESOURCEIDS'].append(tmp_hex) config.set_value( 'RESOURCEIDCHUNKEND', config.get_value('RESOURCEIDCHUNKSTAR') + int(ApUtils.printhex(ChunkSize), 16))
def am_tagchunk_end(data, pc): # ChunkType:end Tag Chunk类型,固定四个字节0x00100103 ChunkType = ApUtils.little_endian(data[pc:pc + 4]) if ApUtils.printhex(ChunkType) == "0x00100103": ApUtils.apprint(" ===========Resolve Tag Chunk End=============") ApUtils.apprint(" [endTag" + str(config.get_value('TAGCOUNTEND')) + "]ChunkType is : " + ApUtils.printhex(ChunkType)) else: ApUtils.apprint(" [Error" + str(config.get_value('TAGCOUNTEND')) + "]Tag Chunk end resolve error!") exit(-1) # Tag Chunk的大小(4) ChunkSize = ApUtils.little_endian(data[pc + 4:pc + 8]) ApUtils.apprint(" [endTag" + str(config.get_value('TAGCOUNTEND')) + "]ChunkSize is : " + ApUtils.printhex(ChunkSize)) # Line Number 行号(4) LineNumber = ApUtils.little_endian(data[pc + 8:pc + 12]) ApUtils.apprint(" [endTag" + str(config.get_value('TAGCOUNTEND')) + "]LineNumber is : " + ApUtils.printhex(LineNumber)) # Unknown未知区域(4) Unknown = ApUtils.little_endian(data[pc + 12:pc + 16]) # Namespace Uri NameSpcae = ApUtils.little_endian(data[pc + 16:pc + 20]) if int(ApUtils.printhex(NameSpcae), 16) <= len( config.global_list['STRINGPOOL']): ApUtils.apprint(" [endTag" + str(config.get_value('TAGCOUNTEND')) + "]NameSpace is : " + config.global_list['STRINGPOOL'][ int(ApUtils.printhex(NameSpcae), 16)]) else: ApUtils.apprint(" [endTag" + str(config.get_value('TAGCOUNTEND')) + "]NameSpace is : null") # name Name = ApUtils.little_endian(data[pc + 20:pc + 24]) NameStr = config.global_list['STRINGPOOL'][int(ApUtils.printhex(Name), 16)] ApUtils.apprint(" [endTag" + str(config.get_value('TAGCOUNTEND')) + "]Tag name is : " + NameStr) # 修改结束指针 config.set_value( 'ENDTAGCHUNKEND', config.get_value('ENDTAGCHUNKSTAR') + int(ApUtils.printhex(ChunkSize), 16))
def am_namespacechunk_star(data, pc): # ChunkType:Namespace Chunk类型,固定四个字节0x00100100 ChunkType = ApUtils.little_endian(data[pc:pc + 4]) if ApUtils.printhex(ChunkType) == "0x00100100": ApUtils.apprint( "===========Resolve Namespace Chunk Start=============") ApUtils.apprint("[startNamespace]ChunkType is : " + ApUtils.printhex(ChunkType)) else: ApUtils.apprint("[Error]Namespace Chunk Start resolve error!") exit(-1) # Namespace Chunk的大小(4) ChunkSize = ApUtils.little_endian(data[pc + 4:pc + 8]) ApUtils.apprint("[startNamespace]ChunkSize is : " + ApUtils.printhex(ChunkSize)) # Line Number 行号(4) LineNumber = ApUtils.little_endian(data[pc + 8:pc + 12]) ApUtils.apprint("[startNamespace]LineNumber is : " + ApUtils.printhex(LineNumber)) # Unknown未知区域(4) Unknown = ApUtils.little_endian(data[pc + 12:pc + 16]) # Prefix命名空间前缀(4)(字符串索引) Prefix = ApUtils.little_endian(data[pc + 16:pc + 20]) PrefixName = config.global_list['STRINGPOOL'][int(ApUtils.printhex(Prefix), 16)] ApUtils.apprint("[startNamespace]Prefix is : " + ApUtils.printhex(Prefix) + " , str is : " + PrefixName) # Uri命名空间的URI(4)(字符串索引) Url = ApUtils.little_endian(data[pc + 20:pc + 24]) UrlName = config.global_list['STRINGPOOL'][int(ApUtils.printhex(Url), 16)] ApUtils.apprint("[startNamespace]Url is : " + ApUtils.printhex(Url) + " , str is : " + UrlName) config.set_value( 'STARNAMESPACEEND', config.get_value('STARNAMESPACESTAR') + int(ApUtils.printhex(ChunkSize), 16))
def am_textchunk(data, pc): # ChunkType:text chunk 类型,固定四个字节0x00100104 ChunkType = ApUtils.little_endian(data[pc:pc + 4]) if ApUtils.printhex(ChunkType) == "0x00100104": ApUtils.apprint(" ===========Resolve Text Chunk=============") ApUtils.apprint(" [textChunk]" + ApUtils.printhex(ChunkType)) else: ApUtils.apprint(" [Error]Text Chunk resolve error!") exit(-1) # Tag Chunk的大小(4) ChunkSize = ApUtils.little_endian(data[pc + 4:pc + 8]) ApUtils.apprint(" [textChunk]ChunkSize is : " + ApUtils.printhex(ChunkSize)) # Line Number 行号(4) LineNumber = ApUtils.little_endian(data[pc + 8:pc + 12]) ApUtils.apprint(" [textChunk]LineNumber is : " + ApUtils.printhex(LineNumber)) # Unknown未知区域(4) Unknown = ApUtils.little_endian(data[pc + 12:pc + 16]) # nameApUtils Name = ApUtils.little_endian(data[pc + 16:pc + 20]) NameStr = config.global_list['STRINGPOOL'][int(ApUtils.printhex(Name), 16)] ApUtils.apprint(" [textChunk]Text name is : " + NameStr) # Unknown未知区域(4) Unknown1 = ApUtils.little_endian(data[pc + 20:pc + 24]) # Unknown未知区域(4) Unknown2 = ApUtils.little_endian(data[pc + 24:pc + 28]) config.set_value( 'TEXTCHUNKEND', config.get_value('TEXTCHUNKSTAR') + int(ApUtils.printhex(ChunkSize), 16))
def am_stringchunk(data, pc): # StringChunk的类型,固定4个字节 ChunkType = ApUtils.little_endian(data[pc:pc + 4]) if ApUtils.printhex(ChunkType) == "0x001c0001": ApUtils.apprint("===========Resolve String Chunk=============") ApUtils.apprint("[String]ChunkType is : " + ApUtils.printhex(ChunkType)) else: ApUtils.apprint("[Error]String Chunk resolve error!") exit(-1) # StringChunk的大小(4) ChunkSize = ApUtils.little_endian(data[pc + 4:pc + 8]) ApUtils.apprint("[String]ChunkSize is : " + ApUtils.printhex(ChunkSize)) config.set_value('STRINGCHUNKSIZEINDEX', pc + 4) # StringChunk中字符串的个数(4) StringCount = ApUtils.little_endian(data[pc + 8:pc + 12]) ApUtils.apprint("[String]StringCount is : " + ApUtils.printhex(StringCount)) config.set_value('STRINGCHUNKCOUNTINDEX', pc + 8) # StringChunk中样式的个数(4) StyleCount = ApUtils.little_endian(data[pc + 12:pc + 16]) ApUtils.apprint("[String]StyleCount is : " + ApUtils.printhex(StyleCount)) # Unknown(4) Unknown = ApUtils.little_endian(data[pc + 16:pc + 20]) #如果此时Unknown为0x00010000也就是256,说明此时使用的为xml编码格式 if int(ApUtils.printhex(Unknown), 16) == 256: ApUtils.apprint("[String]This is XML Flag!") config.set_value('XMLFLAG', 1) # 字符串池的偏移值(4) StringPoolOffset = ApUtils.little_endian(data[pc + 20:pc + 24]) ApUtils.apprint("[String]StringPoolOffset is : " + ApUtils.printhex(StringPoolOffset)) config.set_value('STRINGPOOLOFFSET', StringPoolOffset) config.set_value('STRINGPOOLOFFSETINDEX', pc + 20) # 样式池的偏移值(4) StylePoolOffset = ApUtils.little_endian(data[pc + 24:pc + 28]) ApUtils.apprint("[String]StylePoolOffset is : " + ApUtils.printhex(StylePoolOffset)) config.set_value('STYLEPOOLOFFSET', StylePoolOffset) # 每个字符串的偏移 if int(ApUtils.printhex(StringCount), 16) != 0: StringOffsets = [] for i in range(int(ApUtils.printhex(StringCount), 16)): StringOffset = ApUtils.little_endian(data[pc + 28 + i * 4:pc + 28 + i * 4 + 4]) StringOffsets.append(StringOffset) config.set_value('LASTSTRINGOFFSETSINDEX', pc + 28 + i * 4) # 每个字符串的偏移列表 config.global_list['STRINGOFFSETS'].extend(StringOffsets) else: ApUtils.apprint("[String]There is no String") # 每个样式的偏移 if int(ApUtils.printhex(StyleCount), 16) != 0: StyleOffsets = [] for j in range(int(ApUtils.printhex(StyleCount), 16)): StyleOffset = ApUtils.little_endian( data[pc + 28 + int(ApUtils.printhex(StringCount), 16) * 4 + j * 4:pc + 28 + int(ApUtils.printhex(StringCount), 16) * 4 + j * 4 + 4]) StyleOffsets.append(StyleOffset) # 每个字符串的偏移列表 config.global_list['STYLEOFFSETS'].extend(StyleOffsets) else: ApUtils.apprint("[String]There is no Style") # =======开始解析字符串===========# count = 0 if config.get_value('XMLFLAG') == 0: for index in config.global_list['STRINGOFFSETS']: str_index = pc + int( ApUtils.printhex(config.get_value('STRINGPOOLOFFSET')), 16) + int(ApUtils.printhex(index), 16) str_len = int( ApUtils.printhex( ApUtils.little_endian(data[str_index:str_index + 2])), 16) str_end = data[str_index + (str_len + 1) * 2:str_index + (str_len + 1) * 2 + 2] # utf-8编码 try: string = ApUtils.read_asc(data[str_index + 2:str_index + 2 + str_len * 2])\ .encode("utf-8").decode('unicode_escape') except: try: string = ApUtils.read_asc(data[str_index + 2:str_index + 2 + str_len * 2])\ .encode("utf-8").decode('unicode_escape') except: string = "String resolve error !!" config.set_value('STRINGCHUNKEND', str_index + 2 + str_len * 2 + 2) ApUtils.apprint(" [StringPool][" + str(count) + "]" + string) config.global_list['STRINGPOOL'].append(string) count += 1 config.set_value('LASTSTRINGLEN', str_len) config.set_value('LASTSTRINGINDEX', config.get_value('STRINGCHUNKEND')) elif config.get_value('XMLFLAG') == 1: for index in config.global_list['STRINGOFFSETS']: str_index = pc + int( ApUtils.printhex(config.get_value('STRINGPOOLOFFSET')), 16) + int(ApUtils.printhex(index), 16) str_len = int( ApUtils.printhex( ApUtils.little_endian(data[str_index + 1:str_index + 2])), 16) # utf-8编码 try: string = ApUtils.read_asc(data[str_index + 2:str_index + 2 + str_len ])\ .encode("utf-8").decode('unicode_escape') except: try: string = ApUtils.read_asc(data[str_index + 2:str_index + 2 + str_len])\ .encode("utf-8").decode('unicode_escape') except: string = "String resolve error !!" config.set_value('STRINGCHUNKEND', str_index + 2 + str_len + 1) ApUtils.apprint(" [StringPool][" + str(count) + "]" + string) config.global_list['STRINGPOOL'].append(string) count += 1 config.set_value('LASTSTRINGLEN', str_len) config.set_value('LASTSTRINGINDEX', config.get_value('STRINGCHUNKEND')) else: ApUtils.apprint("[String]XMLFLAG is Wrong!") exit(-1)
def am_tagchunk_star(data, pc): # ChunkType:Tag Chunk类型,固定四个字节0x00100102 ChunkType = ApUtils.little_endian(data[pc:pc + 4]) if ApUtils.printhex(ChunkType) == "0x00100102": ApUtils.apprint(" ===========Resolve Tag Chunk Start=============") ApUtils.apprint(" [startTag" + str(config.get_value('TAGCOUNTSTAR')) + "]ChunkType is : " + ApUtils.printhex(ChunkType)) else: ApUtils.apprint(" [Error" + str(config.get_value('TAGCOUNTSTAR')) + "]Tag Chunk start resolve error!") exit(-1) # Tag Chunk的大小(4) ChunkSize = ApUtils.little_endian(data[pc + 4:pc + 8]) ApUtils.apprint(" [startTag" + str(config.get_value('TAGCOUNTSTAR')) + "]ChunkSize is : " + ApUtils.printhex(ChunkSize)) # Line Number 行号(4) LineNumber = ApUtils.little_endian(data[pc + 8:pc + 12]) ApUtils.apprint(" [startTag" + str(config.get_value('TAGCOUNTSTAR')) + "]LineNumber is : " + ApUtils.printhex(LineNumber)) # Unknown未知区域(4) Unknown = ApUtils.little_endian(data[pc + 12:pc + 16]) # Namespace Uri NameSpcae = ApUtils.little_endian(data[pc + 16:pc + 20]) if int(ApUtils.printhex(NameSpcae), 16) <= len( config.global_list['STRINGPOOL']): ApUtils.apprint(" [startTag" + str(config.get_value('TAGCOUNTSTAR')) + "]NameSpace is : " + config.global_list['STRINGPOOL'][ int(ApUtils.printhex(NameSpcae), 16)]) else: ApUtils.apprint(" [startTag" + str(config.get_value('TAGCOUNTSTAR')) + "]NameSpace is : null") # name Name = ApUtils.little_endian(data[pc + 20:pc + 24]) NameStr = config.global_list['STRINGPOOL'][int(ApUtils.printhex(Name), 16)] ApUtils.apprint(" [startTag" + str(config.get_value('TAGCOUNTSTAR')) + "]Tag name is : " + NameStr) if NameStr == "application": config.set_value('APPLICATIONPC', pc) # Flags好像没有意义,一般都是0x00140014 Flags = ApUtils.little_endian(data[pc + 24:pc + 28]) # Attribute Count AttributeCount = ApUtils.little_endian(data[pc + 28:pc + 32]) ApUtils.apprint(" [startTag" + str(config.get_value('TAGCOUNTSTAR')) + "]Attribute Count is : " + ApUtils.printhex(AttributeCount)) # Class Attribute一般也没用,0x00000000 ClassAttibute = ApUtils.little_endian(data[pc + 32:pc + 36]) # Attributes for i in range(int(ApUtils.printhex(AttributeCount), 16)): att_namespace = ApUtils.little_endian(data[pc + 36 + i * 5 * 4:pc + 36 + i * 5 * 4 + 4]) att_name = ApUtils.little_endian(data[pc + 36 + i * 5 * 4 + 4:pc + 36 + i * 5 * 4 + 4 + 4]) att_valuestr = ApUtils.little_endian( data[pc + 36 + i * 5 * 4 + 4 + 4:pc + 36 + i * 5 * 4 + 4 + 4 + 4]) att_type = ApUtils.little_endian( data[pc + 36 + i * 5 * 4 + 4 + 4 + 4:pc + 36 + i * 5 * 4 + 4 + 4 + 4 + 4]) att_data = ApUtils.little_endian( data[pc + 36 + i * 5 * 4 + 4 + 4 + 4 + 4:pc + 36 + i * 5 * 4 + 4 + 4 + 4 + 4 + 4]) # 打印 #print(" ----------------------------------------------") if int(ApUtils.printhex(att_namespace), 16) <= len( config.global_list['STRINGPOOL']): ApUtils.apprint(" [startTag" + str(config.get_value('TAGCOUNTSTAR')) + "]Attribute[" + str(i) + "]NameSpace is : " + config.global_list['STRINGPOOL'][int( ApUtils.printhex(att_namespace), 16)]) else: ApUtils.apprint(" [startTag" + str(config.get_value('TAGCOUNTSTAR')) + "]Attribute[" + str(i) + "]NameSpace is null ") if int(ApUtils.printhex(att_name), 16) <= len( config.global_list['STRINGPOOL']): attr_name = config.global_list['STRINGPOOL'][int( ApUtils.printhex(att_name), 16)] ApUtils.apprint(" [startTag" + str(config.get_value('TAGCOUNTSTAR')) + "]Attribute[" + str(i) + "]Name is : " + attr_name) # 修改application name if NameStr == "application": if attr_name == "name": config.set_value('APPLICATIONNAMEFLAG', 1) config.set_value('APPLICATIONNAMEINDEX', pc + 36 + i * 5 * 4) else: ApUtils.apprint(" [startTag" + str(config.get_value('TAGCOUNTSTAR')) + "]Attribute[" + str(i) + "]Name is null ") if int(ApUtils.printhex(att_valuestr), 16) <= len( config.global_list['STRINGPOOL']): ApUtils.apprint(" [startTag" + str(config.get_value('TAGCOUNTSTAR')) + "]Attribute[" + str(i) + "]Valus String is : " + config.global_list['STRINGPOOL'][int( ApUtils.printhex(att_valuestr), 16)]) else: ApUtils.apprint(" [startTag" + str(config.get_value('TAGCOUNTSTAR')) + "]Attribute[" + str(i) + "]Valus String is null ") type = ApUtils.getAttrType(int(ApUtils.printhex(att_type), 16) >> 24) ApUtils.apprint(" [startTag" + str(config.get_value('TAGCOUNTSTAR')) + "]Attribute[" + str(i) + "]Type is : " + type) dataAtt = ApUtils.getAttrData( int(ApUtils.printhex(att_type), 16) >> 24, att_data) ApUtils.apprint(" [startTag" + str(config.get_value('TAGCOUNTSTAR')) + "]Attribute[" + str(i) + "]Data is : " + dataAtt) # 修改结束指针 config.set_value( 'STARTTAGCHUNKEND', config.get_value('STARTTAGCHUNKSTAR') + int(ApUtils.printhex(ChunkSize), 16))
def changeApplication(source_filepath, target_filepath, application_name): # 用于存储修改之后的AM文件 cp_data = [] # 解析AM文件 data_hex = resolver(source_filepath) print("[ApEditor]Begin to change application") # 解析要修改的字符串 data_string = ApUtils.encodeutf(application_name) # 处理头部 cp_data.extend(data_hex[0:config.get_value('FILSIZEINDEX')]) # file size old_filesize = ApUtils.printhex( ApUtils.little_endian( data_hex[config.get_value('FILSIZEINDEX' ):config.get_value('FILSIZEINDEX') + 4])) new_filesize = int(old_filesize, 16) + 4 + len(data_string) if config.get_value('APPLICATIONNAMEFLAG') == 0: # 此时需要新加application中name属性 new_filesize += 5 * 4 cp_data.extend(ApUtils.encodehex(new_filesize)) cp_data.extend(data_hex[config.get_value('FILSIZEINDEX') + 4:config.get_value('STRINGCHUNKSIZEINDEX')]) # String chunk size old_stringchunk_size = ApUtils.printhex( ApUtils.little_endian( data_hex[config.get_value('STRINGCHUNKSIZEINDEX'):config. get_value('STRINGCHUNKSIZEINDEX') + 4])) new_stringchunk_size = int(old_stringchunk_size, 16) + 4 + len(data_string) cp_data.extend(ApUtils.encodehex(new_stringchunk_size)) cp_data.extend(data_hex[config.get_value('STRINGCHUNKSIZEINDEX') + 4:config.get_value('STRINGCHUNKCOUNTINDEX')]) # String chunk count old_stringchunk_count = ApUtils.printhex( ApUtils.little_endian( data_hex[config.get_value('STRINGCHUNKCOUNTINDEX'):config. get_value('STRINGCHUNKCOUNTINDEX') + 4])) new_stringchunk_count = int(old_stringchunk_count, 16) + 1 cp_data.extend(ApUtils.encodehex(new_stringchunk_count)) cp_data.extend(data_hex[config.get_value('STRINGCHUNKCOUNTINDEX') + 4:config.get_value('STRINGPOOLOFFSETINDEX')]) # Stringpool off set old_stringpool_offset = ApUtils.printhex( ApUtils.little_endian( data_hex[config.get_value('STRINGPOOLOFFSETINDEX'):config. get_value('STRINGPOOLOFFSETINDEX') + 4])) new_stringpool_offset = int(old_stringpool_offset, 16) + 4 cp_data.extend(ApUtils.encodehex(new_stringpool_offset)) # String off sets cp_data.extend(data_hex[config.get_value('STRINGPOOLOFFSETINDEX') + 4:config.get_value('LASTSTRINGOFFSETSINDEX') + 4]) old_laststring_offsets = ApUtils.printhex( ApUtils.little_endian( data_hex[config.get_value('LASTSTRINGOFFSETSINDEX'):config. get_value('LASTSTRINGOFFSETSINDEX') + 4])) if config.get_value('XMLFLAG') == 0: new_laststring_offsets = int( old_laststring_offsets, 16) + (config.get_value('LASTSTRINGLEN') + 2) * 2 cp_data.extend(ApUtils.encodehex(new_laststring_offsets)) elif config.get_value('XMLFLAG') == 1: new_laststring_offsets = int(old_laststring_offsets, 16) + ( config.get_value('LASTSTRINGLEN') + 2 + 1) cp_data.extend(ApUtils.encodehex(new_laststring_offsets)) else: print "[Error]Something wrong with XMLFLAG!" exit(-1) cp_data.extend(data_hex[config.get_value('LASTSTRINGOFFSETSINDEX') + 4:config.get_value('LASTSTRINGINDEX')]) # sting cp_data.extend(data_string) # 修改applicaiton name if config.get_value('APPLICATIONNAMEFLAG') == 1: # 此时application中含有android:name属性,直接修改字符串指针即可 cp_data.extend(data_hex[config.get_value('LASTSTRINGINDEX'):config. get_value('APPLICATIONNAMEINDEX')]) # namespace不用换 cp_data.extend( data_hex[config.get_value('APPLICATIONNAMEINDEX'):config. get_value('APPLICATIONNAMEINDEX') + 4]) # name不换 cp_data.extend( data_hex[config.get_value('APPLICATIONNAMEINDEX') + 4:config.get_value('APPLICATIONNAMEINDEX') + 4 + 4]) # valuesstr换,这里是下标,从0开始,因此-1 cp_data.extend(ApUtils.encodehex(new_stringchunk_count - 1)) # type不换 cp_data.extend( data_hex[config.get_value('APPLICATIONNAMEINDEX') + 4 + 4 + 4:config.get_value('APPLICATIONNAMEINDEX') + 4 + 4 + 4 + 4]) # data换 cp_data.extend(ApUtils.encodehex(new_stringchunk_count - 1)) cp_data.extend(data_hex[config.get_value('APPLICATIONNAMEINDEX') + 4 + 4 + 4 + 4 + 4:]) elif config.get_value('APPLICATIONNAMEFLAG') == 0: # 此时application中没有android:name属性,新增一个属性 cp_data.extend(data_hex[config.get_value('LASTSTRINGINDEX'):config. get_value('APPLICATIONPC')]) # type不变 cp_data.extend( data_hex[config.get_value('APPLICATIONPC' ):config.get_value('APPLICATIONPC') + 4]) # size+5*4 old_application_size = ApUtils.printhex( ApUtils.little_endian( data_hex[config.get_value('APPLICATIONPC') + 4:config.get_value('APPLICATIONPC') + 8])) new_application_size = int(old_application_size, 16) + 5 * 4 cp_data.extend(ApUtils.encodehex(new_application_size)) # linenumber+unknown+namespace+name+flag不变 cp_data.extend(data_hex[config.get_value('APPLICATIONPC') + 8:config.get_value('APPLICATIONPC') + 28]) # Attribute count +1 old_attr_count = ApUtils.printhex( ApUtils.little_endian( data_hex[config.get_value('APPLICATIONPC') + 28:config.get_value('APPLICATIONPC') + 32])) new_attr_count = int(old_attr_count, 16) + 1 cp_data.extend(ApUtils.encodehex(new_attr_count)) # class attribute cp_data.extend(data_hex[config.get_value('APPLICATIONPC') + 32:config.get_value('APPLICATIONPC') + 36]) # 接下来只需要解析一个属性即可,为了初始化一些基本字段 old_attr_namespace = data_hex[config.get_value('APPLICATIONPC') + 36:config.get_value('APPLICATIONPC') + 40] # 定位到name在Stringpool的index name_index = config.global_list['STRINGPOOL'].index("name") # 这里属性是有一定顺序的,在name前面有theme,label,icon count = 0 for j in range(int(old_attr_count, 16)): attr_num = int( ApUtils.printhex( ApUtils.little_endian( data_hex[config.get_value('APPLICATIONPC') + 36 + 4 + 4 * j * 5:config.get_value('APPLICATIONPC') + 36 + 4 + 4 * j * 5 + 4])), 16) attr_name = config.global_list['STRINGPOOL'][attr_num] if attr_name == "theme" or attr_name == "label" or attr_name == "icon": count += 1 # 拷贝这些前面的属性 cp_data.extend( data_hex[config.get_value('APPLICATIONPC') + 36 + 4 * j * 5:config.get_value('APPLICATIONPC') + 36 + 4 * j * 5 + 20]) # 新增name属性 # namespace cp_data.extend(old_attr_namespace) # name cp_data.extend(ApUtils.encodehex(name_index)) # valuestr cp_data.extend(ApUtils.encodehex(new_stringchunk_count - 1)) # type,这里是String固定type cp_data.extend(["08", "00", "00", "03"]) # data cp_data.extend(ApUtils.encodehex(new_stringchunk_count - 1)) # 拷贝剩下的属性 attr_index_start = config.get_value( 'APPLICATIONPC') + 36 + 5 * count * 4 attr_index = config.get_value('APPLICATIONPC') + 36 + 5 * int( old_attr_count, 16) * 4 cp_data.extend(data_hex[attr_index_start:attr_index]) # 剩下的拷贝 cp_data.extend(data_hex[attr_index:]) else: print("[ERROR]There is something wrong with application resolve!!!") exit(-1) ApUtils.writedata(cp_data, target_filepath) # 结束 print("[ApEditor]Change Application success!!!")
def resolver(am_path): print("[ApEditor]Begin to resolve AndroidManifest.xml") # 全局变量初始化 config.init_global() # 读取二进制文件并转化成16进制 data_hex = ApUtils.am_read(am_path) # 开始解析头部 ApResolver.am_header(data_hex) # 解析后当前指针 pc = config.get_value('AMHEADER') # 解析StringChunk ApResolver.am_stringchunk(data_hex, pc) pc = config.get_value('STRINGCHUNKEND') # 调整指针,预留16位 config.set_value('RESOURCEIDCHUNKSTAR', pc) for ind in range(16): if ApUtils.printhex( ApUtils.little_endian(data_hex[pc + ind:pc + ind + 4])) == "0x00080180": config.set_value('RESOURCEIDCHUNKSTAR', config.get_value('RESOURCEIDCHUNKSTAR') + ind) break pc = config.get_value('RESOURCEIDCHUNKSTAR') # 解析resource chunk ApResolver.am_resourceidchunk(data_hex, pc) pc = config.get_value('RESOURCEIDCHUNKEND') # print pc # 开始进入循环解析 while pc < len(data_hex): # namespace start if ApUtils.printhex(ApUtils.little_endian( data_hex[pc:pc + 4])) == "0x00100100": config.set_value('STARNAMESPACESTAR', pc) ApResolver.am_namespacechunk_star(data_hex, pc) pc = config.get_value('STARNAMESPACEEND') # tag start elif ApUtils.printhex(ApUtils.little_endian( data_hex[pc:pc + 4])) == "0x00100102": config.set_value('STARTTAGCHUNKSTAR', pc) ApResolver.am_tagchunk_star(data_hex, pc) pc = config.get_value('STARTTAGCHUNKEND') config.set_value('TAGCOUNTSTAR', config.get_value('TAGCOUNTSTAR') + 1) # tag end elif ApUtils.printhex(ApUtils.little_endian( data_hex[pc:pc + 4])) == "0x00100103": config.set_value('ENDTAGCHUNKSTAR', pc) ApResolver.am_tagchunk_end(data_hex, pc) pc = config.get_value('ENDTAGCHUNKEND') config.set_value('TAGCOUNTEND', config.get_value('TAGCOUNTEND') + 1) # tag end elif ApUtils.printhex(ApUtils.little_endian( data_hex[pc:pc + 4])) == "0x00100101": config.set_value('ENDNAMESPACESTAR', pc) ApResolver.am_namespacechunk_end(data_hex, pc) pc = config.get_value('ENDNAMESPACEEND') # text end elif ApUtils.printhex(ApUtils.little_endian( data_hex[pc:pc + 4])) == "0x00100104": config.set_value('TEXTCHUNKSTAR', pc) ApResolver.am_textchunk(data_hex, pc) pc = config.get_value('TEXTCHUNKEND') else: ApUtils.apprint("[error]NO type of the chunk,the pc is " + str(pc)) exit(-1) # 解析结束 print("[ApEditor]Resolve AndroidManifest.xml success!!!") return data_hex