Add fancy stuff

This commit is contained in:
Bjoern Kerler 2021-05-09 16:44:26 +02:00
parent bc4ba64552
commit d6f95b620c
28 changed files with 804 additions and 11 deletions

8
.idea/.gitignore vendored Normal file
View file

@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
# Editor-based HTTP Client requests
/httpRequests/

12
.idea/edl_github.iml Normal file
View file

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="jdk" jdkName="Python 3.8" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="PyDocumentationSettings">
<option name="format" value="PLAIN" />
<option name="myDocStringFormat" value="Plain" />
</component>
</module>

View file

@ -0,0 +1,44 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="DuplicatedCode" enabled="true" level="WEAK WARNING" enabled_by_default="true">
<Languages>
<language minSize="78" name="Python" />
</Languages>
</inspection_tool>
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="PyPackageRequirementsInspection" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoredPackages">
<value>
<list size="17">
<item index="0" class="java.lang.String" itemvalue="dnspython" />
<item index="1" class="java.lang.String" itemvalue="qiling" />
<item index="2" class="java.lang.String" itemvalue="matplotlib" />
<item index="3" class="java.lang.String" itemvalue="lxml" />
<item index="4" class="java.lang.String" itemvalue="numpy" />
<item index="5" class="java.lang.String" itemvalue="pytz" />
<item index="6" class="java.lang.String" itemvalue="requests" />
<item index="7" class="java.lang.String" itemvalue="ldap3" />
<item index="8" class="java.lang.String" itemvalue="idna" />
<item index="9" class="java.lang.String" itemvalue="coverage" />
<item index="10" class="java.lang.String" itemvalue="colorama" />
<item index="11" class="java.lang.String" itemvalue="PyQt5" />
<item index="12" class="java.lang.String" itemvalue="frida" />
<item index="13" class="java.lang.String" itemvalue="frida-tools" />
<item index="14" class="java.lang.String" itemvalue="pyserial" />
<item index="15" class="java.lang.String" itemvalue="argparse" />
<item index="16" class="java.lang.String" itemvalue="keystone" />
</list>
</value>
</option>
</inspection_tool>
<inspection_tool class="PyUnresolvedReferencesInspection" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoredIdentifiers">
<list>
<option value="object.__getitem__" />
<option value="object.__setitem__" />
</list>
</option>
</inspection_tool>
</profile>
</component>

View file

@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

4
.idea/misc.xml Normal file
View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.8" project-jdk-type="Python SDK" />
</project>

8
.idea/modules.xml Normal file
View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/edl_github.iml" filepath="$PROJECT_DIR$/.idea/edl_github.iml" />
</modules>
</component>
</project>

6
.idea/vcs.xml Normal file
View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

View file

@ -1,3 +1,7 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# (c) B.Kerler 2018-2021
import logging import logging
from Library.utils import LogBase from Library.utils import LogBase

View file

@ -1,14 +1,26 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# (c) B.Kerler 2018-2021
from Library.utils import LogBase from Library.utils import LogBase
import logging import logging
try: try:
from Library.Modules.generic import generic from Library.Modules.generic import generic
except Exception as e: except ImportError as e:
generic = None
pass
try:
from Library.Modules.oneplus import oneplus
except ImportError as e:
oneplus = None
pass pass
try: try:
from Library.Modules.xiaomi import xiaomi from Library.Modules.xiaomi import xiaomi
except Exception as e: except ImportError as e:
xiaomi = None
pass pass
class modules(metaclass=LogBase): class modules(metaclass=LogBase):
@ -16,6 +28,7 @@ class modules(metaclass=LogBase):
self.fh = fh self.fh = fh
self.args = args self.args = args
self.serial = serial self.serial = serial
self.error = self.__logger.error
self.supported_functions = supported_functions self.supported_functions = supported_functions
self.__logger.setLevel(loglevel) self.__logger.setLevel(loglevel)
if loglevel==logging.DEBUG: if loglevel==logging.DEBUG:
@ -26,10 +39,15 @@ class modules(metaclass=LogBase):
self.devicemodel = devicemodel self.devicemodel = devicemodel
self.generic = None self.generic = None
try: try:
self.generic = generic(fh=self.fh, serial=self.serial, args=self.args, loglevel=self.__logger.level) self.generic = generic(fh=self.fh, serial=self.serial, args=self.args, loglevel=loglevel)
except Exception as e: except Exception as e:
pass pass
self.ops = None self.ops = None
try:
self.ops = oneplus(fh=self.fh, projid=self.devicemodel, serial=self.serial,
supported_functions=self.supported_functions, loglevel=loglevel)
except Exception as e:
pass
self.xiaomi=None self.xiaomi=None
try: try:
self.xiaomi = xiaomi(fh=self.fh) self.xiaomi = xiaomi(fh=self.fh)
@ -37,9 +55,13 @@ class modules(metaclass=LogBase):
pass pass
def addpatch(self): def addpatch(self):
if self.ops is not None:
return self.ops.addpatch()
return "" return ""
def addprogram(self): def addprogram(self):
if self.ops is not None:
return self.ops.addprogram()
return "" return ""
def edlauth(self): def edlauth(self):
@ -48,6 +70,8 @@ class modules(metaclass=LogBase):
return True return True
def writeprepare(self): def writeprepare(self):
if self.ops is not None:
return self.ops.run()
return True return True
def run(self, command, args): def run(self, command, args):
@ -61,7 +85,7 @@ class modules(metaclass=LogBase):
else: else:
options[args[i]] = True options[args[i]] = True
if command=="": if command=="":
print("Valid commands are:\noemunlock\n") print("Valid commands are:\noemunlock, ops\n")
return False return False
if self.generic is not None and command == "oemunlock": if self.generic is not None and command == "oemunlock":
if "enable" in options: if "enable" in options:
@ -69,7 +93,49 @@ class modules(metaclass=LogBase):
elif "disable" in options: elif "disable" in options:
enable = False enable = False
else: else:
self.__logger.error("Unknown mode given. Available are: enable, disable.") self.error("Unknown mode given. Available are: enable, disable.")
return False return False
return self.generic.oem_unlock(enable) return self.generic.oem_unlock(enable)
elif self.ops is not None and command == "ops":
if self.devicemodel is not None:
enable = False
partition = "param"
if "enable" in options:
enable = True
elif "disable" in options:
enable = False
else:
self.error("Unknown mode given. Available are: enable, disable.")
return False
res = self.fh.detect_partition(self.args, partition)
if res[0]:
lun = res[1]
rpartition = res[2]
paramdata = self.fh.cmd_read_buffer(lun, rpartition.sector, rpartition.sectors, False)
if paramdata == b"":
self.error("Error on reading param partition.")
return False
paramdata = self.ops.enable_ops(paramdata, enable,self.devicemodel,self.serial)
if paramdata!=None:
self.ops.run()
if self.fh.cmd_program_buffer(lun, rpartition.sector, paramdata, False):
print("Successfully set mode")
return True
else:
self.error("Error on writing param partition")
return False
else:
self.error("No param info generated, did you provide the devicemodel ?")
return False
else:
fpartitions = res[1]
self.error(f"Error: Couldn't detect partition: {partition}\nAvailable partitions:")
for lun in fpartitions:
for rpartition in fpartitions[lun]:
if self.args["--memory"].lower() == "emmc":
self.error("\t" + rpartition)
else:
self.error(lun + ":\t" + rpartition)
else:
self.error("A devicemodel is needed for this command")
return False return False

581
Library/Modules/oneplus.py Executable file
View file

@ -0,0 +1,581 @@
#!/usr/bin/env python3
"""
Usage:
oneplus.py rawxml [--projid=value] [--serial=value]
oneplus.py rawnewxml [--projid=value] [--ts=value] [--serial=value]
oneplus.py setprojmodel_verify <token> <pk> [--projid=value]
oneplus.py setswprojmodel_verify <token> <pk> [--projid=value] [--ts=value]
oneplus.py program_verify <token> <prog_token> <pk> [--projid=value]
Options:
--projid=value Set the appropriate projid [default: 18825]
--serial=value Set the appropriate serial [default: 123456]
--ts=value Set the device timestamp [default: 1604949411]
"""
import time
import random
from struct import pack
import logging
from Library.utils import LogBase
try:
from Library.cryptutils import cryptutils
except Exception as e:
print(e)
from ..cryptutils import cryptutils
from binascii import unhexlify, hexlify
deviceconfig={
# OP5
"16859": dict(version=1,cm=None,param_mode=0),
# OP5t, Dumpling
"17801": dict(version=1,cm=None,param_mode=0),
# OP6T Europe, fajita
"17819": dict(version=1,cm=None,param_mode=0),
# Oneplus 7 Pro
"18821": dict(version=1,cm=None,param_mode=0),
"18825": dict(version=1,cm=None,param_mode=0),
"18827": dict(version=1,cm=None,param_mode=0),
"18857": dict(version=1,cm=None,param_mode=0),
# Oneplus 7t
"18865": dict(version=1,cm=None,param_mode=0),
"19801": dict(version=1,cm=None,param_mode=0),
"19861": dict(version=1,cm=None,param_mode=0),
"19863": dict(version=1,cm=None,param_mode=0),
"18831": dict(version=1,cm=None,param_mode=0),
# OP8 Pro, instantnoodlep
"19811": dict(version=2,cm="40217c07",param_mode=0),
# OP8, instantnoodle
"19821": dict(version=2,cm="0cffee8a",param_mode=0),
# OP8 T-Mo, instantnoodlet
"19855": dict(version=2,cm="6d9215b4",param_mode=0),
# OP8 Verizon, instantnoodlev
"19867": dict(version=2,cm="4107b2d4",param_mode=0),
# OP8 Verizon, instantnoodlevis
"19868": dict(version=-1,cm="178d8213",param_mode=0),
# OP8t, kebab
"19805": dict(version=2,cm="1a5ec176",param_mode=0),
# OP8t T-Mo, kebabt
"20809": dict(version=2,cm="d6bc8c36",param_mode=0),
# OP Nord, Avicii
"20801": dict(version=2,cm="eacf50e7",param_mode=0),
# billie8t, OP N10 5G Metro
"20885": dict(version=3,cm = "3a403a71",param_mode=1),
# billie8 Global, OP N10 5G
"20886": dict(version=3,cm = "b8bd9e39",param_mode=1),
# billie8t, OP N10 5G TMO
"20888": dict(version=3,cm = "142f1bd7",param_mode=1),
# billie8 Europe, OP N10 5G
"20889": dict(version=3,cm = "f2056ae1",param_mode=1),
# bengalt, OP N100 TMO
"20880": dict(version=3,cm = "6ccf5913",param_mode=1),
# bengal Global, OP N100
"20881": dict(version=3,cm = "fa9ff378",param_mode=1),
# bengalt, OP N100 TMO
"20882": dict(version=3,cm = "4ca1e84e",param_mode=1),
# bengal Europe, OP N100
"20883": dict(version=3,cm = "ad9dba4a",param_mode=1),
# lemonadep, OP9 Pro
"19815": dict(version=2,cm = "9c151c7f", param_mode=0),
"20859": dict(version=2,cm = "9c151c7f", param_mode=0),
# lemonadept, OP9 Pro TMO
"2085A": dict(version=2,cm = "7f19519a",param_mode=1),
# lemonade, OP9
"19825": dict(version=2,cm = "0898dcd6",param_mode=1),
# lemonadet, OP9 TMO
"20854": dict(version=2,cm = "16225d4e",param_mode=1),
# lemonadev, OP9 VZW
"2080A": dict(version=2,cm = "020885c8",param_mode=1),
# charpentier
"20828": dict(version=2,cm = None,param_mode=1),
# dre8t
"20818": dict(version=2, cm=None, param_mode=1),
# dre8m
"2083C": dict(version=2, cm=None, param_mode=1),
# dre9
"2083D": dict(version=2, cm=None, param_mode=1)
}
class oneplus(metaclass=LogBase):
def __init__(self, fh, projid="18825", serial=123456, ATOBuild=0, Flash_Mode=0, cf=0, supported_functions=None, loglevel=logging.INFO):
self.fh = fh
self.ATOBuild = ATOBuild
self.Flash_Mode = Flash_Mode
self.cf = cf # CustFlag
self.supported_functions = supported_functions
self.__logger.setLevel(loglevel)
if loglevel==logging.DEBUG:
logfilename = "log.txt"
fh = logging.FileHandler(logfilename)
self.__logger.addHandler(fh)
try:
from Library.Modules.oneplus_param import paramtools
if projid in deviceconfig:
mode = deviceconfig[projid]["param_mode"]
self.ops_parm = paramtools(mode=mode,serial=serial)
else:
self.ops_parm = paramtools(mode=0, serial=serial)
except ImportError as e:
self.__logger.error(str(e))
self.ops_parm = None
self.ops = self.convert_projid(fh, projid, serial)
def getprodkey(self, projid):
if projid in ["18825", "18801"]: # key_guacamoles, fajiita
prodkey = "b2fad511325185e5"
else: # key_op7t/op8/N10
prodkey = "7016147d58e8c038"
return prodkey
def convert_projid(self, fh, projid, serial):
prodkey = self.getprodkey(projid)
pk = ""
val = bytearray(b"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")
for i in range(0, 16):
rand = int(random.randint(0, 0x100))
nr = (rand & 0xFF) % 0x3E
pk += chr(val[nr])
if projid in deviceconfig:
version=deviceconfig[projid]["version"]
cm=deviceconfig[projid]["cm"]
if version==1:
return oneplus1(fh, projid, serial, pk, prodkey, self.cf)
elif version==2:
if cm is not None:
return oneplus1(fh, cm, serial, pk, prodkey, self.cf)
else:
assert "Device is not supported"
exit(0)
elif version==3:
if cm is not None:
oneplus2(fh, cm, serial, pk, prodkey, self.ATOBuild, self.Flash_Mode, self.cf)
else:
assert "Device is not supported"
exit(0)
return None
def run(self):
if self.ops is not None:
if "demacia" in self.supported_functions:
if not self.ops.run("demacia"):
exit(0)
if "SetNetType" in self.supported_functions:
self.fh.cmd_send(f"SetNetType")
elif "setprojmodel" in self.supported_functions:
if not self.ops.run(""):
exit(0)
if "setprocstart" in self.supported_functions:
if not self.ops.run(""):
exit(0)
return True
def setprojmodel_verify(self, pk, token):
if self.ops.setprojmodel_verify:
return self.ops.setprojmodel_verify(pk, token)
def setswprojmodel_verify(self, pk, token, device_timestamp):
if self.ops.setswprojmodel_verify:
return self.ops.setswprojmodel_verify(pk, token, device_timestamp)
def program_verify(self, pk, token, tokendata):
if self.ops.program_verify:
return self.ops.program_verify(pk, token, tokendata)
def generatetoken(self, program=False, device_timestamp="123456789"):
return self.ops.generatetoken(program=program, device_timestamp=device_timestamp)
def demacia(self):
if self.ops.demacia():
return self.ops.demacia()
def enable_ops(self, data, enable, projid, serial):
if self.ops_parm is not None:
return self.ops_parm.enable_ops(data, enable)
return None
def addpatch(self):
if "setprojmodel" in self.supported_functions or "setswprojmodel" in self.supported_functions:
pk, token = self.ops.generatetoken(True)
return f"pk=\"{pk}\" token=\"{token}\" "
else:
return ""
def addprogram(self):
if "setprojmodel" in self.supported_functions or "setswprojmodel" in self.supported_functions:
pk, token = self.ops.generatetoken(True)
return f"pk=\"{pk}\" token=\"{token}\" "
else:
return ""
class oneplus1:
def __init__(self, fh, ModelVerifyPrjName="18825", serial=123456, pk="", prodkey="", cf=0):
self.pk = pk
self.prodkey = prodkey
self.ModelVerifyPrjName = ModelVerifyPrjName
self.fh = fh
self.random_postfix = "8MwDdWXZO7sj0PF3"
self.Version = "guacamoles_21_O.22_191107"
self.cf = str(cf)
self.soc_sn = str(serial)
def crypt_token(self, data, pk, decrypt=False, demacia=False):
aes = cryptutils().aes()
if demacia:
aeskey = b"\x01\x63\xA0\xD1\xFD\xE2\x67\x11" + bytes(pk, 'utf-8') + b"\x48\x27\xC2\x08\xFB\xB0\xE6\xF0"
aesiv = b"\x96\xE0\x79\x0C\xAE\x2B\xB4\xAF\x68\x4C\x36\xCB\x0B\xEC\x49\xCE"
else:
aeskey = b"\x10\x45\x63\x87\xE3\x7E\x23\x71" + bytes(pk, 'utf-8') + b"\xA2\xD4\xA0\x74\x0f\xD3\x28\x96"
aesiv = b"\x9D\x61\x4A\x1E\xAC\x81\xC9\xB2\xD3\x76\xD7\x49\x31\x03\x63\x79"
if decrypt:
cdata = unhexlify(data)
result = aes.aes_cbc(aeskey, aesiv, cdata)
result = result.rstrip(b'\x00')
if result[:16] == b"907heavyworkload":
return result
else:
return result.decode('utf-8').split(',')
else:
if not demacia:
while len(data) < 256:
data += "\x00"
pdata = bytes(data, 'utf-8')
else:
while len(data) < 256:
data += b"\x00"
pdata = data
result = aes.aes_cbc(aeskey, aesiv, pdata, False)
rdata = hexlify(result)
return rdata.upper().decode('utf-8')
def cmd_setpro(self):
pk, token = self.generatetoken(False)
data = "<?xml version=\"1.0\" ?>\n<data>\n<setprojmodel token=\"" + token + "\" pk=\"" + pk + "\" />\n</data>"
return data
def cmd_dem(self):
pk, token = self.demacia()
data = "<?xml version=\"1.0\" ?>\n<data>\n<demacia token=\"" + token + "\" pk=\"" + pk + "\" />\n</data>"
return data
def generatetoken(self, program=False, device_timestamp=None):
timestamp = str(int(time.time()))
ha = cryptutils().hash()
h1 = self.prodkey + self.ModelVerifyPrjName + self.random_postfix
ModelVerifyHashToken = hexlify(ha.sha256(bytes(h1, 'utf-8'))).decode('utf-8').upper()
# ModelVerifyPrjName=0x1C [0]
# random_postfix=0x2D [1]
# verify_hash=0x3E [2] Len:0x41
# ver=0x90 [3]
# cf=0x4 [4]
# sn=0x14 [5]
# ts=0x7f [6] Len:0x11
# secret=0xd1 (hash store) [7], len:0x41
# 0x7, Len:0x11
# 0x24, Len:0x41
# 0x1c 0x4 0x14 0x90 0x7f ModelVerifyHashToken
h2 = "c4b95538c57df231" + self.ModelVerifyPrjName + self.cf + self.soc_sn + self.Version + \
timestamp + ModelVerifyHashToken + "5b0217457e49381b"
secret = hexlify(ha.sha256(bytes(h2, 'utf-8'))).decode('utf-8').upper() # 0xd1
if program:
items = [timestamp, secret]
else:
items = [self.ModelVerifyPrjName, self.random_postfix, ModelVerifyHashToken, self.Version, self.cf,
self.soc_sn, timestamp, secret]
data = ""
for item in items:
data += item + ","
data = data[:-1]
token = self.crypt_token(data, self.pk)
return self.pk, token
def setprojmodel_verify(self, pk, token):
self.pk = pk
ha = cryptutils().hash()
items = self.crypt_token(token, pk, True, False)
info = ["Projid", "ModelVerifyHashToken", "Hash1", "FirmwareString", "CustFlag", "SOC_Serial", "Timestamp",
"secret"]
i = 0
print()
if len(info) == len(items):
for item in items:
print(info[i] + "=" + item)
i += 1
# Old
# 0=ModelVerifyPrjName [param+0x1C]
# 1=random_postfix [param+0x2D]
# 2=hash(key+0+1) [ModelVerifyHashToken param+0x3E]
# 3=ver [param_1+0x90]
# 4=cf [param_1+4]
# 5=serial? [param_1+0x14]
# 6=timestamp [param_1+0x7F]
hash1 = self.prodkey + items[0] + items[1]
res1 = hexlify(ha.sha256(bytes(hash1, 'utf-8'))).decode('utf-8').upper()
if items[2] != res1:
print("Hash1 failed !")
return
# ModelVerifyPrjName cf sn ver ts ModelVerifyHashToken
secret = "c4b95538c57df231" + items[0] + items[4] + items[5] + items[3] + items[6] + \
items[2] + "5b0217457e49381b"
res2 = hexlify(ha.sha256(bytes(secret, 'utf-8'))).decode('utf-8').upper()
if items[7] != res2:
print("secret failed !")
return
print("setprojmodel good")
return items
def toSigned32(self, n):
n = n & 0xffffffff
return (n ^ 0x80000000) - 0x80000000
def demacia(self):
"""
return "<?xml version=\"1.0\" ?>\n<data>\n " + \
"<program SECTOR_SIZE_IN_BYTES=\"4096\" filename=\"param.bin\" " + \
"num_partition_sectors=\"256\" partofsingleimage=\"0\" physical_partition_number=\"0\" " + \
"read_back_verify=\"1\" start_sector=\"8456\" token=\""+token+"\" pk=\""+pk+"\" />\n</data>"
"""
ha = cryptutils().hash()
serial = self.soc_sn
while len(serial) < 10:
serial = '0' + serial
hash1 = "2e7006834dafe8ad" + serial + "a6674c6b039707ff"
data = b"907heavyworkload" + ha.sha256(bytes(hash1, 'utf-8'))
token = self.crypt_token(data, self.pk, False, True)
return self.pk, token
def run(self, flag):
if flag == "demacia":
pk, token = self.demacia()
res = self.fh.cmd_send(f"demacia token=\"{token}\" pk=\"{pk}\"")
if b"verify_res=\"0\"" not in res:
print("Demacia failed:")
print(res)
return False
pk, token = self.generatetoken(False)
res = self.fh.cmd_send(f"setprojmodel token=\"{token}\" pk=\"{pk}\"")
if b"model_check=\"0\"" not in res or b"auth_token_verify=\"0\"" not in res:
print("Setprojmodel failed.")
print(res)
return False
return True
def program_verify(self, pk, token, tokendata):
print()
self.pk = pk
items = self.crypt_token(token, pk, True, False)
if len(items) == 2:
print("Timestamp=" + items[0])
print("secret=" + items[1])
if items[0] != tokendata[6] or items[1] != tokendata[7]:
print("Hash failed !")
return
print("program good")
class oneplus2(metaclass=LogBase):
def __init__(self, fh, ModelVerifyPrjName="20889", serial=123456, pk="", prodkey="", ATOBuild=0, Flash_Mode=0,
cf=0, loglevel=logging.INFO):
self.ModelVerifyPrjName = ModelVerifyPrjName
self.pk = pk
self.fh = fh
self.prodkey = prodkey
self.random_postfix = "c75oVnz8yUgLZObh" # ModelVerifyRandom
self.Version = "billie8_14_E.01_201028" # Version
self.device_id = str(int(ModelVerifyPrjName, 16))
self.flash_mode = str(Flash_Mode)
self.ato_build_state = str(ATOBuild)
self.soc_sn = str(serial)
self.__logger.setLevel(loglevel)
if loglevel==logging.DEBUG:
logfilename = "log.txt"
fh = logging.FileHandler(logfilename)
self.__logger.addHandler(fh)
def crypt_token(self, data, pk, device_timestamp, decrypt=False):
aes = cryptutils().aes()
aeskey = b"\x46\xA5\x97\x30\xBB\x0D\x41\xE8" + bytes(pk, 'utf-8') + \
pack("<Q", int(device_timestamp,10)) # we get this using setprocstart
aesiv = b"\xDC\x91\x0D\x88\xE3\xC6\xEE\x65\xF0\xC7\x44\xB4\x02\x30\xCE\x40"
if decrypt:
cdata = unhexlify(data)
result = aes.aes_cbc(aeskey, aesiv, cdata)
result = result.rstrip(b'\x00')
return result.decode('utf-8').split(',')
else:
while len(data) < 0x200:
data += "\x00"
pdata = bytes(data, 'utf-8')
result = aes.aes_cbc(aeskey, aesiv, pdata, False)
rdata = hexlify(result)
return rdata.upper().decode('utf-8')
def generatetoken(self, program=False, device_timestamp=None): # setswprojmodel
timestamp = str(int(time.time()))
ha = cryptutils().hash()
h1 = self.prodkey + self.ModelVerifyPrjName + self.random_postfix
ModelVerifyHashToken = hexlify(ha.sha256(bytes(h1, 'utf-8'))).decode('utf-8').upper()
# 0x1c[0x10] 0x4 0x90 0x7f 0x3e ModelVerifyHashToken/verify_hash
h2 = self.prodkey + self.ModelVerifyPrjName + self.soc_sn + self.Version + timestamp + \
ModelVerifyHashToken + "8f7359c8a2951e8c"
secret = hexlify(ha.sha256(bytes(h2, 'utf-8'))).decode('utf-8').upper()
if program:
items = [timestamp, secret]
else: # 0x1C[0x10] 0x2D[0x11] 0x3E[0x41] 0x10[0x4]
# 0x14[0x4] 0x90[0x40] 0x4[0x4] 0x114[0x4] 0x7F[0x10] 0xD1[0x41]
items = [self.ModelVerifyPrjName, self.random_postfix, ModelVerifyHashToken, self.ato_build_state,
self.flash_mode, self.Version, self.soc_sn, self.device_id, timestamp, secret]
data = ""
for item in items:
data += item + ","
data = data[:-1]
token = self.crypt_token(data, self.pk, device_timestamp)
return self.pk, token
def run(self, flag):
res = self.fh.cmd_send(f"setprocstart")
if not b"device_timestamp" in res:
print("Setprocstart failed.")
print(res.decode('utf-8'))
return False
data = res.decode('utf-8')
device_timestamp = data[data.rfind("device_timestamp"):].split("\"")[1]
pk, token = self.generatetoken(False, device_timestamp)
res = self.fh.cmd_send(f"setswprojmodel token=\"{token}\" pk=\"{pk}\"")
if not b"model_check=\"0\"" in res or not b"auth_token_verify=\"0\"" in res:
print("Setswprojmodel failed.")
print(res.decode('utf-8'))
return False
return True
def setswprojmodel_verify(self, pk, token, device_timestamp):
self.pk = pk
ha = cryptutils().hash()
items = self.crypt_token(token, pk, device_timestamp, True)
info = ["ModelVerifyPrjName", "random_postfix", "ModelVerifyHashToken", "ato_build_state", "flash_mode",
"Version", "soc_sn", "cf", "timestamp", "secret"]
i = 0
print()
if len(info) == len(items):
for item in items:
print(info[i] + "=" + item)
i += 1
# New
# 0=ModelVerifyPrjName [param+0x1C]
# 1=random_postfix [param+0x2D]
# 2=hash [param_1+0xd1]
# 3=[ATO Build state param+0x3E]
# 4=[flash mode param_1+0x10]
# 5=[img ver param+0x14]
# 6=soc sn [param_1+0x90]
# 7=cf [param_1+4]
# 8=timestamp [param_1+0x114]
# 9=secret [param_1+0x7f]
hash1 = self.prodkey + items[0] + items[1]
res1 = hexlify(ha.sha256(bytes(hash1, 'utf-8'))).decode('utf-8').upper()
if items[2] != res1:
print("Hash1 failed !")
return
# ModelVerifyPrjName sn ver ts ModelVerifyHashToken
secret = self.prodkey + items[0] + items[6] + items[5] + items[8] + items[2] \
+ "8f7359c8a2951e8c"
# h2 = self.prodkey + self.ModelVerifyPrjName + self.soc_sn + self.Version + timestamp +
# ModelVerifyHashToken + "8f7359c8a2951e8c"
res2 = hexlify(ha.sha256(bytes(secret, 'utf-8'))).decode('utf-8').upper()
if items[9] != res2:
print("secret failed !")
return
print("setswprojmodel good")
return items
def main():
from docopt import docopt
args = docopt(__doc__, version='oneplus 1.2')
# filename="param_jacob_7pro.bin"
# filename="chris/param.bin"
if args["rawxml"]:
projid = args["--projid"][0]
serial = args["--serial"]
op = oneplus(None, projid=projid, serial=serial)
# 18831 2799496336,2799496336
# 18825
# 18857 7 Europe
pk, token = op.demacia()
print(
f"./edl.py rawxml \"<?xml version=\\\"1.0\\\" ?><data><demacia "+
f"token=\\\"{token}\\\" pk=\\\"{pk}\\\" /></data>\"")
pk, token = op.generatetoken(False)
print(
f"./edl.py rawxml \"<?xml version=\\\"1.0\\\" ?><data><setprojmodel " +
f"token=\\\"{token}\\\" pk=\\\"{pk}\\\" /></data>\" --debugmode")
elif args["rawnewxml"]:
serial = args["--serial"]
device_timestamp = args["--ts"]
op2 = oneplus(None, projid="20889", serial=serial, ATOBuild=0, Flash_Mode=0, cf=0)
# 20889 OP N10 5G Europe
print(f"./edl.py rawxml \"<?xml version=\\\"1.0\\\" ?><data><setprocstart /></data>\"")
# Response should be : <?xml version="1.0" ?><data><response value=1 device_timestamp="%llu" /></data>
pk, token = op2.generatetoken(False, device_timestamp)
print(
f"./edl.py rawxml \"<?xml version=\\\"1.0\\\" ?><data><setswprojmodel " +
f"token=\\\"{token}\\\" pk=\\\"{pk}\\\" /></data>\" --debugmode")
elif args["setprojmodel_verify"]:
projid = args["--projid"][0]
op = oneplus(None, projid=projid, serial=123456)
token = args["<token>"]
pk = args["<pk>"]
# setprojmodel_verify 2BA77B345812E4E45DDB5E407CF9B0F20BCD3E4F0C504A86A3DAA7D70643D0D86F4F5DAEE99E21093D26FF8A8A
# 7C2CCFED387FA4C7D3BC6D8B8C2CC2D27D398886FC150C98CDC521699568C4A419D7E2F2C1A33F6B57AA7CCB5F
# 39D69BB87463986B2CADDD55A41F0F9404C3FB08B0325BFDFCFDE05D1D8314D22F39979A289505D5050D854092
# CFC9FA3C101A267DD3ECA0442BF89066365ABA6607D43743D86B47B228BAAC5538B622644D74FD4049BE37C520
# 76DE1B4BFE75187A7B0EE88E6C26E106570B8C0541C4693878BE9B23DEB8E4C530CFBFE9F25597FA3A86223711
# 2CAF77F0D1EA4CC41EB201FFAE31036FC9E405BABAE43DE9C7E56FE1DC8E82 KHaJV1TfN45ofeLW 18865
# setprojmodel_verify 633B7E2BBE68BAC392B3E10FC8FEAC09F152853805A6D91FAADDE5A631C7B5A6081C6156F7344BDF407ABF7598
# 0A9E6DA96964D472FE94311FEAADF6A9032C623A1C5D5B9BDD68C5E049F13DF9D893422C1A44047B1AC8E05A0A
# 2A942B15B409A933A06BAB09F41FB0A3A5C8FEB86B98D39739FA4E2ABDF471DE181646F7AA228C6EC81DB3BAF2
# F2C3B5381FC9A722F9D11B6A101CAAE31ACD873B83B39AC07B7603EAA38B13F5D0B5E8F9236FB94B967AECE278
# FEA280E9330636F7C6C72C36A6040F6B8BC3C56AEC9CB0C07360E14EA83D2F6DEC4613FA74D79C325A320B88F2
# BF025CF9CE528E13169BA255E68909D7E902CE494B49514F6F57713D6F46BE Tgu1kbDW3NemNNqn 18831
op.setprojmodel_verify(pk, token)
elif args["program_verify"]:
projid = args["--projid"][0]
op = oneplus(None, projid=projid)
token = args["<token>"]
prog_token = args["<prog_token>"]
pk = args["<pk>"]
items = op.setprojmodel_verify(pk, token)
op.program_verify(pk, prog_token, items)
elif args["setswprojmodel_verify"]:
projid = args["--projid"][0]
device_timestamp = args["--ts"]
op = oneplus(None, projid=projid, serial=123456)
token = args["<token>"]
pk = args["<pk>"]
op.setswprojmodel_verify(pk, token, device_timestamp)
def test_setswprojmodel_verify():
deviceresp = b"RX:<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\nRX:<data>\nRX:<response value=\"ACK\" " + \
b"device_timestamp=\"2507003650\" /></data>\n<?xmlversion=\"1.0\" ? ><data><setprocstart /></data>"
projid = "20889"
op = oneplus(None, projid=projid, serial=123456)
data = deviceresp.decode('utf-8')
device_timestamp = data[data.rfind("device_timestamp"):].split("\"")[1]
pk, token = op.generatetoken(False, device_timestamp)
if not op.setswprojmodel_verify(pk, token, device_timestamp):
assert "Setswprojmodel error"
if __name__ == "__main__":
main()

View file

@ -1,3 +1,7 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# (c) B.Kerler 2018-2021
import logging import logging
from Library.utils import LogBase from Library.utils import LogBase

View file

@ -1,4 +1,7 @@
#!/usr/bin/env python3 #!/usr/bin/python3
# -*- coding: utf-8 -*-
# (c) B.Kerler 2018-2021
from capstone import * from capstone import *
from keystone import * from keystone import *
from binascii import unhexlify from binascii import unhexlify

View file

@ -1,3 +1,7 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# (c) B.Kerler 2018-2019
import binascii import binascii
import platform import platform
import time import time

View file

@ -1,3 +1,7 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# (c) B.Kerler 2018-2019
import os import os
import sys import sys
import logging import logging

View file

@ -1,6 +1,11 @@
#!/usr/bin/env python3 #!/usr/bin/python3
# -*- coding: utf-8 -*-
# (c) B.Kerler 2018-2019
from binascii import hexlify from binascii import hexlify
from Library.utils import * try:
from Library.utils import *
except:
from utils import *
class gpt(metaclass=LogBase): class gpt(metaclass=LogBase):

View file

@ -1,3 +1,7 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# (c) B.Kerler 2018-2019
import logging import logging
from binascii import hexlify from binascii import hexlify
from struct import unpack from struct import unpack

View file

@ -1,3 +1,7 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# (c) B.Kerler 2018-2021
import os import os
import pt64 import pt64
import pt import pt

View file

@ -1,3 +1,6 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# (c) B.Kerler 2018-2019
import ctypes import ctypes
from enum import Enum from enum import Enum
from Config.qualcomm_config import secgen, secureboottbl from Config.qualcomm_config import secgen, secureboottbl

View file

@ -1,3 +1,6 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# (c) B.Kerler 2018-2021
import binascii import binascii
import time import time
import os import os

View file

@ -1,4 +1,6 @@
#!/usr/bin/env python3 #!/usr/bin/python3
# -*- coding: utf-8 -*-
# (c) B.Kerler 2018-2021
import logging import logging
import sys import sys
from queue import Queue from queue import Queue

View file

@ -1,3 +1,6 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# (c) B.Kerler 2018-2021
from struct import pack from struct import pack
from binascii import unhexlify from binascii import unhexlify
from Library.utils import * from Library.utils import *

View file

@ -1,3 +1,6 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# (c) B.Kerler 2018-2021
import sys import sys
import os import os
import logging import logging

View file

@ -1,3 +1,7 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# (c) B.Kerler 2018-2021
import usb.core # pyusb import usb.core # pyusb
import usb.util import usb.util
from enum import Enum from enum import Enum

View file

@ -1,4 +1,6 @@
#!/usr/bin/env python3 #!/usr/bin/python3
# -*- coding: utf-8 -*-
# (c) B.Kerler 2018-2021
import argparse import argparse
from Library.usblib import * from Library.usblib import *

View file

@ -1,3 +1,6 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# (c) B.Kerler 2018-2021
import sys import sys
import logging import logging
import logging.config import logging.config

View file

@ -1,3 +1,6 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# (c) B.Kerler 2018-2021
import xml.etree.ElementTree as ET import xml.etree.ElementTree as ET

2
edl.py
View file

@ -1,5 +1,5 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# Qualcomm Sahara / Firehose Client (c) B.Kerler 2018-2020. # Qualcomm Sahara / Firehose Client (c) B.Kerler 2018-2021
# Licensed under MIT License # Licensed under MIT License
""" """
Usage: Usage: