mirror of
https://github.com/bkerler/edl.git
synced 2024-11-14 19:14:58 -05:00
Fixes
This commit is contained in:
parent
963a774b74
commit
db91abc8c3
4 changed files with 202 additions and 23 deletions
|
@ -5,7 +5,7 @@ from Library.utils import *
|
|||
from Library.gpt import gpt
|
||||
try:
|
||||
from Library.oppo import oppo
|
||||
except:
|
||||
except Exception as e:
|
||||
pass
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
@ -199,6 +199,36 @@ class qualcomm_firehose:
|
|||
self.xmlsend(data, False)
|
||||
return True
|
||||
|
||||
def cmd_patch(self, physical_partition_number, start_sector, byte_offset, value, size_in_bytes, display=True):
|
||||
'''
|
||||
<patch SECTOR_SIZE_IN_BYTES="512" byte_offset="16" filename="DISK" physical_partition_number="0" size_in_bytes="4" start_sector="NUM_DISK_SECTORS-1." value="0" what="Zero Out Header CRC in Backup Header."/>
|
||||
'''
|
||||
|
||||
data = f"<?xml version=\"1.0\" ?><data>\n" + \
|
||||
f"<patch SECTOR_SIZE_IN_BYTES=\"{self.cfg.SECTOR_SIZE_IN_BYTES}\"" + \
|
||||
f" byte_offset=\"{byte_offset}\"" + \
|
||||
f" filename=\"DISK\"" + \
|
||||
f" physical_partition_number=\"{physical_partition_number}\"" + \
|
||||
f" size_in_bytes=\"{size_in_bytes}\" " + \
|
||||
f" start_sector=\"{start_sector}\" " + \
|
||||
f" value=\"{value}\" "
|
||||
data += f"/>\n</data>"
|
||||
|
||||
if self.ops is not None and "setprojmodel" in self.supported_functions:
|
||||
pk, token = self.ops.generatetoken(True)
|
||||
data += f"pk=\"{pk}\" token=\"{token}\" "
|
||||
|
||||
rsp = self.xmlsend(data)
|
||||
if rsp[0] == True:
|
||||
if display:
|
||||
logger.info(f"Patch:\n--------------------\n")
|
||||
logger.info(rsp[1])
|
||||
return True
|
||||
else:
|
||||
logger.warning("Patch command isn't supported.")
|
||||
return False
|
||||
|
||||
|
||||
def cmd_program(self, physical_partition_number, start_sector, filename, display=True):
|
||||
size = os.stat(filename).st_size
|
||||
fsize=os.stat(filename).st_size
|
||||
|
@ -272,6 +302,78 @@ class qualcomm_firehose:
|
|||
return False
|
||||
return False
|
||||
|
||||
def cmd_program_buffer(self, physical_partition_number, start_sector, wfdata, display=True):
|
||||
size=len(wfdata)
|
||||
|
||||
# Make sure we fill data up to the sector size
|
||||
num_partition_sectors = size // self.cfg.SECTOR_SIZE_IN_BYTES
|
||||
if (size % self.cfg.SECTOR_SIZE_IN_BYTES) != 0:
|
||||
num_partition_sectors += 1
|
||||
if display:
|
||||
logger.info(
|
||||
f"\nWriting to physical partition {str(physical_partition_number)}, sector {str(start_sector)}, sectors {str(num_partition_sectors)}")
|
||||
data = f"<?xml version=\"1.0\" ?><data>\n" + \
|
||||
f"<program SECTOR_SIZE_IN_BYTES=\"{self.cfg.SECTOR_SIZE_IN_BYTES}\"" + \
|
||||
f" num_partition_sectors=\"{num_partition_sectors}\"" + \
|
||||
f" physical_partition_number=\"{physical_partition_number}\"" + \
|
||||
f" start_sector=\"{start_sector}\" "
|
||||
|
||||
if self.ops is not None and "setprojmodel" in self.supported_functions:
|
||||
pk, token = self.ops.generatetoken(True)
|
||||
data += f"pk=\"{pk}\" token=\"{token}\" "
|
||||
|
||||
data += f"/>\n</data>"
|
||||
rsp = self.xmlsend(data)
|
||||
pos = 0
|
||||
prog = 0
|
||||
if display:
|
||||
print_progress(prog, 100, prefix='Progress:', suffix='Complete', bar_length=50)
|
||||
if rsp[0]:
|
||||
bytesToWrite = self.cfg.SECTOR_SIZE_IN_BYTES * num_partition_sectors
|
||||
total = self.cfg.SECTOR_SIZE_IN_BYTES * num_partition_sectors
|
||||
old = 0
|
||||
fpos=0
|
||||
fsize=len(wfdata)
|
||||
while fsize > 0:
|
||||
wlen = self.cfg.MaxPayloadSizeToTargetInBytes // self.cfg.SECTOR_SIZE_IN_BYTES * self.cfg.SECTOR_SIZE_IN_BYTES
|
||||
if fsize < wlen:
|
||||
wlen = fsize
|
||||
wdata = wfdata[fpos:fpos+wlen]
|
||||
bytesToWrite -= wlen
|
||||
fsize -= wlen
|
||||
pos += wlen
|
||||
fpos += wlen
|
||||
if (wlen % self.cfg.SECTOR_SIZE_IN_BYTES) != 0:
|
||||
filllen = (wlen // self.cfg.SECTOR_SIZE_IN_BYTES * self.cfg.SECTOR_SIZE_IN_BYTES) + self.cfg.SECTOR_SIZE_IN_BYTES
|
||||
wdata += b"\x00" * (filllen - wlen)
|
||||
wlen = len(wdata)
|
||||
self.cdc.write(wdata, wlen)
|
||||
prog = int(float(pos) / float(total) * float(100))
|
||||
if (prog > old):
|
||||
if display:
|
||||
print_progress(prog, 100, prefix='Progress:', suffix='Complete', bar_length=50)
|
||||
|
||||
if display and prog != 100:
|
||||
print_progress(100, 100, prefix='Progress:', suffix='Complete', bar_length=50)
|
||||
self.cdc.write(b'', self.cfg.MaxPayloadSizeToTargetInBytes)
|
||||
time.sleep(0.2)
|
||||
info = self.xml.getlog(self.cdc.read(self.cfg.MaxXMLSizeInBytes))
|
||||
rsp = self.xml.getresponse(self.cdc.read(self.cfg.MaxXMLSizeInBytes))
|
||||
if "value" in rsp:
|
||||
if rsp["value"] == "ACK":
|
||||
return True
|
||||
else:
|
||||
logger.error(f"Error:")
|
||||
for line in info:
|
||||
logger.error(line)
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
else:
|
||||
logger.error(f"Error:{rsp}")
|
||||
return False
|
||||
return False
|
||||
|
||||
def cmd_erase(self, physical_partition_number, start_sector, num_partition_sectors, display=True):
|
||||
if display:
|
||||
logger.info(
|
||||
|
@ -393,7 +495,7 @@ class qualcomm_firehose:
|
|||
if rsp[1]["value"] == "NAK":
|
||||
if display:
|
||||
logger.error(rsp[2].decode('utf-8'))
|
||||
return ""
|
||||
return b""
|
||||
bytesToRead = self.cfg.SECTOR_SIZE_IN_BYTES * num_partition_sectors
|
||||
total = bytesToRead
|
||||
dataread = 0
|
||||
|
@ -423,15 +525,15 @@ class qualcomm_firehose:
|
|||
logger.error(f"Error:")
|
||||
for line in info:
|
||||
logger.error(line)
|
||||
return ""
|
||||
return b""
|
||||
else:
|
||||
logger.error(f"Error:{rsp[2]}")
|
||||
return ""
|
||||
return b""
|
||||
return resData #Do not remove, needed for oppo
|
||||
|
||||
def get_gpt(self, lun, gpt_num_part_entries, gpt_part_entry_size, gpt_part_entry_start_lba):
|
||||
data = self.cmd_read_buffer(lun, 0, 2, False)
|
||||
if data == "":
|
||||
if data == b"":
|
||||
return None, None
|
||||
guid_gpt = gpt(
|
||||
num_part_entries=gpt_num_part_entries,
|
||||
|
@ -444,6 +546,8 @@ class qualcomm_firehose:
|
|||
if sectors==0:
|
||||
return None, None
|
||||
data = self.cmd_read_buffer(lun, 0, sectors, False)
|
||||
if data==b"":
|
||||
return None, None
|
||||
guid_gpt.parse(data, self.cfg.SECTOR_SIZE_IN_BYTES)
|
||||
return data, guid_gpt
|
||||
else:
|
||||
|
@ -451,7 +555,7 @@ class qualcomm_firehose:
|
|||
|
||||
def get_backup_gpt(self, lun, gpt_num_part_entries, gpt_part_entry_size, gpt_part_entry_start_lba):
|
||||
data = self.cmd_read_buffer(lun, 0, 2, False)
|
||||
if data == "":
|
||||
if data == b"":
|
||||
return None
|
||||
guid_gpt = gpt(
|
||||
num_part_entries=gpt_num_part_entries,
|
||||
|
@ -462,6 +566,8 @@ class qualcomm_firehose:
|
|||
if "backup_lba" in header:
|
||||
sectors = header["first_usable_lba"] - 1
|
||||
data = self.cmd_read_buffer(lun, header["backup_lba"], sectors, False)
|
||||
if data==b"":
|
||||
return None
|
||||
return data
|
||||
else:
|
||||
return None
|
||||
|
@ -489,6 +595,8 @@ class qualcomm_firehose:
|
|||
if info==[]:
|
||||
info=self.cmd_nop()
|
||||
supfunc = False
|
||||
self.supported_functions = ['program','write','read','patch']
|
||||
'''
|
||||
self.supported_functions = []
|
||||
for line in info:
|
||||
if "chip serial num" in line.lower():
|
||||
|
@ -505,10 +613,10 @@ class qualcomm_firehose:
|
|||
self.supported_functions.append(rs)
|
||||
if "supported functions" in line.lower():
|
||||
supfunc = True
|
||||
|
||||
'''
|
||||
try:
|
||||
self.ops = oppo(self,projid=self.oppoprjid, serials=[self.serial, self.serial])
|
||||
except:
|
||||
except Exception as e:
|
||||
self.ops = None
|
||||
data=self.cdc.read() #logbuf
|
||||
try:
|
||||
|
|
66
edl.py
66
edl.py
|
@ -43,6 +43,8 @@ Usage:
|
|||
edl.py rawxml <xmlstring> [--loader=filename] [--debugmode] [--vid=vid] [--pid=pid] [--oppo=projid]
|
||||
edl.py reset [--loader=filename] [--debugmode] [--vid=vid] [--pid=pid]
|
||||
edl.py nop [--loader=filename] [--debugmode] [--vid=vid] [--pid=pid]
|
||||
edl.py oemunlock [--memory=memtype] [--lun=lun] [--loader=filename] [--debugmode] [--vid=vid] [--pid=pid]
|
||||
edl.py ops <mode> [--memory=memtype] [--lun=lun] [--loader=filename] [--debugmode] [--vid=vid] [--pid=pid] [--oppo=projid]
|
||||
|
||||
Description:
|
||||
server [--tcpport=portnumber] # Run tcp/ip server
|
||||
|
@ -707,6 +709,8 @@ def do_firehose_server(mainargs, cdc, sahara):
|
|||
partition.sectors - (0x4000 // cfg.SECTOR_SIZE_IN_BYTES)),
|
||||
(0x4000 // cfg.SECTOR_SIZE_IN_BYTES),
|
||||
filename)
|
||||
if data==b"":
|
||||
continue
|
||||
val = struct.unpack("<I", data[:4])[0]
|
||||
if (val & 0xFFFFFFF0) == 0xD0B5B1C0:
|
||||
with open(filename, "wb") as wf:
|
||||
|
@ -1384,6 +1388,8 @@ def handle_firehose(arguments, cdc, sahara, verbose):
|
|||
partition.sector + (
|
||||
partition.sectors - (0x4000 // cfg.SECTOR_SIZE_IN_BYTES)),
|
||||
(0x4000 // cfg.SECTOR_SIZE_IN_BYTES), filename)
|
||||
if data==b"":
|
||||
continue
|
||||
val = struct.unpack("<I", data[:4])[0]
|
||||
if (val & 0xFFFFFFF0) == 0xD0B5B1C0:
|
||||
with open(filename, "wb") as wf:
|
||||
|
@ -1703,6 +1709,66 @@ def handle_firehose(arguments, cdc, sahara, verbose):
|
|||
elif arguments["server"]:
|
||||
do_firehose_server(arguments, cdc, sahara)
|
||||
exit(0)
|
||||
elif arguments["oemunlock"]:
|
||||
partition = "config"
|
||||
res=detect_partition(fh, arguments, partition)
|
||||
if res[0]==True:
|
||||
lun=res[1]
|
||||
rpartition=res[2]
|
||||
offsettopatch=0x7FFFF
|
||||
sector=rpartition.sector + (offsettopatch//cfg.SECTOR_SIZE_IN_BYTES)
|
||||
offset=offsettopatch%cfg.SECTOR_SIZE_IN_BYTES
|
||||
value=0x1
|
||||
size_in_bytes=1
|
||||
if fh.cmd_patch(lun, sector, offset, value, size_in_bytes, True):
|
||||
print(f"Patched sector {str(rpartition.sector)}, offset {str(offset)} with value {value}, size in bytes {size_in_bytes}.")
|
||||
else:
|
||||
fpartitions=res[1]
|
||||
logger.error(f"Error: Couldn't detect partition: {partition}\nAvailable partitions:")
|
||||
for lun in fpartitions:
|
||||
for rpartition in fpartitions[lun]:
|
||||
if arguments["--memory"].lower() == "emmc":
|
||||
logger.error("\t" + rpartition)
|
||||
else:
|
||||
logger.error(lun + ":\t" + rpartition)
|
||||
exit(0)
|
||||
elif arguments["ops"]:
|
||||
if fh.ops==None:
|
||||
logger.error("Feature is not supported")
|
||||
exit(0)
|
||||
partition = "param"
|
||||
mode=arguments["<mode>"]
|
||||
enable=False
|
||||
if mode=="enable":
|
||||
enable=True
|
||||
elif mode=="disable":
|
||||
enable=False
|
||||
else:
|
||||
logger.error("Unknown mode given. Available are: enable, disable.")
|
||||
exit(0)
|
||||
res=detect_partition(fh, arguments, partition)
|
||||
if res[0]==True:
|
||||
lun=res[1]
|
||||
rpartition=res[2]
|
||||
paramdata=fh.cmd_read_buffer(lun,rpartition.sector,rpartition.sectors,False)
|
||||
if paramdata==b"":
|
||||
logger.error("Error on reading param partition.")
|
||||
exit(1)
|
||||
paramdata=fh.ops.enable_ops(paramdata,enable)
|
||||
if fh.cmd_program_buffer(lun,rpartition.sector,paramdata,False):
|
||||
print("Successfully set mode")
|
||||
else:
|
||||
logger.error("Error on writing param partition")
|
||||
else:
|
||||
fpartitions=res[1]
|
||||
logger.error(f"Error: Couldn't detect partition: {partition}\nAvailable partitions:")
|
||||
for lun in fpartitions:
|
||||
for rpartition in fpartitions[lun]:
|
||||
if arguments["--memory"].lower() == "emmc":
|
||||
logger.error("\t"+rpartition)
|
||||
else:
|
||||
logger.error(lun + ":\t" + rpartition)
|
||||
exit(0)
|
||||
else:
|
||||
logger.error("Unknown/Missing command, a command is required.")
|
||||
exit(0)
|
||||
|
|
|
@ -123,11 +123,12 @@ def extract_hdr(memsection,si,mm,code_size,signature_size):
|
|||
anti_rollback_version=struct.unpack("<I", mm[md_offset:md_offset + 4])[0]
|
||||
|
||||
signatureoffset = memsection.file_start_addr + 0x30 + md_size + code_size + signature_size
|
||||
|
||||
if mm[signatureoffset] != 0x30:
|
||||
print("Error on " + si.filename + ", unknown signaturelength")
|
||||
try:
|
||||
if mm[signatureoffset] != 0x30:
|
||||
print("Error on " + si.filename + ", unknown signaturelength")
|
||||
return None
|
||||
except:
|
||||
return None
|
||||
|
||||
if len(mm) < signatureoffset + 4:
|
||||
print("Signature error on " + si.filename)
|
||||
return None
|
||||
|
@ -201,17 +202,20 @@ def extract_old_hdr(memsection,si,mm,code_size,signature_size):
|
|||
def main(argv):
|
||||
f = []
|
||||
path = ""
|
||||
if (len(argv)<2):
|
||||
print("Usage: ./fhloaderparse.py [FHLoaderDir]")
|
||||
if (len(argv)<3):
|
||||
print("Usage: ./fhloaderparse.py [FHLoaderDir] [OutputDir]")
|
||||
exit(0)
|
||||
else:
|
||||
path = argv[1]
|
||||
outputdir = argv[2]
|
||||
if not os.path.exists(outputdir):
|
||||
os.mkdir(outputdir)
|
||||
for (dirpath, dirnames, filenames) in walk(path):
|
||||
for filename in filenames:
|
||||
f.append(os.path.join(dirpath, filename))
|
||||
|
||||
hashes={}
|
||||
for (dirpath, dirnames, filenames) in walk('Loaders'):
|
||||
for (dirpath, dirnames, filenames) in walk(outputdir):
|
||||
for filename in filenames:
|
||||
fname=os.path.join(dirpath, filename)
|
||||
with open(fname,'rb') as rf:
|
||||
|
@ -221,8 +225,12 @@ def main(argv):
|
|||
hashes[sha256.digest()]=fname
|
||||
|
||||
filelist = []
|
||||
rt=open("Loaders/"+argv[1]+".log","w")
|
||||
rt=open(os.path.join(outputdir,argv[1]+".log"),"w")
|
||||
extensions=["elf","mbn","bin"]
|
||||
|
||||
if not os.path.exists(os.path.join(outputdir,"unknown")):
|
||||
os.makedirs(os.path.join(outputdir,"unknown"))
|
||||
|
||||
for filename in f:
|
||||
found=False
|
||||
for ext in extensions:
|
||||
|
@ -283,9 +291,6 @@ def main(argv):
|
|||
|
||||
|
||||
|
||||
if not os.path.exists("Loaders/unknown"):
|
||||
os.makedirs("Loaders/unknown")
|
||||
|
||||
sorted_x = sorted(filelist, key=lambda x: (x.hw_id, -x.filesize))
|
||||
class loaderinfo:
|
||||
hw_id=''
|
||||
|
@ -304,9 +309,9 @@ def main(argv):
|
|||
if (lf not in loaderlists):
|
||||
loaderlists[lf]=item.filename
|
||||
print(info)
|
||||
copyfile(item.filename,"Loaders/"+lf.hw_id+"_"+lf.pk_hash[0:16]+"_FHPRG.bin")
|
||||
copyfile(item.filename,os.path.join(outputdir,lf.hw_id+"_"+lf.pk_hash[0:16]+"_FHPRG.bin"))
|
||||
else:
|
||||
copyfile(item.filename,"Loaders/unknown/"+item.filename[item.filename.rfind("\\")+1:]+"_"+lf.pk_hash[0:16]+"_FHPRG.bin")
|
||||
copyfile(item.filename,os.path.join(outputdir,"unknown",item.filename[item.filename.rfind("\\")+1:]+"_"+lf.pk_hash[0:16]+"_FHPRG.bin"))
|
||||
else:
|
||||
print(item.filename+" does already exist. Skipping")
|
||||
try:
|
||||
|
@ -321,7 +326,7 @@ def main(argv):
|
|||
info += "\tOEMVER:" + item.oem_version + "\tQCVER:" + item.qc_version + "\tVAR:" + item.image_variant
|
||||
print(info)
|
||||
rt.write(info+"\n")
|
||||
copyfile(item.filename,"Loaders/unknown/"+item.filename[item.filename.rfind("\\")+1:])
|
||||
copyfile(item.filename,os.path.join(outputdir,"unknown",item.filename[item.filename.rfind("\\")+1:]))
|
||||
|
||||
rt.close()
|
||||
main(sys.argv)
|
|
@ -6,7 +6,7 @@ class client():
|
|||
self.commands=[]
|
||||
|
||||
def send(self):
|
||||
self.tcp = tcpclient(1340) #define Port 1340
|
||||
self.tcp = tcpclient()
|
||||
self.tcp.sendcommands(self.commands)
|
||||
|
||||
def read(self,src):
|
||||
|
|
Loading…
Reference in a new issue