Fix "OSError: Unable to find libfuse" on Windows

This commit is contained in:
ColdWindScholar 2024-05-04 11:55:05 +08:00
parent 89afbbbe96
commit f8ced92bdf
4 changed files with 112 additions and 112 deletions

Binary file not shown.

Binary file not shown.

View file

@ -1,38 +1,34 @@
from fuse import FuseOSError, Operations, LoggingMixIn
from pathlib import Path
import logging
import os
from stat import S_IFDIR, S_IFLNK, S_IFREG
from time import time
import mmap
import errno
from stat import S_IFDIR, S_IFREG
from tempfile import NamedTemporaryFile
from time import time
import sys
import os
if not os.environ.get('FUSE_LIBRARY_PATH') and os.name == 'nt':
os.environ.setdefault('FUSE_LIBRARY_PATH', os.path.join(os.path.dirname(__file__), r"bin\winfsp-%s.dll" % ("x64" if sys.maxsize > 0xffffffff else "x86")))
from fuse import Operations, LoggingMixIn
class MtkDaFS(LoggingMixIn, Operations):
def __init__(self, da_handler, rw=False):
self.da_handler = da_handler
self.rw = rw
self.files = {}
self.files['/'] = dict(
self.files = {'/': dict(
st_mode=(S_IFDIR | 0o555),
st_ctime=time(),
st_mtime=time(),
st_atime=time(),
st_nlink=2)
self.files['/emmc_user.bin'] = dict(
st_nlink=2), '/emmc_user.bin': dict(
st_mode=(S_IFREG | 0o777) if self.rw else (S_IFREG | 0o555),
st_ctime=time(),
st_mtime=time(),
st_atime=time(),
st_nlink=2,
st_size = self.da_handler.mtk.daloader.daconfig.flashsize)
self.files['/partitions'] = dict(
st_size=self.da_handler.mtk.daloader.daconfig.flashsize), '/partitions': dict(
st_mode=(S_IFDIR | 0o555),
st_ctime=time(),
st_mtime=time(),
st_atime=time(),
st_nlink=2)
st_nlink=2)}
for part in self.da_handler.mtk.daloader.get_partition_data():
self.files[f'/partitions/{part.name}'] = dict(
@ -41,26 +37,27 @@ class MtkDaFS(LoggingMixIn, Operations):
st_mtime=time(),
st_atime=time(),
st_nlink=2,
st_size = part.sectors*self.da_handler.mtk.daloader.daconfig.pagesize,
offset=part.sector*self.da_handler.mtk.daloader.daconfig.pagesize)
st_size=part.sectors * self.da_handler.mtk.daloader.daconfig.pagesize,
offset=part.sector * self.da_handler.mtk.daloader.daconfig.pagesize)
def readdir(self, path, fh):
return ['.', '..'] + [ x.removeprefix(path).removeprefix('/') for x in self.files if x.startswith(path) and x != path]
return ['.', '..'] + [x.removeprefix(path).removeprefix('/') for x in self.files if
x.startswith(path) and x != path]
def read(self, path, size, offset, fh):
if size+offset > self.files[path]['st_size']:
if size + offset > self.files[path]['st_size']:
return b''
file_offset = 0
if 'offset' in self.files[path]:
file_offset = self.files[path]['offset']
data = self.da_handler.da_ro(start=file_offset+offset, length=size, filename='', parttype=None)
data = self.da_handler.da_ro(start=file_offset + offset, length=size, filename='', parttype=None)
return bytes(data)
def write(self, path, data, offset, fh):
if not self.rw:
return 0
if offset+len(data) > self.files[path]['st_size']:
if offset + len(data) > self.files[path]['st_size']:
return b''
file_offset = 0
@ -69,7 +66,7 @@ class MtkDaFS(LoggingMixIn, Operations):
with NamedTemporaryFile('rb+', buffering=0) as f_write:
f_write.write(data)
self.da_handler.da_wo(start=file_offset+offset, length=len(data), filename=f_write.name, parttype=None)
self.da_handler.da_wo(start=file_offset + offset, length=len(data), filename=f_write.name, parttype=None)
return len(data)
def getattr(self, path, fh=None):

173
stage2
View file

@ -17,6 +17,7 @@ from mtkclient.Library.Hardware.hwcrypto import crypto_setup, hwcrypto
from mtkclient.config.mtk_config import Mtk_Config
from mtkclient.config.usb_ids import default_ids
class Stage2(metaclass=LogBase):
def __init__(self, args, loglevel=logging.INFO):
self.__logger = self.__logger
@ -40,8 +41,8 @@ class Stage2(metaclass=LogBase):
self.__logger.setLevel(logging.INFO)
self.cdc = usb_class(portconfig=default_ids, loglevel=loglevel, devclass=10)
self.usbread=self.cdc.usbread
self.usbwrite=self.cdc.usbwrite
self.usbread = self.cdc.usbread
self.usbwrite = self.cdc.usbwrite
def preinit(self):
try:
@ -160,7 +161,7 @@ class Stage2(metaclass=LogBase):
self.usbwrite(pack(">I", sectors))
if display:
pg.show_progress(prefix="Progress:",pos=0,total=sectors)
pg.show_progress(prefix="Progress:", pos=0, total=sectors)
for sector in range(sectors):
tmp = self.usbread(0x200)
@ -183,7 +184,7 @@ class Stage2(metaclass=LogBase):
else:
return buffer[start % 0x200:(start % 0x200) + length]
def userdata(self, start=0, length=32*0x200, filename="data.bin"):
def userdata(self, start=0, length=32 * 0x200, filename="data.bin"):
sectors = 0
if length != 0:
sectors = (length // 0x200) + (1 if length % 0x200 else 0)
@ -191,7 +192,6 @@ class Stage2(metaclass=LogBase):
if self.cdc.connected:
self.readflash(type=0, start=start, length=length, display=True, filename=filename)
def preloader(self, start, length, filename):
sectors = 0
if start != 0:
@ -318,8 +318,8 @@ class Stage2(metaclass=LogBase):
start = 0
else:
start = (start // 0x100)
if start>0xFFFF:
start=0xFFFF
if start > 0xFFFF:
start = 0xFFFF
if length == 0:
sectors = 16 * 1024 * 1024 // 0x100
else:
@ -339,8 +339,8 @@ class Stage2(metaclass=LogBase):
bytestoread = sectors * 0x100
count = sectors
pg = progress(pagesize=0x200)
if sectors>0xFFFF:
count=0xFFFF
if sectors > 0xFFFF:
count = 0xFFFF
with open(filename, "wb") as wf:
self.usbwrite(pack(">I", 0xf00dd00d))
self.usbwrite(pack(">I", 0x2000))
@ -353,28 +353,28 @@ class Stage2(metaclass=LogBase):
if len(tmp) != 0x100:
self.error("Error on getting data")
return
pg.show_progress(prefix="Progress:",pos=sector,total=sectors)
pg.show_progress(prefix="Progress:", pos=sector, total=sectors)
bytesread += 0x100
size = min(bytestoread, len(tmp))
wf.write(tmp[:size])
bytestoread -= size
while bytestoread>0:
while bytestoread > 0:
self.usbwrite(pack(">I", 0xf00dd00d))
self.usbwrite(pack(">I", 0x2000))
self.usbwrite(pack(">H", sector+1))
self.usbwrite(pack(">H", sector + 1))
self.usbwrite(pack(">H", 1))
tmp = self.usbread(0x100)
size = min(bytestoread, len(tmp))
wf.write(tmp[:size])
bytestoread -= size
pg.show_progress(prefix="Progress:", pos=sector, total=sectors)
sector+=1
sector += 1
pg.show_progress(prefix="Progress:", pos=sectors, total=sectors)
print("Done")
def keys(self, data=b"", otp=None, mode="dxcc"):
# self.hwcrypto.disable_range_blacklist("cqdma",self.cmd_C8)
keyinfo=""
keyinfo = ""
retval = {}
meid = self.config.get_meid()
socid = self.config.get_socid()
@ -401,31 +401,32 @@ class Stage2(metaclass=LogBase):
retval["socid"] = hexlify(socid).decode('utf-8')
except Exception as err:
pass
if self.setup.dxcc_base is not None and mode not in ["sej_aes_decrypt","sej_aes_encrypt","sej_sst_decrypt","sej_sst_encrypt","dxcc_sha256"]:
rpmbkey = self.hwcrypto.aes_hwcrypt(btype="dxcc",mode="rpmb")
if self.setup.dxcc_base is not None and mode not in ["sej_aes_decrypt", "sej_aes_encrypt", "sej_sst_decrypt",
"sej_sst_encrypt", "dxcc_sha256"]:
rpmbkey = self.hwcrypto.aes_hwcrypt(btype="dxcc", mode="rpmb")
rpmb2key = self.hwcrypto.aes_hwcrypt(btype="dxcc", mode="rpmb2")
fdekey = self.hwcrypto.aes_hwcrypt(btype="dxcc",mode="fde")
ikey = self.hwcrypto.aes_hwcrypt(btype="dxcc",mode="itrustee")
platkey, provkey = self.hwcrypto.aes_hwcrypt(btype="dxcc",mode="prov")
keyinfo+="\nKeys :\n-----------------------------------------\n"
keyinfo+="RPMB: " + hexlify(rpmbkey).decode('utf-8')+"\n"
keyinfo+="RPMB2: " + hexlify(rpmb2key).decode('utf-8') + "\n"
keyinfo+="FDE : " + hexlify(fdekey).decode('utf-8')+"\n"
keyinfo+="iTrustee: " + hexlify(ikey).decode('utf-8')+"\n"
keyinfo+="Platform: " + hexlify(platkey).decode('utf-8')+"\n"
keyinfo+="Provisioning: " + hexlify(provkey).decode('utf-8')+"\n"
keyinfo+="\n"
fdekey = self.hwcrypto.aes_hwcrypt(btype="dxcc", mode="fde")
ikey = self.hwcrypto.aes_hwcrypt(btype="dxcc", mode="itrustee")
platkey, provkey = self.hwcrypto.aes_hwcrypt(btype="dxcc", mode="prov")
keyinfo += "\nKeys :\n-----------------------------------------\n"
keyinfo += "RPMB: " + hexlify(rpmbkey).decode('utf-8') + "\n"
keyinfo += "RPMB2: " + hexlify(rpmb2key).decode('utf-8') + "\n"
keyinfo += "FDE : " + hexlify(fdekey).decode('utf-8') + "\n"
keyinfo += "iTrustee: " + hexlify(ikey).decode('utf-8') + "\n"
keyinfo += "Platform: " + hexlify(platkey).decode('utf-8') + "\n"
keyinfo += "Provisioning: " + hexlify(provkey).decode('utf-8') + "\n"
keyinfo += "\n"
if rpmbkey is not None:
self.info("RPMB : " + hexlify(rpmbkey).decode('utf-8'))
self.config.hwparam.writesetting("rpmbkey",hexlify(rpmbkey).decode('utf-8'))
self.config.hwparam.writesetting("rpmbkey", hexlify(rpmbkey).decode('utf-8'))
retval["rpmbkey"] = hexlify(rpmbkey).decode('utf-8')
if rpmb2key is not None:
self.info("RPMB2 : " + hexlify(rpmb2key).decode('utf-8'))
self.config.hwparam.writesetting("rpmb2key",hexlify(rpmb2key).decode('utf-8'))
self.config.hwparam.writesetting("rpmb2key", hexlify(rpmb2key).decode('utf-8'))
retval["rpmb2key"] = hexlify(rpmb2key).decode('utf-8')
if fdekey is not None:
self.info("FDE : " + hexlify(fdekey).decode('utf-8'))
self.config.hwparam.writesetting("fdekey",hexlify(fdekey).decode('utf-8'))
self.config.hwparam.writesetting("fdekey", hexlify(fdekey).decode('utf-8'))
retval["fdekey"] = hexlify(fdekey).decode('utf-8')
if ikey is not None:
self.info("iTrustee : " + hexlify(ikey).decode('utf-8'))
@ -437,8 +438,9 @@ class Stage2(metaclass=LogBase):
self.config.hwparam.writesetting("provkey", hexlify(provkey).decode('utf-8'))
retval["provkey"] = hexlify(provkey).decode('utf-8')
return retval, keyinfo
elif self.setup.sej_base is not None and mode not in ["sej_aes_decrypt","sej_aes_encrypt","sej_sst_decrypt","sej_sst_encrypt","dxcc_sha256"]:
retval={}
elif self.setup.sej_base is not None and mode not in ["sej_aes_decrypt", "sej_aes_encrypt", "sej_sst_decrypt",
"sej_sst_encrypt", "dxcc_sha256"]:
retval = {}
rpmbkey = self.hwcrypto.aes_hwcrypt(mode="rpmb", data=meid, otp=otp, btype="sej")
if rpmbkey:
self.info("RPMB : " + hexlify(rpmbkey).decode('utf-8'))
@ -456,30 +458,30 @@ class Stage2(metaclass=LogBase):
self.config.hwparam.writesetting("mtee3", hexlify(mtee3).decode('utf-8'))
retval["mtee3"] = hexlify(mtee3).decode('utf-8')
keyinfo+="\nKeys :\n-----------------------------------------\n"
keyinfo+="RPMB: " + hexlify(rpmbkey).decode('utf-8')
keyinfo+="\n"
keyinfo += "\nKeys :\n-----------------------------------------\n"
keyinfo += "RPMB: " + hexlify(rpmbkey).decode('utf-8')
keyinfo += "\n"
keyinfo += "MTEE: " + hexlify(mtee).decode('utf-8')
keyinfo += "\n"
retval["rpmbkey"] = hexlify(rpmbkey).decode('utf-8')
return retval, keyinfo
if mode == "sej_aes_decrypt":
dec_data = self.hwcrypto.aes_hwcrypt(mode="cbc", data=data, btype="sej", encrypt=False, otp=otp)
keyinfo+="\n"
keyinfo+="Data: " + hexlify(dec_data).decode('utf-8')
keyinfo+="\n"
keyinfo += "\n"
keyinfo += "Data: " + hexlify(dec_data).decode('utf-8')
keyinfo += "\n"
return dec_data, keyinfo
elif mode == "sej_aes_encrypt":
enc_data = self.hwcrypto.aes_hwcrypt(mode="cbc", data=data, btype="sej", encrypt=True, otp=otp)
keyinfo+="\n"
keyinfo+="Data: " + hexlify(enc_data).decode('utf-8')
keyinfo+="\n"
keyinfo += "\n"
keyinfo += "Data: " + hexlify(enc_data).decode('utf-8')
keyinfo += "\n"
return enc_data, keyinfo
elif mode == "sej_sst_decrypt":
dec_data = self.hwcrypto.aes_hwcrypt(mode="sst", data=data, btype="sej", encrypt=False, otp=otp)
keyinfo+="\n"
keyinfo+="Data: " + hexlify(dec_data).decode('utf-8')
keyinfo+="\n"
keyinfo += "\n"
keyinfo += "Data: " + hexlify(dec_data).decode('utf-8')
keyinfo += "\n"
return dec_data, keyinfo
elif mode == "sej_sst_encrypt":
enc_data = self.hwcrypto.aes_hwcrypt(mode="sst", data=data, btype="sej", encrypt=True, otp=otp)
@ -489,9 +491,9 @@ class Stage2(metaclass=LogBase):
return enc_data, keyinfo
elif mode == "dxcc_sha256":
sha256val = self.hwcrypto.aes_hwcrypt(mode="sha256", data=data, btype="dxcc")
keyinfo+="\n"
keyinfo+="SHA256: " + hexlify(sha256val).decode('utf-8')
keyinfo+="\n"
keyinfo += "\n"
keyinfo += "SHA256: " + hexlify(sha256val).decode('utf-8')
keyinfo += "\n"
return sha256val, keyinfo
return None, ""
@ -501,7 +503,6 @@ class Stage2(metaclass=LogBase):
self.usbwrite(pack(">I", 0x3000))
def getint(valuestr):
if valuestr == '':
return None
@ -544,71 +545,72 @@ def showcommands():
def main():
parser = argparse.ArgumentParser(description=info)
subparsers = parser.add_subparsers(dest="cmd", help='Valid commands are: rpmb, preloader, data, boot2, memread, memwrite, keys')
subparsers = parser.add_subparsers(dest="cmd",
help='Valid commands are: rpmb, preloader, data, boot2, memread, memwrite, keys')
parser_rpmb = subparsers.add_parser("rpmb", help="Dump the rpmb")
parser_rpmb.add_argument('--start', dest='start', type=str,
help='Start offset to dump')
help='Start offset to dump')
parser_rpmb.add_argument('--length', dest='length', type=str,
help='Max length to dump')
help='Max length to dump')
parser_rpmb.add_argument('--reverse', dest='reverse', action="store_true",
help='Reverse byte order (example: rpmb command)')
help='Reverse byte order (example: rpmb command)')
parser_rpmb.add_argument('--filename', dest='filename', type=str,
help='Read from / save to filename')
help='Read from / save to filename')
parser_preloader = subparsers.add_parser("preloader", help="Dump the preloader")
parser_preloader.add_argument('--start', dest='start', type=str,
help='Start offset to dump')
help='Start offset to dump')
parser_preloader.add_argument('--length', dest='length', type=str,
help='Max length to dump')
help='Max length to dump')
parser_preloader.add_argument('--filename', dest='filename', type=str,
help='Read from / save to filename')
help='Read from / save to filename')
parser_data = subparsers.add_parser("data", help="Read the mmc")
parser_data.add_argument('--start', dest='start', type=str,
help='Start offset to dump')
help='Start offset to dump')
parser_data.add_argument('--length', dest='length', type=str,
help='Max length to dump')
help='Max length to dump')
parser_data.add_argument('--filename', dest='filename', type=str,
help='Read from / save to filename')
help='Read from / save to filename')
parser_boot2 = subparsers.add_parser("boot2", help="Dump boot2")
parser_boot2.add_argument('--start', dest='start', type=str,
help='Start offset to dump')
help='Start offset to dump')
parser_boot2.add_argument('--length', dest='length', type=str,
help='Max length to dump')
help='Max length to dump')
parser_boot2.add_argument('--filename', dest='filename', type=str,
help='Read from / save to filename')
help='Read from / save to filename')
parser_memread = subparsers.add_parser("memread", help="Read memory")
parser_memread.add_argument(dest='start', type=str,
help='Start offset to dump')
help='Start offset to dump')
parser_memread.add_argument(dest='length', type=str,
help='Max length to dump')
help='Max length to dump')
parser_memread.add_argument('--filename', dest='filename', type=str,
help='Save to filename')
help='Save to filename')
parser_memwrite = subparsers.add_parser("memwrite", help="Write memory")
parser_memwrite.add_argument(dest='start', type=str,
help='Start offset to dump')
help='Start offset to dump')
parser_memwrite.add_argument('data', type=str,
help='Data to write [hexstring, dword or filename]')
help='Data to write [hexstring, dword or filename]')
parser_reboot = subparsers.add_parser("reboot", help="Reboot device")
parser_seccfg = subparsers.add_parser("seccfg", help="Generate seccfg")
parser_seccfg.add_argument('flag', type=str,
help='Option for generating: unlock or lock')
help='Option for generating: unlock or lock')
parser_seccfg.add_argument('--sw', dest='sw', action="store_true",
help='Option for generating: sw or hw')
help='Option for generating: sw or hw')
parser_keys = subparsers.add_parser("keys", help="Write memory")
parser_keys.add_argument('--otp', dest='otp', type=str,
help='OTP for keys (dxcc,sej,gcpu)')
help='OTP for keys (dxcc,sej,gcpu)')
parser_keys.add_argument('--mode', dest='mode', default=None, type=str,
help='keymode (dxcc,sej,gcpu,sej_aes_decrypt,sej_aes_decrypt,sej_sst_decrypt,sej_sst_encrypt')
help='keymode (dxcc,sej,gcpu,sej_aes_decrypt,sej_aes_decrypt,sej_sst_decrypt,sej_sst_encrypt')
parser_keys.add_argument('--data', dest='data', default=None, type=str,
help='data')
help='data')
args = parser.parse_args()
cmd = args.cmd
if cmd not in cmds:
@ -673,35 +675,35 @@ def main():
exit(0)
start = getint(args.start)
if os.path.exists(args.data):
filename=args.data
data=None
filename = args.data
data = None
else:
if "0x" in args.data:
data=getint(args.data)
data = getint(args.data)
else:
data=args.data
filename=None
data = args.data
filename = None
if st2.memwrite(start, data, filename):
print(f"Successfully wrote data to {hex(start)}.")
else:
print(f"Failed to write data to {hex(start)}.")
elif cmd == "keys":
keyinfo=""
data=b""
if args.mode in ["sej_aes_decrypt","sej_aes_encrypt","sej_sst_decrypt","sej_sst_encrypt"]:
keyinfo = ""
data = b""
if args.mode in ["sej_aes_decrypt", "sej_aes_encrypt", "sej_sst_decrypt", "sej_sst_encrypt"]:
if not args.data:
print("Option --data is needed")
exit(0)
data = bytes.fromhex(args.data)
# otp_hisense=bytes.fromhex("486973656E736500000000000000000000000000000000000000000000000000")
# st2.jump(0x223449)
keys, keyinfo=st2.keys(data=data, mode=args.mode, otp=args.otp)
keys, keyinfo = st2.keys(data=data, mode=args.mode, otp=args.otp)
print(keyinfo)
print("Wrote keys to logs/hwparam.json")
elif cmd == "reboot":
st2.reboot()
elif cmd == "seccfg":
if args.flag not in ["unlock","lock"]:
if args.flag not in ["unlock", "lock"]:
print("Valid flags are: unlock, lock")
sys.exit(1)
"""
@ -720,10 +722,10 @@ def main():
SBOOT_RUNTIME_OFF = 0
SBOOT_RUNTIME_ON = 1
"""
if args.flag=="unlock":
if args.flag == "unlock":
lock_state = 3
critical_lock_state = 1
elif args.flag=="lock":
elif args.flag == "lock":
lock_state = 1
critical_lock_state = 0
with open("seccfg.bin", "wb") as wf:
@ -736,12 +738,13 @@ def main():
if args.sw:
enc_hash = st2.hwcrypto.sej.sej_sec_cfg_sw(dec_hash, True)
else:
enc_hash = st2.hwcrypto.sej.sej_sec_cfg_hw(dec_hash,True)
enc_hash = st2.hwcrypto.sej.sej_sec_cfg_hw(dec_hash, True)
data = seccfg_data + enc_hash
data += b"\x00" * (0x200 - len(data))
wf.write(data)
print("Successfully wrote seccfg to seccfg.bin. You need to write seccfg.bin to partition seccfg.")
st2.close()
if __name__ == "__main__":
main()