Fix qfil and gpt issues

This commit is contained in:
Bjoern Kerler 2021-02-01 01:02:15 +01:00
parent 125117d876
commit 15c98ae7b5
4 changed files with 72 additions and 50 deletions

View file

@ -137,6 +137,7 @@ class firehose(metaclass=LogBase):
self.skipresponse = skipresponse
self.luns = luns
self.supported_functions = []
self.lunsizes={}
self.__logger.setLevel(loglevel)
if loglevel == logging.DEBUG:
@ -272,7 +273,7 @@ class firehose(metaclass=LogBase):
def cmd_nop(self):
data = "<?xml version=\"1.0\" ?><data><nop /></data>"
val = self.xmlsend(data)
if val[0]:
if val[0] and val[1]!={}:
self.__logger.info("Nop succeeded.")
return self.xml.getlog(val[2])
else:
@ -817,7 +818,7 @@ class firehose(metaclass=LogBase):
if self.modules.edlauth():
rsp = self.xmlsend(connectcmd)
if len(rsp) > 1:
if rsp[0]: # On Ack
if rsp[0] and rsp[1]!={}: # On Ack
self.cdc.read(self.cfg.MaxXMLSizeInBytes)
if "MemoryName" not in rsp[1]:
# print(rsp[1])
@ -900,6 +901,19 @@ class firehose(metaclass=LogBase):
self.luns = self.getluns(self.args)
return True
def getlunsize(self,lun):
if not lun in self.lunsizes:
try:
data, guid_gpt = self.get_gpt(lun, int(self.args["--gpt-num-part-entries"]),
int(self.args["--gpt-part-entry-size"]),
int(self.args["--gpt-part-entry-start-lba"]))
self.lunsizes[lun]=guid_gpt.totalsectors
except Exception as e:
self.__logger.error(e)
return -1
else:
return self.lunsizes[lun]
return guid_gpt.totalsectors
def connect(self):
v = b'-1'
@ -974,7 +988,10 @@ class firehose(metaclass=LogBase):
if storageinfo is not None:
for info in storageinfo:
if "storage_info" in info:
si = json.loads(info)["storage_info"]
try:
si = json.loads(info)["storage_info"]
except:
continue
self.__logger.info("Storage report:")
for sii in si:
self.__logger.info(f"{sii}:{si[sii]}")

View file

@ -408,15 +408,9 @@ class firehose_client(metaclass=LogBase):
start = int(options["<start_sector>"])
sectors = int(options["<sectors>"])
filename = options["<filename>"]
data = self.firehose.cmd_read_buffer(lun, start, sectors, False)
try:
with open(filename, "wb") as write_handle:
write_handle.write(data)
self.printer(f"Dumped sector {str(start)} with sector count {str(sectors)} as {filename}.")
return True
except Exception as error:
self.__logger.error(f"Error: Couldn't open {filename} for writing: %s" % str(error))
return False
if self.firehose.cmd_read(lun, start, sectors, filename,True):
self.printer(f"Dumped sector {str(start)} with sector count {str(sectors)} as {filename}.")
return True
elif cmd == "peek":
if not self.check_param(["<offset>", "<length>", "<filename>"]):
return False
@ -766,47 +760,58 @@ class firehose_client(metaclass=LogBase):
return self.firehose.modules.run(command=mcommand, args=moptions)
elif cmd == "qfil":
self.__logger.info("[qfil] raw programming...")
rawprogram = options["<rawprogram>"]
rawprogram = options["<rawprogram>"].split(",")
imagedir = options["<imagedir>"]
patch = options["<patch>"]
patch = options["<patch>"].split(",")
for xml in rawprogram:
self.__logger.info("[qfil] programming %s" % xml)
fl = open(xml, "r")
for evt, elem in ET.iterparse(fl, events=["end"]):
if elem.tag == "program":
if elem.get("filename", ""):
filename = os.path.join(imagedir, elem.get("filename"))
if not os.path.isfile(filename):
self.__logger.error("[ERROR] %s not existed!" % filename)
sys.exit(1)
partition_number = elem.get("physical_partition_number")
start_sector = elem.get("start_sector")
self.__logger.info("[qfil] programming {filename} to partition({partition})" +
"@sector({start_sector})...".format(
filename=filename, partition=partition_number, start_sector=start_sector))
self.firehose.cmd_program(partition_number, start_sector, filename)
if os.path.exists(xml):
self.__logger.info("[qfil] programming %s" % xml)
fl = open(xml, "r")
for evt, elem in ET.iterparse(fl, events=["end"]):
if elem.tag == "program":
if elem.get("filename", ""):
filename = os.path.join(imagedir, elem.get("filename"))
if not os.path.isfile(filename):
self.__logger.error("%s doesn't exist!" % filename)
continue
partition_number = int(elem.get("physical_partition_number"))
NUM_DISK_SECTORS=self.firehose.getlunsize(partition_number)
start_sector = elem.get("start_sector")
if "NUM_DISK_SECTORS" in start_sector:
start_sector=start_sector.replace("NUM_DISK_SECTORS",str(NUM_DISK_SECTORS))
if "-" in start_sector or "*" in start_sector or "/" in start_sector or "+" in start_sector:
start_sector=start_sector.replace(".","")
start_sector=eval(start_sector)
self.__logger.info(f"[qfil] programming {filename} to partition({partition_number})" +
f"@sector({start_sector})...")
self.firehose.cmd_program(int(partition_number), int(start_sector), filename)
else:
self.__logger.warning(f"File : {xml} not found.")
self.__logger.info("[qfil] raw programming ok.")
self.__logger.info("[qfil] patching...")
for xml in patch:
self.__logger.info("[qfil] patching with %s" % xml)
fl = open(xml, "r")
for evt, elem in ET.iterparse(fl, events=["end"]):
if elem.tag == "patch":
filename = elem.get("filename")
if filename != "DISK":
continue
start_sector = elem.get("start_sector")
size_in_bytes = elem.get("size_in_bytes")
self.__logger.info(
"[qfil] patching {filename} sector({start_sector}), size={size_in_bytes}".format(
filename=filename, start_sector=start_sector, size_in_bytes=size_in_bytes))
content = ElementTree.tostring(elem).decode("utf-8")
CMD = "<?xml version=\"1.0\" ?><data>\n<{content} /></data>".format(
content=content)
print(CMD)
self.firehose.xmlsend(CMD)
if os.path.exists(xml):
fl = open(xml, "r")
for evt, elem in ET.iterparse(fl, events=["end"]):
if elem.tag == "patch":
filename = elem.get("filename")
if filename != "DISK":
continue
start_sector = elem.get("start_sector")
size_in_bytes = elem.get("size_in_bytes")
self.__logger.info(
"[qfil] patching {filename} sector({start_sector}), size={size_in_bytes}".format(
filename=filename, start_sector=start_sector, size_in_bytes=size_in_bytes))
content = ElementTree.tostring(elem).decode("utf-8")
CMD = "<?xml version=\"1.0\" ?><data>\n<{content} /></data>".format(
content=content)
print(CMD)
self.firehose.xmlsend(CMD)
else:
self.__logger.warning(f"File : {xml} not found.")
self.__logger.info("[qfil] patching ok")
bootable = self.find_bootable_partition(rawprogram)
if bootable != -1:

View file

@ -171,7 +171,7 @@ class gpt(metaclass=LogBase):
for idx in range(0, num_part_entries):
data = gptdata[start + (idx * entrysize):start + (idx * entrysize) + entrysize]
if int(hexlify(data[0:16]), 16) == 0:
if int(hexlify(data[16:32]), 16) == 0:
break
partentry = read_object(data, self.gpt_partition)
pa = partf()
@ -191,7 +191,7 @@ class gpt(metaclass=LogBase):
pa.type = hex(type)
pa.name = partentry["name"].replace(b"\x00\x00", b"").decode('utf-16')
if pa.type == "EFI_UNUSED":
break
continue
self.partentries.append(pa)
self.totalsectors = self.header["last_usable_lba"]
return True

4
edl.py
View file

@ -16,7 +16,7 @@ Usage:
edl.py r <partitionname> <filename> [--memory=memtype] [--sectorsize==bytes] [--lun=lun] [--loader=filename] [--skipresponse] [--debugmode] [--vid=vid] [--pid=pid]
edl.py rl <directory> [--memory=memtype] [--lun=lun] [--sectorsize==bytes] [--skip=partnames] [--genxml] [--skipresponse] [--loader=filename] [--debugmode] [--vid=vid] [--pid=pid]
edl.py rf <filename> [--memory=memtype] [--lun=lun] [--sectorsize==bytes] [--loader=filename] [--debugmode] [--skipresponse] [--vid=vid] [--pid=pid]
edl.py rs <start_sector> <sectors> <filename> [--lun=lun] [--sectorsize==bytes] [--loader=filename] [--debugmode] [--skipresponse] [--vid=vid] [--pid=pid]
edl.py rs <start_sector> <sectors> <filename> [--lun=lun] [--sectorsize==bytes] [--memory=memtype] [--loader=filename] [--debugmode] [--skipresponse] [--vid=vid] [--pid=pid]
edl.py w <partitionname> <filename> [--partitionfilename=filename] [--memory=memtype] [--lun=lun] [--sectorsize==bytes] [--skipwrite] [--skipresponse] [--loader=filename] [--debugmode] [--vid=vid] [--pid=pid] [--devicemodel=value]
edl.py wl <directory> [--memory=memtype] [--lun=lun] [--sectorsize==bytes] [--skip=partnames] [--skipresponse] [--loader=filename] [--debugmode] [--vid=vid] [--pid=pid] [--devicemodel=value]
edl.py wf <filename> [--memory=memtype] [--lun=lun] [--sectorsize==bytes] [--loader=filename] [--skipresponse] [--debugmode] [--vid=vid] [--pid=pid] [--devicemodel=value]
@ -46,7 +46,7 @@ Usage:
edl.py reset [--loader=filename] [--debugmode] [--vid=vid] [--pid=pid]
edl.py nop [--loader=filename] [--debugmode] [--vid=vid] [--pid=pid]
edl.py modules <command> <options> [--memory=memtype] [--lun=lun] [--loader=filename] [--debugmode] [--skipresponse] [--vid=vid] [--pid=pid] [--devicemodel=value]
edl.py qfil <rawprogram> <patch> <imagedir>
edl.py qfil <rawprogram> <patch> <imagedir> [--loader=filename] [--memory=memtype] [--debugmode] [--skipresponse] [--vid=vid] [--pid=pid]
Description:
server [--tcpport=portnumber] # Run tcp/ip server