#!/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()
…