#!
/usr/bin/env python3
# (c) B. Kerler 2017-2020, licensed under MIT license
"""
Usage:
[Link] --help
[Link] <filename>
Options:
Mode 1 for regular ozip, Mode 2 for CPH1803/CPH1909 [default: 1]
"""
from docopt import docopt
args = docopt(__doc__, version='1.2')
import os
import sys, stat
import shutil
import binascii
from [Link] import AES
from zipfile import ZipFile
keys = [
"D6EECF0AE5ACD4E0E9FE522DE7CE381E", # mnkey
"D6ECCF0AE5ACD4E0E92E522DE7C1381E", # mkey
"D6DCCF0AD5ACD4E0292E522DB7C1381E", # realkey, R9s CPH1607 MSM8953, Plus, R11, RMX1921
Realme XT, RMX1851EX Realme Android 10, RMX1992EX_11_OTA_1050
"D7DCCE1AD4AFDCE2393E5161CBDC4321", # testkey
"D7DBCE2AD4ADDCE1393E5521CBDC4321", # utilkey
"D7DBCE1AD4AFDCE1393E5121CBDC4321", # R11s CPH1719 MSM8976, Plus
"D4D2CD61D4AFDCE13B5E01221BD14D20", # FindX CPH1871 SDM845
"261CC7131D7C1481294E532DB752381E", # FindX
"1CA21E12271335AE33AB81B2A7B14622", # Realme 2 pro SDM660/MSM8976
"D4D2CE11D4AFDCE13B3E0121CBD14D20", # K1 SDM660/MSM8976
"1C4C1EA3A12531AE491B21BB31613C11", # Realme 3 Pro SDM710, X, 5 Pro, Q, RMX1921 Realme XT
"1C4C1EA3A12531AE4A1B21BB31C13C21", # Reno 10x zoom PCCM00 SDM855, CPH1921EX Reno 5G
"1C4A11A3A12513AE441B23BB31513121", # Reno 2 PCKM00 SDM730G
"1C4A11A3A12589AE441A23BB31517733", # Realme X2 SDM730G
"1C4A11A3A22513AE541B53BB31513121", # Realme 5 SDM665
"2442CE821A4F352E33AE81B22BC1462E", # R17 Pro SDM710
"14C2CD6214CFDC2733AE81B22BC1462C", # CPH1803 OppoA3s SDM450/MSM8953
"1E38C1B72D522E29E0D4ACD50ACFDCD6",
"12341EAAC4C123CE193556A1BBCC232D",
"2143DCCB21513E39E1DCAFD41ACEDBD7",
"2D23CCBBA1563519CE23C1C4AA1E3412", # A77 CPH1715 MT6750T
"172B3E14E46F3CE13E2B5121CBDC4321", # Realme 1 MTK P60
"ACAA1E12A71431CE4A1B21BBA1C1C6A2", # Realme U1 RMX1831 MTK P70
"ACAC1E13A72531AE4A1B22BB31C1CC22", # Realme 3 RMX1825EX P70
"1C4411A3A12533AE441B21BB31613C11", # A1k CPH1923 MTK P22
"1C4416A8A42717AE441523B336513121", # Reno 3 PCRM00 MTK 1000L
"ACAC1E13A12531AE4A1B21BB31C13C21", # Reno, K3
"ACAC1E13A72431AE4A1B22BBA1C1C6A2", # A9
"12CAC11211AAC3AEA2658690122C1E81", # A1,A83t
"1CA21E12271435AE331B81BBA7C14612", # CPH1909 OppoA5s MT6765
"D1DACF24351CE428A9CE32ED87323216", # Realme1(reserved)
"A1CC75115CAECB890E4A563CA1AC67C8", # A73(reserved)
"2132321EA2CA86621A11241ABA512722", # Realme3(reserved)
#F3 Plus CPH1613 - MSM8976
]
def keytest(data):
for key in keys:
ctx = [Link]([Link](key), AES.MODE_ECB)
dat = [Link](data)
if (dat[0:4] == b'\x50\x4B\x03\x04'):
print("Found correct AES key: " + key)
return [Link](key)
elif (dat[0:4] == b'\x41\x56\x42\x30'):
print("Found correct AES key: " + key)
return [Link](key)
elif (dat[0:4] == b'\x41\x4E\x44\x52'):
print("Found correct AES key: " + key)
return [Link](key)
return -1
def del_rw(action, name, exc):
[Link](name, stat.S_IWRITE)
[Link](name)
def rmrf(path):
if [Link](path):
if [Link](path):
del_rw("", path, "")
else:
[Link](path, onerror=del_rw)
def decryptfile(key, rfilename):
with open(rfilename,'rb') as rr:
with open(rfilename+".tmp", 'wb') as wf:
[Link](0x10)
dsize = int([Link](0x10).replace(b"\x00", b"").decode('utf-8'), 10)
[Link](0x1050)
print("Decrypting " + rfilename)
flen = [Link](rfilename).st_size - 0x1050
ctx = [Link](key, AES.MODE_ECB)
while (dsize > 0):
if flen > 0x4000:
size = 0x4000
else:
size = flen
data = [Link](size)
if dsize < size:
size = dsize
if len(data) == 0:
break
dr = [Link](data)
[Link](dr[:size])
flen -= size
dsize -= size
[Link](rfilename)
[Link](rfilename+".tmp",rfilename)
def decryptfile2(key, rfilename, wfilename):
with open(rfilename,'rb') as rr:
with open(wfilename, 'wb') as wf:
print("Decrypting " + rfilename)
ctx = [Link](key, AES.MODE_ECB)
bstart = 0
goon = True
while (goon):
[Link](bstart)
header = [Link](12)
if len(header) == 0:
break
if (header != b"OPPOENCRYPT!"):
[Link](1)
[Link](0x10 + bstart)
bdsize = int([Link](0x10).replace(b"\x00", b"").decode('utf-8'), 10)
if bdsize < 0x40000:
goon = False
[Link](0x50 + bstart)
while (bdsize > 0):
data = [Link](0x10)
if len(data) == 0:
break
size = 0x10;
if bdsize < 0x10:
size = bdsize
dr = [Link](data)
[Link](dr[:size])
bdsize -= 0x10
data = [Link](0x3FF0)
if len(data) == 0:
break
bdsize -= 0x3FF0
[Link](data)
bstart = bstart + 0x40000 + 0x50
def mode2(filename):
temp=[Link]([Link]([Link](filename)), "temp")
out=[Link]([Link]([Link](filename)), "out")
with open(filename, 'rb') as fr:
magic = [Link](12)
if magic[:2] == b"PK":
testkey = True
with ZipFile([Link][1], 'r') as zipObj:
if [Link](temp):
rmrf(temp)
[Link](temp)
if [Link](out):
rmrf(out)
[Link](out)
print("Extracting " + [Link][1])
[Link](temp)
tmplen = len(temp)
for r, d, f in [Link](temp):
for file in f:
rfilename = [Link](r, file)
relativefilename = rfilename[tmplen + 1 :]
wfilename = [Link](out, relativefilename)
wdirname = [Link](wfilename)
if not [Link](wdirname):
[Link](wdirname)
encrypted = False
with open(rfilename, 'rb') as rr:
magic = [Link](12)
if (magic == b"OPPOENCRYPT!"):
encrypted = True
if testkey == True:
with open([Link](temp, "[Link]"), "rb") as rt:
[Link](0x50)
data = [Link](16)
key = keytest(data)
if (key == -1):
print("Unknown AES key, reverse key from recovery first!")
[Link](1)
testkey = False
if encrypted:
decryptfile2(key, rfilename, wfilename)
else:
[Link](rfilename, wfilename)
rmrf(temp)
print("DONE... files decrypted to: " + out)
def main():
print("ozipdecrypt 1.1 (c) [Link] 2017-2020")
filename=args["<filename>"]
with open(filename, 'rb') as fr:
magic = [Link](12)
if (magic == b"OPPOENCRYPT!"):
pk = False
elif magic[:2] == b"PK":
pk = True
else:
print("ozip has unknown magic, OPPOENCRYPT! expected!")
[Link](1)
if pk == False:
[Link](0x1050)
data = [Link](16)
key = keytest(data)
if (key == -1):
print("Unknown AES key, reverse key from recovery first!")
[Link](1)
ctx = [Link](key, AES.MODE_ECB)
filename = [Link][1][:-4] + "zip"
with open(filename, 'wb') as wf:
[Link](0x1050)
print("Decrypting...")
while (True):
data = [Link](16)
if len(data) == 0:
break
[Link]([Link](data))
data = [Link](0x4000)
if len(data) == 0:
break
[Link](data)
print("DONE!!")
else:
testkey = True
filename = [Link]([Link][1])
path = [Link]([Link](filename))
outpath = [Link](path, "out")
if [Link](outpath):
[Link](outpath)
[Link](outpath)
with ZipFile(filename, 'r') as zo:
clist = []
try:
if [Link]('oppo_metadata', outpath):
with open([Link](outpath, 'oppo_metadata')) as rt:
for line in rt:
[Link](line[:-1])
except:
print("Detected mode 2....")
mode2(filename)
[Link](0)
if testkey:
fname = ''
if "firmware-update/[Link]" in clist:
fname = "firmware-update/[Link]"
#fname = [Link]('firmware-update', '[Link]')
elif "[Link]" in clist:
fname = '[Link]'
if fname != '':
if [Link](fname, outpath):
with open([Link](outpath, [Link]("/", [Link])), "rb") as rt:
[Link](0x1050)
data = [Link](16)
key = keytest(data)
if (key == -1):
print("Unknown AES key, reverse key from recovery first!")
[Link](1)
testkey = False
if testkey == True:
print("Unknown image, please report an issue with image name!")
[Link](0)
for info in [Link]():
print("Extracting " + [Link])
outfile = [Link](outpath, [Link])
if not [Link](outfile):
[Link]([Link], outpath)
if len(clist) > 0:
if [Link] in clist:
decryptfile(key, outfile)
else:
magic = b''
with open(outfile, 'rb') as rr:
magic = [Link](12)
if (magic == b"OPPOENCRYPT!"):
decryptfile(key, outfile)
print("DONE... files decrypted to: " + outpath)
if __name__ == '__main__':
main()