Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 13 additions & 7 deletions Library/firehose.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ def cmd_setbootablestoragedrive(self,partition_number):
return False


def cmd_write(self,physical_partition_number,start_sector,filename,Display=True):
def cmd_write(self, physical_partition_number, start_sector, filename, nonStandardResponses, Display=True):
size = os.stat(filename).st_size
with open(filename,"rb") as rf:
#Make sure we fill data up to the sector size
Expand Down Expand Up @@ -178,6 +178,12 @@ def cmd_write(self,physical_partition_number,start_sector,filename,Display=True)
self.cdc.write(b'',self.cfg.MaxPayloadSizeToTargetInBytes)
time.sleep(0.2)
info = self.xml.getlog(self.cdc.read(self.cfg.MaxXMLSizeInBytes))
if not nonStandardResponses:
rsp=self.xml.getresponse(self.cdc.read(self.cfg.MaxXMLSizeInBytes))
if rsp["value"]=="ACK":
return True
else:
print(f"Error:{info[1]}")
else:
print(f"Error:{rsp}")
return False
Expand Down Expand Up @@ -228,14 +234,14 @@ def cmd_erase(self,physical_partition_number,start_sector,num_partition_sectors,
return False
return False

def cmd_read_buffer(self,physical_partition_number,start_sector,num_partition_sectors,Display=True):
def cmd_read_buffer(self, physical_partition_number, start_sector, num_partition_sectors, nonStandardResponses, Display=True):
if Display:
print(f"\nReading from physical partition {str(physical_partition_number)}, sector {str(start_sector)}, sectors {str(num_partition_sectors)}")
data=f"<?xml version=\"1.0\" ?><data><read 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}\"/>\n</data>"
rsp=self.xmlsend(data, True)
rsp=self.xmlsend(data, nonStandardResponses)
resData=bytearray()
if (rsp[0])==True:
bytesToRead=self.cfg.SECTOR_SIZE_IN_BYTES*num_partition_sectors
Expand Down Expand Up @@ -270,15 +276,15 @@ def cmd_read_buffer(self,physical_partition_number,start_sector,num_partition_se
return ""
return ""

def cmd_read(self,physical_partition_number,start_sector,num_partition_sectors,filename,Display=True):
def cmd_read(self, physical_partition_number, start_sector, num_partition_sectors, nonStandardResponses, filename, Display=True):
if Display:
print(f"\nReading from physical partition {str(physical_partition_number)}, sector {str(start_sector)}, sectors {str(num_partition_sectors)}")
with open(filename,"wb") as wf:
data=f"<?xml version=\"1.0\" ?><data><read 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}\"/>\n</data>"
rsp=self.xmlsend(data, True)
rsp=self.xmlsend(data, nonStandardResponses)
if (rsp[0])==True:
bytesToRead=self.cfg.SECTOR_SIZE_IN_BYTES*num_partition_sectors
total=bytesToRead
Expand Down Expand Up @@ -419,11 +425,11 @@ def cmd_peek(self,address,SizeInBytes,filename):
'''
data=f"<?xml version=\"1.0\" ?><data><peek address64=\"{address}\" SizeInBytes=\"{SizeInBytes}\" /></data>\n"
'''
<?xml version="1.0" encoding="UTF-8" ?><data><log value="Using address 00100000" /></data>
<?xml version="1.0" encoding="UTF-8" ?><data><log value="Using address 00100000" /></data>
<?xml version="1.0" encoding="UTF-8" ?><data><log value="0x22 0x00 0x00 0xEA 0x70 0x00 0x00 0xEA 0x74 0x00 0x00 0xEA 0x78 0x00 0
x00 0xEA 0x7C 0x00 0x00 0xEA 0x80 0x00 0x00 0xEA 0x84 0x00 0x00 0xEA 0x88 0x00 0x00 0xEA 0xFE 0xFF 0xFF 0xEA 0xFE 0xFF 0xFF 0xEA
0xFE 0xFF 0xFF 0xEA 0xFE 0xFF 0xFF 0xEA 0xFE 0xFF 0xFF 0xEA 0xFE 0xFF 0xFF 0xEA 0xFE 0xFF 0xFF 0xEA 0xFE 0xFF 0xFF 0xEA 0xFE 0x
FF 0xFF 0xEA 0xFE 0xFF 0xFF 0xEA 0xFE 0xFF 0xFF 0xEA 0xFE 0xFF 0xFF 0xEA 0xFE 0xFF 0xFF 0xEA 0xFE 0xFF 0xFF 0xEA 0xFE 0xFF 0xFF
FF 0xFF 0xEA 0xFE 0xFF 0xFF 0xEA 0xFE 0xFF 0xFF 0xEA 0xFE 0xFF 0xFF 0xEA 0xFE 0xFF 0xFF 0xEA 0xFE 0xFF 0xFF 0xEA 0xFE 0xFF 0xFF
0xEA 0xFE 0xFF 0xFF 0xEA 0xFE 0xFF 0xFF 0xEA 0xFE 0xFF " /></data>
'''
try:
Expand Down
27 changes: 14 additions & 13 deletions edl.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ def main():
parser.add_argument('-gpt-num-part-entries', metavar="<number>", type=int, help='[CMD:Firehose] Number of partitions', default=None)
parser.add_argument('-gpt-part-entry-size', metavar="<number>", type=int, help='[CMD:Firehose] Size of partition entry', default=None)
parser.add_argument('-gpt-part-entry-start-lba', metavar="<number>", type=int, help='[CMD:Firehose] Beginning of partition entries', default=None)
parser.add_argument('-non-standard-responses', help='[CMD:Firehose] Enable non standard response support (for KaiOS Nokias / Alcatel Cingular Flip)', action="store_true")


args = parser.parse_args()
Expand Down Expand Up @@ -190,11 +191,11 @@ def main():
fh = qualcomm_firehose(cdc,xml,cfg)
info=fh.connect(0)
if args.gpt!='':
fh.cmd_read(args.lun, 0, 0x4000//cfg.SECTOR_SIZE_IN_BYTES, args.gpt)
fh.cmd_read(args.lun, 0, 0x4000//cfg.SECTOR_SIZE_IN_BYTES, args.non_standard_responses, args.gpt)
print(f"Dumped GPT to {args.gpt}")
exit(0)
elif args.printgpt==True:
data = fh.cmd_read_buffer(args.lun, 0, 0x4000 // cfg.SECTOR_SIZE_IN_BYTES)
data = fh.cmd_read_buffer(args.lun, 0, 0x4000 // cfg.SECTOR_SIZE_IN_BYTES, args.non_standard_responses)
if data!='':
guid_gpt = gpt(
num_part_entries=args.gpt_num_part_entries,
Expand All @@ -212,7 +213,7 @@ def main():
exit(0)
partitionname=args.r[0]
filename=args.r[1]
data = fh.cmd_read_buffer(args.lun, 0, 0x4000 // cfg.SECTOR_SIZE_IN_BYTES,False)
data = fh.cmd_read_buffer(args.lun, 0, 0x4000 // cfg.SECTOR_SIZE_IN_BYTES, args.non_standard_responses, False)
guid_gpt = gpt(
num_part_entries=args.gpt_num_part_entries,
part_entry_size=args.gpt_part_entry_size,
Expand All @@ -222,21 +223,21 @@ def main():

for partition in guid_gpt.partentries:
if partition.name==partitionname:
data = fh.cmd_read(args.lun, partition.sector, partition.sectors, filename)
data = fh.cmd_read(args.lun, partition.sector, partition.sectors, args.non_standard_responses, filename)
print(f"Dumped sector {str(partition.sector)} with sector count {str(partition.sectors)} as {filename}.")
exit(0)
print(f"Error: Couldn't detect partition: {partitionname}")
exit(0)
elif args.rf!='':
filename=args.rf
data = fh.cmd_read_buffer(args.lun, 0, 0x4000 // cfg.SECTOR_SIZE_IN_BYTES,False)
data = fh.cmd_read_buffer(args.lun, 0, 0x4000 // cfg.SECTOR_SIZE_IN_BYTES, args.non_standard_responses, False)
guid_gpt = gpt(
num_part_entries=args.gpt_num_part_entries,
part_entry_size=args.gpt_part_entry_size,
part_entry_start_lba=args.gpt_part_entry_start_lba,
)
guid_gpt.parse(data, cfg.SECTOR_SIZE_IN_BYTES)
data = fh.cmd_read(args.lun, 0, guid_gpt.totalsectors, filename)
data = fh.cmd_read(args.lun, 0, guid_gpt.totalsectors, args.non_standard_responses, filename)
print(f"Dumped sector 0 with sector count {str(guid_gpt.totalsectors)} as {filename}.")
exit(0)
elif args.pbl!='':
Expand Down Expand Up @@ -283,7 +284,7 @@ def main():
exit(0)
elif args.footer!='':
filename=args.footer
data = fh.cmd_read_buffer(args.lun, 0, 0x4000 // cfg.SECTOR_SIZE_IN_BYTES,False)
data = fh.cmd_read_buffer(args.lun, 0, 0x4000 // cfg.SECTOR_SIZE_IN_BYTES, args.non_standard_responses, False)
guid_gpt = gpt(
num_part_entries=args.gpt_num_part_entries,
part_entry_size=args.gpt_part_entry_size,
Expand All @@ -294,7 +295,7 @@ def main():
for partition in guid_gpt.partentries:
if partition.name in pnames:
print(f"Detected partition: {partition.name}")
data = fh.cmd_read_buffer(args.lun, partition.sector+(partition.sectors-(0x4000 // cfg.SECTOR_SIZE_IN_BYTES)), (0x4000 // cfg.SECTOR_SIZE_IN_BYTES), filename)
data = fh.cmd_read_buffer(args.lun, partition.sector+(partition.sectors-(0x4000 // cfg.SECTOR_SIZE_IN_BYTES)), (0x4000 // cfg.SECTOR_SIZE_IN_BYTES), args.non_standard_responses, filename)
val=struct.unpack("<I",data[:4])[0]
if ((val&0xFFFFFFF0)==0xD0B5B1C0):
with open(filename,"wb") as wf:
Expand All @@ -310,7 +311,7 @@ def main():
start=int(args.rs[0])
sectors=int(args.rs[1])
filename=args.rs[2]
data = fh.cmd_read(args.lun, start, sectors, filename)
data = fh.cmd_read(args.lun, start, sectors, args.non_standard_responses, filename)
print(f"Dumped sector {str(start)} with sector count {str(sectors)} as {filename}.")
exit(0)
elif len(args.peek)!=0:
Expand Down Expand Up @@ -340,7 +341,7 @@ def main():
if not os.path.exists(filename):
print(f"Error: Couldn't find file: {filename}")
exit(0)
data = fh.cmd_read_buffer(args.lun, 0, 0x4000 // cfg.SECTOR_SIZE_IN_BYTES,False)
data = fh.cmd_read_buffer(args.lun, 0, 0x4000 // cfg.SECTOR_SIZE_IN_BYTES, args.non_standard_responses, False)
guid_gpt = gpt(
num_part_entries=args.gpt_num_part_entries,
part_entry_size=args.gpt_part_entry_size,
Expand All @@ -356,7 +357,7 @@ def main():
if sectors>partition.sectors:
print(f"Error: {filename} has {sectors} sectors but partition only has {partition.sectors}.")
exit(0)
data = fh.cmd_write(args.lun, partition.sector, filename)
data = fh.cmd_write(args.lun, partition.sector, filename, args.non_standard_responses)
print(f"Wrote {filename} to sector {str(partition.sector)}.")
exit(0)
print(f"Error: Couldn't detect partition: {partitionname}")
Expand All @@ -370,14 +371,14 @@ def main():
if not os.path.exists(filename):
print(f"Error: Couldn't find file: {filename}")
exit(0)
if fh.cmd_write(args.lun, start, filename)==True:
if fh.cmd_write(args.lun, start, filename, args.non_standard_responses)==True:
print(f"Wrote {filename} to sector {str(start)}.")
else:
print(f"Error on writing {filename} to sector {str(start)}")
exit(0)
elif args.e != '':
partitionname=args.e
data = fh.cmd_read_buffer(args.lun, 0, 0x4000 // cfg.SECTOR_SIZE_IN_BYTES,False)
data = fh.cmd_read_buffer(args.lun, 0, 0x4000 // cfg.SECTOR_SIZE_IN_BYTES, args.non_standard_responses, False)
guid_gpt=gpt(
num_part_entries=args.gpt_num_part_entries,
part_entry_size=args.gpt_part_entry_size,
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
capstone==4.0.2
keystone==18.0.0
pyusb==1.1.0
pyusb==1.2.1
pyserial==3.5