#!/usr/bin/python3 import sys def getvaluefrombytes(tbytes): va = 0 for j in range(len(tbytes)): va += tbytes[j] * 256 ** j return va def decodebytesfromnum(num, lens=4): tbytes = bytearray() for i in range(lens): tbytes.append((num & (0xff << 8 * i)) >> 8 * i) return tbytes def set_cid(readbytes, channelname): # find End of central directory for i in range(len(readbytes) - 22): if (readbytes[-22 - i] == 0x50 and readbytes[-21 - i] == 0x4b and readbytes[-20 - i] == 0x05 and readbytes[ -19 - i] == 0x06): break start_central_directory_value_pos = -6 - i start_central_directory = readbytes[start_central_directory_value_pos + 3] * 256 ** 3 \ + readbytes[start_central_directory_value_pos + 2] * 256 ** 2 \ + readbytes[start_central_directory_value_pos + 1] * 256 \ + readbytes[start_central_directory_value_pos] if readbytes[start_central_directory - 16:start_central_directory] == 'APK Sig Block 42'.encode("utf-8"): print("check v2 true") else: print("check v2 fail") return sign_block_size = 0 sgin_block_value_pos = start_central_directory - 16 - 8 for i in range(8): sign_block_size += 256 ** i * readbytes[sgin_block_value_pos + i] sign_block_start_pos = start_central_directory - sign_block_size - 8 k = 0; keybytes = {} tempbytes = [] strkey = 0 k = 0 #walleid 0x71777777 walleIDbytes = bytearray() walleIDbytes.append(0x77) walleIDbytes.append(0x77) walleIDbytes.append(0x77) walleIDbytes.append(0x71) pairlen = 0 for i in range(sign_block_start_pos + 8, sgin_block_value_pos): tempbytes.append(readbytes[i]) if k == 7: pairlen = getvaluefrombytes(tempbytes) tempbytes.clear() if k == 11: strkey = getvaluefrombytes(tempbytes) tempbytes.clear() if k == pairlen + 7: keybytes[strkey] = bytes(tempbytes) tempbytes.clear() k = -1 k += 1 channel = "{\"channel\":\"%s\"}" % channelname channelbytes = bytearray(channel.encode("utf-8")) if len(channelbytes) > 252: print(" channel str len < 252") return insertbytes = bytearray() channelbytes_len = len(channelbytes) + 4 insertbytes.append(channelbytes_len) for i in range(7): insertbytes.append(0) for i in walleIDbytes: insertbytes.append(i) for i in channelbytes: insertbytes.append(i) start_central_directory += len(insertbytes) dictoffsetbytes = decodebytesfromnum(start_central_directory) for index in range(4): readbytes[start_central_directory_value_pos + index] = dictoffsetbytes[index] sign_block_size += len(insertbytes) signsizebytes = decodebytesfromnum(sign_block_size, 8) for index in range(8): readbytes[sign_block_start_pos + index] = signsizebytes[index] readbytes[sgin_block_value_pos + index] = signsizebytes[index] for b in insertbytes[::-1]: readbytes.insert(sgin_block_value_pos, b) outfilepath = "channel_%s.apk" % channelname with open(outfilepath, "wb") as fout: fout.write(readbytes) def main(): if len(sys.argv) != 3: print("i need apk_path and channel_id.") exit(-1) filepath = sys.argv[1] cid = sys.argv[2] readbytes = bytearray() with open(filepath, "rb") as f: readbytes = bytearray(f.read()) set_cid(readbytes, cid) if __name__ == "__main__": main()
…