MT6781 fixes, read speed improvements, dxcc improvements, minor bug fixes

This commit is contained in:
Bjoern Kerler 2024-07-22 14:58:13 +02:00
parent c5bc57d2b2
commit 1ffb152766
No known key found for this signature in database
GPG key ID: A3E0FAF79F2F4578
22 changed files with 397 additions and 173 deletions

122
README.md
View file

@ -171,12 +171,17 @@ sudo reboot
### Using MTKTools via the graphical user interface: ### Using MTKTools via the graphical user interface:
For the 'basics' you can use the GUI interface. This supports dumping partitions or the full flash for now. Run the following command: For the 'basics' you can use the GUI interface. This supports dumping partitions or the full flash for now. Run the following command:
``` ```
python mtk_gui python mtk_gui.py
```
### Using stock mtk functionality without exploits :
```
python mtk.py --stock
``` ```
### Run multiple commands ### Run multiple commands
```bash ```bash
python mtk script run.example python mtk.py script run.example
``` ```
See the file "[run.example](https://github.com/bkerler/mtkclient/blob/main/run.example)" on how to structure the script file See the file "[run.example](https://github.com/bkerler/mtkclient/blob/main/run.example)" on how to structure the script file
@ -184,12 +189,12 @@ See the file "[run.example](https://github.com/bkerler/mtkclient/blob/main/run.e
1. Dump boot and vbmeta 1. Dump boot and vbmeta
``` ```
python mtk r boot,vbmeta boot.img,vbmeta.img python mtk.py r boot,vbmeta boot.img,vbmeta.img
``` ```
2. Reboot the phone 2. Reboot the phone
``` ```
python mtk reset python mtk.py reset
``` ```
3. Download patched magisk for mtk: 3. Download patched magisk for mtk:
@ -219,12 +224,12 @@ mv [displayed magisk patched boot filename here] boot.patched
8. Flash magisk-patched boot and empty vbmeta 8. Flash magisk-patched boot and empty vbmeta
``` ```
python mtk w boot,vbmeta boot.patched,vbmeta.img.empty python mtk.py w boot,vbmeta boot.patched,vbmeta.img.empty
``` ```
9. Reboot the phone 9. Reboot the phone
``` ```
python mtk reset python mtk.py reset
``` ```
10. Disconnect usb cable and enjoy your rooted phone :) 10. Disconnect usb cable and enjoy your rooted phone :)
@ -235,7 +240,7 @@ python mtk reset
Example: Example:
``` ```
python mtk payload --metamode FASTBOOT python mtk.py payload --metamode FASTBOOT
``` ```
### Read efuses ### Read efuses
@ -243,28 +248,28 @@ python mtk payload --metamode FASTBOOT
Example: Example:
``` ```
python mtk da efuse python mtk.py da efuse
``` ```
### Unlock bootloader ### Unlock bootloader
1. Erase metadata and userdata (and md_udc if existing): 1. Erase metadata and userdata (and md_udc if existing):
``` ```
python mtk e metadata,userdata,md_udc python mtk.py e metadata,userdata,md_udc
``` ```
2. Unlock bootloader: 2. Unlock bootloader:
``` ```
python mtk da seccfg unlock python mtk.py da seccfg unlock
``` ```
for relocking use: for relocking use:
``` ```
python mtk da seccfg lock python mtk.py da seccfg lock
``` ```
3. Reboot the phone: 3. Reboot the phone:
``` ```
python mtk reset python mtk.py reset
``` ```
and disconnect usb cable to let the phone reboot. and disconnect usb cable to let the phone reboot.
@ -279,57 +284,57 @@ then the device should boot within 5 seconds.
Dump boot partition to filename boot.bin via preloader Dump boot partition to filename boot.bin via preloader
``` ```
python mtk r boot boot.bin python mtk.py r boot boot.bin
``` ```
Dump boot partition to filename boot.bin via bootrom Dump boot partition to filename boot.bin via bootrom
``` ```
python mtk r boot boot.bin [--preloader=Loader/Preloader/your_device_preloader.bin] python mtk.py r boot boot.bin [--preloader=Loader/Preloader/your_device_preloader.bin]
``` ```
Dump preloader partition to filename preloader.bin via bootrom Dump preloader partition to filename preloader.bin via bootrom
``` ```
python mtk r preloader preloader.bin --parttype=boot1 [--preloader=Loader/Preloader/your_device_preloader.bin] python mtk.py r preloader preloader.bin --parttype=boot1 [--preloader=Loader/Preloader/your_device_preloader.bin]
``` ```
Read full flash to filename flash.bin (use --preloader for brom) Read full flash to filename flash.bin (use --preloader for brom)
``` ```
python mtk rf flash.bin python mtk.py rf flash.bin
``` ```
Read full flash to filename flash.bin (use --preloader for brom) for IoT devices (MT6261/MT2301): Read full flash to filename flash.bin (use --preloader for brom) for IoT devices (MT6261/MT2301):
``` ```
python mtk rf flash.bin --iot python mtk.py rf flash.bin --iot
``` ```
Read flash offset 0x128000 with length 0x200000 to filename flash.bin (use --preloader for brom) Read flash offset 0x128000 with length 0x200000 to filename flash.bin (use --preloader for brom)
``` ```
python mtk ro 0x128000 0x200000 flash.bin python mtk.py ro 0x128000 0x200000 flash.bin
``` ```
Dump all partitions to directory "out". (use --preloader for brom) Dump all partitions to directory "out". (use --preloader for brom)
``` ```
python mtk rl out python mtk.py rl out
``` ```
Show gpt (use --preloader for brom) Show gpt (use --preloader for brom)
``` ```
python mtk printgpt python mtk.py printgpt
``` ```
Mount the flash as a filesystem Mount the flash as a filesystem
``` ```
python mtk fs /mnt/mtk python mtk.py fs /mnt/mtk
``` ```
### Write flash ### Write flash
@ -338,83 +343,83 @@ python mtk fs /mnt/mtk
Write filename boot.bin to boot partition Write filename boot.bin to boot partition
``` ```
python mtk w boot boot.bin python mtk.py w boot boot.bin
``` ```
Write filename flash.bin as full flash (currently only works in da mode) Write filename flash.bin as full flash (currently only works in da mode)
``` ```
python mtk wf flash.bin python mtk.py wf flash.bin
``` ```
Write all files in directory "out" to the flash partitions Write all files in directory "out" to the flash partitions
``` ```
python mtk wl out python mtk.py wl out
``` ```
write file flash.bin to flash offset 0x128000 with length 0x200000 (use --preloader for brom) write file flash.bin to flash offset 0x128000 with length 0x200000 (use --preloader for brom)
``` ```
python mtk wo 0x128000 0x200000 flash.bin python mtk.py wo 0x128000 0x200000 flash.bin
``` ```
### Erase flash ### Erase flash
Erase boot partition Erase boot partition
``` ```
python mtk e boot python mtk.py e boot
``` ```
Erase boot sectors Erase boot sectors
``` ```
python mtk es boot [sector count] python mtk.py es boot [sector count]
``` ```
### DA commands: ### DA commands:
Peek memory Peek memory
``` ```
python mtk da peek [addr in hex] [length in hex] [optional: -filename filename.bin for reading to file] python mtk.py da peek [addr in hex] [length in hex] [optional: -filename filename.bin for reading to file]
``` ```
Poke memory Poke memory
``` ```
python mtk da poke [addr in hex] [data as hexstring or -filename for reading from file] python mtk.py da poke [addr in hex] [data as hexstring or -filename for reading from file]
``` ```
Read rpmb (Only xflash for now) Read rpmb (Only xflash for now)
``` ```
python mtk da rpmb r [will read to rpmb.bin] python mtk.py da rpmb r [will read to rpmb.bin]
``` ```
Write rpmb [Currently broken, xflash only] Write rpmb [Currently broken, xflash only]
``` ```
python mtk da rpmb w filename python mtk.py da rpmb w filename
``` ```
Generate and display rpmb1-3 key Generate and display rpmb1-3 key
``` ```
python mtk da generatekeys python mtk.py da generatekeys
``` ```
Unlock / Lock bootloader Unlock / Lock bootloader
``` ```
python mtk da seccfg [lock or unlock] python mtk.py da seccfg [lock or unlock]
``` ```
--------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------------
### Bypass SLA, DAA and SBC (using generic_patcher_payload) ### Bypass SLA, DAA and SBC (using generic_patcher_payload)
`` ``
python mtk payload python mtk.py payload
`` ``
If you want to use SP Flash tool afterwards, make sure you select "UART" in the settings, not "USB". If you want to use SP Flash tool afterwards, make sure you select "UART" in the settings, not "USB".
### Dump preloader ### Dump preloader
- Device has to be in bootrom mode and preloader has to be intact on the device - Device has to be in bootrom mode and preloader has to be intact on the device
``` ```
python mtk dumppreloader [--ptype=["amonet","kamakiri","kamakiri2","hashimoto"]] [--filename=preloader.bin] python mtk.py dumppreloader [--ptype=["amonet","kamakiri","kamakiri2","hashimoto"]] [--filename=preloader.bin]
``` ```
### Dump brom ### Dump brom
@ -425,12 +430,12 @@ python mtk dumppreloader [--ptype=["amonet","kamakiri","kamakiri2","hashimoto"]]
and "hashimoto" (via cqdma) and "hashimoto" (via cqdma)
``` ```
python mtk dumpbrom --ptype=["amonet","kamakiri","hashimoto"] [--filename=brom.bin] python mtk.py dumpbrom --ptype=["amonet","kamakiri","hashimoto"] [--filename=brom.bin]
``` ```
For to dump unknown bootroms, use brute option : For to dump unknown bootroms, use brute option :
``` ```
python mtk brute python mtk.py brute
``` ```
If it's successful, please add an issue over here and append the bootrom in order to add full support. If it's successful, please add an issue over here and append the bootrom in order to add full support.
@ -439,39 +444,39 @@ If it's successful, please add an issue over here and append the bootrom in orde
### Crash da in order to enter brom ### Crash da in order to enter brom
``` ```
python mtk crash [--vid=vid] [--pid=pid] [--interface=interface] python mtk.py crash [--vid=vid] [--pid=pid] [--interface=interface]
``` ```
### Read memory using patched preloader ### Read memory using patched preloader
- Boot in Brom or crash to Brom - Boot in Brom or crash to Brom
``` ```
python mtk peek [addr] [length] --preloader=patched_preloader.bin python mtk.py peek [addr] [length] --preloader=patched_preloader.bin
``` ```
### Run custom payload ### Run custom payload
``` ```
python mtk payload --payload=payload.bin [--var1=var1] [--wdt=wdt] [--uartaddr=addr] [--da_addr=addr] [--brom_addr=addr] python mtk.py payload --payload=payload.bin [--var1=var1] [--wdt=wdt] [--uartaddr=addr] [--da_addr=addr] [--brom_addr=addr]
``` ```
--------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------------
## Stage2 usage ## Stage2 usage
### Run python mtk stage (brom) or mtk plstage (preloader) ### Run python mtk.py stage (brom) or mtk plstage (preloader)
#### Run stage2 in bootrom #### Run stage2 in bootrom
`` ``
python mtk stage python mtk.py stage
`` ``
#### Run stage2 in preloader #### Run stage2 in preloader
`` ``
python mtk plstage python mtk.py plstage
`` ``
#### Run stage2 plstage in bootrom #### Run stage2 plstage in bootrom
- Boot in Brom or crash to Brom - Boot in Brom or crash to Brom
``` ```
python mtk plstage --preloader=preloader.bin python mtk.py plstage --preloader=preloader.bin
``` ```
### Use stage2 tool ### Use stage2 tool
@ -479,42 +484,42 @@ python mtk plstage --preloader=preloader.bin
### Leave stage2 and reboot ### Leave stage2 and reboot
`` ``
python stage2 reboot python stage2.py reboot
`` ``
### Read rpmb in stage2 mode ### Read rpmb in stage2 mode
`` ``
python stage2 rpmb python stage2.py rpmb
`` ``
### Read preloader in stage2 mode ### Read preloader in stage2 mode
`` ``
python stage2 preloader python stage2.py preloader
`` ``
### Read memory as hex data in stage2 mode ### Read memory as hex data in stage2 mode
`` ``
python stage2 memread [start addr] [length] python stage2.py memread [start addr] [length]
`` ``
### Read memory to file in stage2 mode ### Read memory to file in stage2 mode
`` ``
python stage2 memread [start addr] [length] --filename filename.bin python stage2.py memread [start addr] [length] --filename filename.bin
`` ``
### Write hex data to memory in stage2 mode ### Write hex data to memory in stage2 mode
`` ``
python stage2 memwrite [start addr] --data [data as hexstring] python stage2.py memwrite [start addr] --data [data as hexstring]
`` ``
### Write memory from file in stage2 mode ### Write memory from file in stage2 mode
`` ``
python stage2 memwrite [start addr] --filename filename.bin python stage2.py memwrite [start addr] --filename filename.bin
`` ``
### Extract keys ### Extract keys
`` ``
python stage2 keys --mode [sej, dxcc] python stage2.py keys --mode [sej, dxcc]
`` ``
For dxcc, you need to use plstage instead of stage For dxcc, you need to use plstage instead of stage
@ -529,16 +534,3 @@ For dxcc, you need to use plstage instead of stage
### Chip details / configs ### Chip details / configs
- Go to config/brom_config.py - Go to config/brom_config.py
- Unknown usb vid/pids for autodetection go to config/usb_ids.py - Unknown usb vid/pids for autodetection go to config/usb_ids.py
## Learning Resources
[MTK Preloader](https://o0xmuhe.github.io/2022/03/05/MTK-Preloader-踩坑/)
[MOSEC-2022](https://o0xmuhe.github.io/2022/11/23/议题解读-MOSEC2022-MediAttack-break-the-boot-chain-of-MediaTek-SoC/)
[Dissecting MTK BROM Exploit](https://tinyhack.com/2021/01/31/dissecting-a-mediatek-bootrom-exploit/)
[Dumping Exynos BROM](https://fredericb.info/2020/06/exynos8890-bootrom-dump-dump-exynos-8890-bootrom-from-samsung-galaxy-s7.html)
[Rev Exynos BROM USB STACK ](https://fredericb.info/2020/06/reverse-engineer-usb-stack-of-exynos-bootrom.html#reverse-engineer-usb-stack-of-exynos-bootrom)
[Buffer Overflow In Huawei BROM USB STACK](https://labs.taszk.io/blog/post/bootrom_usb/)

View file

@ -92,9 +92,15 @@ def main():
with open(loader, "rb") as rf: with open(loader, "rb") as rf:
rf.seek(mbuf) rf.seek(mbuf)
data = rf.read(m_len) data = rf.read(m_len)
test = data.find(b"\x01\x01\x54\xE3\x01\x14\xA0\xE3")
if test != -1:
print("V6 Device is patched against carbonara :(")
test=data.find(b"\x08\x00\xa8\x52\xff\x02\x08\xeb") test=data.find(b"\x08\x00\xa8\x52\xff\x02\x08\xeb")
if test != -1: if test != -1:
print("Device is patched against carbonara :(") print("V6 Device is patched against carbonara :(")
test2=data.find(b"\x06\x9B\x4F\xF0\x80\x40\x02\xA9")
if test2 != -1:
print("V5 Device is patched against carbonara :(")
hashidx = data.find(int.to_bytes(0xC0070004, 4, 'little')) hashidx = data.find(int.to_bytes(0xC0070004, 4, 'little'))
if hashidx != -1: if hashidx != -1:
print("Hash check found.") print("Hash check found.")
@ -111,7 +117,11 @@ def main():
if hashidx is not None: if hashidx is not None:
print("Hash check 4 (V6) found.") print("Hash check 4 (V6) found.")
else: else:
print("HASH ERROR !!!!") hashidx = find_binary(data,b"\x01\x10\x81\xE2\x00\x00\x51\xE1")
if hashidx is not None:
print("Hash check 5 (V6) found.")
else:
print("HASH ERROR !!!!")
fname = os.path.join("loaders", fname = os.path.join("loaders",
hex(da[0]["hw_code"])[2:] + "_" + hex(startaddr)[2:] + os.path.basename( hex(da[0]["hw_code"])[2:] + "_" + hex(startaddr)[2:] + os.path.basename(

13
learning_resources.md Normal file
View file

@ -0,0 +1,13 @@
## Learning Resources
[MTK Preloader](https://o0xmuhe.github.io/2022/03/05/MTK-Preloader-踩坑/)
[MOSEC-2022](https://o0xmuhe.github.io/2022/11/23/议题解读-MOSEC2022-MediAttack-break-the-boot-chain-of-MediaTek-SoC/)
[Dissecting MTK BROM Exploit](https://tinyhack.com/2021/01/31/dissecting-a-mediatek-bootrom-exploit/)
[Dumping Exynos BROM](https://fredericb.info/2020/06/exynos8890-bootrom-dump-dump-exynos-8890-bootrom-from-samsung-galaxy-s7.html)
[Rev Exynos BROM USB STACK ](https://fredericb.info/2020/06/reverse-engineer-usb-stack-of-exynos-bootrom.html#reverse-engineer-usb-stack-of-exynos-bootrom)
[Buffer Overflow In Huawei BROM USB STACK](https://labs.taszk.io/blog/post/bootrom_usb/)

20
mtk.py
View file

@ -942,6 +942,26 @@ if __name__ == '__main__':
da_dump.add_argument('--noreconnect', action="store_true", help='Disable reconnect') da_dump.add_argument('--noreconnect', action="store_true", help='Disable reconnect')
da_rpmb.add_argument('--noreconnect', action="store_true", help='Disable reconnect') da_rpmb.add_argument('--noreconnect', action="store_true", help='Disable reconnect')
parser_script.add_argument('--stock', action="store_true", help='use stock da')
parser_printgpt.add_argument('--stock', action="store_true", help='use stock da')
parser_footer.add_argument('--stock', action="store_true", help='use stock da')
parser_e.add_argument('--stock', action="store_true", help='use stock da')
parser_es.add_argument('--stock', action="store_true", help='use stock da')
parser_wl.add_argument('--stock', action="store_true", help='use stock da')
parser_wf.add_argument('--stock', action="store_true", help='use stock da')
parser_w.add_argument('--stock', action="store_true", help='use stock da')
parser_rs.add_argument('--stock', action="store_true", help='use stock da')
parser_rf.add_argument('--stock', action="store_true", help='use stock da')
parser_rl.add_argument('--stock', action="store_true", help='use stock da')
parser_gpt.add_argument('--stock', action="store_true", help='use stock da')
parser_r.add_argument('--stock', action="store_true", help='use stock da')
da_keys.add_argument('--stock', action="store_true", help='use stock da')
da_unlock.add_argument('--stock', action="store_true", help='use stock da')
da_peek.add_argument('--stock', action="store_true", help='use stock da')
da_poke.add_argument('--stock', action="store_true", help='use stock da')
da_dump.add_argument('--stock', action="store_true", help='use stock da')
da_rpmb.add_argument('--stock', action="store_true", help='use stock da')
parser_script.add_argument('--uartloglevel', help='Set uart log level (0=Trace, 2=Normal)') parser_script.add_argument('--uartloglevel', help='Set uart log level (0=Trace, 2=Normal)')
parser_printgpt.add_argument('--uartloglevel', help='Set uart log level (0=Trace, 2=Normal)') parser_printgpt.add_argument('--uartloglevel', help='Set uart log level (0=Trace, 2=Normal)')
parser_footer.add_argument('--uartloglevel', help='Set uart log level (0=Trace, 2=Normal)') parser_footer.add_argument('--uartloglevel', help='Set uart log level (0=Trace, 2=Normal)')

View file

@ -33,6 +33,12 @@ class SlaKey:
da_sla_keys = [ da_sla_keys = [
SlaKey(vendor="Tecno/Infinix",
da_codes=[0x1208, 0x0907],
name="",
d="499890AEF768030B56AD8BF7355262A57643A8C3DF318647B72E0B72416D91D25882D0077FEBE9E8275E9F42C3F89FFF5E99E0163487461B7CC3E97C1CC4F4E2D587AB7D8DB80335AA8E3254F318AAC42136FF1043649918685A0F5CF5548318090C26D951A2B93F79FB0D9B5E1DB1C928091E1908A5DA7D3B9194A22B18B78C6EF88932EFB3D88DB8BA7117257063DE165FA8534D50C6B35F6F7C0AF5F4A96BB89756BB7AC94110E8D1B5868A5DAADF815FE8FA38960A039D681F319C7B7ED7A55649C2F2F75B26C27807AFED8BC4EF57619FF9DA152E337FE379E1B1B0020C1EF2ABDCE4A66AAF3802EE8AB105ACA6F3388EA4C20184E572778C8EB3D30B51",
n="BA4C5178EE5477B7A30FC99F9FE78E7C011E58B5DC05832591AADEE0D26A2667738FFE851782016CAE7DB8DC1958C627BC60E3A96D46E225536DCC76CBFADFE6CA2CBE4BE982AB46CBB0F1C5CB2CB13D7BBAC96E467D76AF819DCA28FB90A03AF92DDC05B34506E24F02A049D73B8143A1CF4B081372D49F4BCA21DA9EE8A19679669C71C836FC5B8180BD98256BA2AE82B702DDC61EDFD9C47871D027297D6C72A984046081953D141656F0DC4BC4E2D4006147BE096D7E855AA7057460EAC7C57660F1F28BE278C38700BAC5EBADB39F6508CF2F1E4044421664A856623FFB2002C1204CED786D576E3DDAA7C185FD698B1185A98A03B875F0A93831270557",
e="010001"),
# lk/files/pbp/keys/toolauth/da_prvk.pem # lk/files/pbp/keys/toolauth/da_prvk.pem
SlaKey(vendor="KaiOS", SlaKey(vendor="KaiOS",
da_codes=[], da_codes=[],
@ -47,14 +53,6 @@ da_sla_keys = [
d="09976537029b4362591c5b13873f223de5525d55df52dde283e52afa67f6c9dbf1408d2fb586a624efc93426f5f3be981f80e861ddd975a1e5e662db84f5164804a3ae717605d7f15866df9ed1497c38fdd6197243163ef22f958d7b822c57317203e9a1e7d18dad01f15054facdbddb9261a1272638da661fe4f9f0714ecf00e6541cc435afb1fd75a27d34b17ad400e9474ba850dafce266799caff32a058ff71e4c2daacaf8ba709e9ca4dc87584a7ffe8aa9a0a160ed069c3970b7dae3987ded71bd0bc824356987bd74363d46682c71913c3edbdb2a911f701f23aee3f8dd98180b5a138fd5ad74743682d2d2d1bb3d92786710248f316dd8391178ea81", d="09976537029b4362591c5b13873f223de5525d55df52dde283e52afa67f6c9dbf1408d2fb586a624efc93426f5f3be981f80e861ddd975a1e5e662db84f5164804a3ae717605d7f15866df9ed1497c38fdd6197243163ef22f958d7b822c57317203e9a1e7d18dad01f15054facdbddb9261a1272638da661fe4f9f0714ecf00e6541cc435afb1fd75a27d34b17ad400e9474ba850dafce266799caff32a058ff71e4c2daacaf8ba709e9ca4dc87584a7ffe8aa9a0a160ed069c3970b7dae3987ded71bd0bc824356987bd74363d46682c71913c3edbdb2a911f701f23aee3f8dd98180b5a138fd5ad74743682d2d2d1bb3d92786710248f316dd8391178ea81",
n="D16403466C530EF9BB53C1E8A96A61A4E332E17DC0F55BB46D207AC305BAE9354EAAC2CB3077B33740D275036B822DB268200DE17DA3DB7266B27686B8970B85737050F084F8D576904E74CD6C53B31F0BB0CD60686BF67C60DA0EC20F563EEA715CEBDBF76D1C5C10E982AB2955D833DE553C9CDAFD7EA2388C02823CFE7DD9AC83FA2A8EB0685ABDAB56A92DF1A7805E8AC0BD10C0F3DCB1770A9E6BBC3418C5F84A48B7CB2316B2C8F64972F391B116A58C9395A9CE9E743569A367086D7771D39FEC8EBBBA3DD2B519785A76A9F589D36D637AF884543FD65BAC75BE823C0C50AA16D58187B97223625C54C66B5A5E4DBAEAB7BE89A4E340A2E241B09B2F", n="D16403466C530EF9BB53C1E8A96A61A4E332E17DC0F55BB46D207AC305BAE9354EAAC2CB3077B33740D275036B822DB268200DE17DA3DB7266B27686B8970B85737050F084F8D576904E74CD6C53B31F0BB0CD60686BF67C60DA0EC20F563EEA715CEBDBF76D1C5C10E982AB2955D833DE553C9CDAFD7EA2388C02823CFE7DD9AC83FA2A8EB0685ABDAB56A92DF1A7805E8AC0BD10C0F3DCB1770A9E6BBC3418C5F84A48B7CB2316B2C8F64972F391B116A58C9395A9CE9E743569A367086D7771D39FEC8EBBBA3DD2B519785A76A9F589D36D637AF884543FD65BAC75BE823C0C50AA16D58187B97223625C54C66B5A5E4DBAEAB7BE89A4E340A2E241B09B2F",
e="010001"), e="010001"),
"""
SlaKey(vendor="Generic",
da_codes=[],
name="VERIFIED_BOOT_IMG_AUTH_KEY.ini",
d=0xDACD8B5FDA8A766FB7BCAA43F0B16915CE7B47714F1395FDEBCF12A2D41155B0FB587A51FECCCB4DDA1C8E5EB9EB69B86DAF2C620F6C2735215A5F22C0B6CE377AA0D07EB38ED340B5629FC2890494B078A63D6D07FDEACDBE3E7F27FDE4B143F49DB4971437E6D00D9E18B56F02DABEB0000B6E79516D0C8074B5A42569FD0D9196655D2A4030D42DFE05E9F64883E6D5F79A5BFA3E7014C9A62853DC1F21D5D626F4D0846DB16452187DD776E8886B48C210C9E208059E7CAFC997FD2CA210775C1A5D9AA261252FB975268D970C62733871D57814098A453DF92BC6CA19025CD9D430F02EE46F80DE6C63EA802BEF90673AAC4C6667F2883FB4501FA77455,
n=0x8BC9B1F7A559BCDD1717F3F7BFF8B858743892A6338D21D0BE2CE78D1BCB8F61A8D31822F694C476929897E4B10753DDBE45A2276C0EFEE594CF75E47016DA9CDB3D8EB6C3E4C5D69B8BCCE1AE443CF299C22B905300C85875E8DBB8231F4E9949D8CF9D8E0F40E93F29F843420F22CD9D080A45A4407F58F3609D03A7DB950D3D847B8B4E7D50DB6359D37A2DD730D3CE77F8FB2A33C095B0A6CF3E08593E4F70254DCDF671790F530EC07C3CD1E80199CB42F24ACA92DB5996F2119003F502E16D88EB4E4A8DEAE4036558D2A52F5C9960B0FBBC6F6FA75EFF6F5A173CE1A82539A35973D568B8918ED12F7610748BEB0239A5006257E19574C77F4133A269,
e="010001"),
""",
SlaKey(vendor="Generic", SlaKey(vendor="Generic",
da_codes=[], da_codes=[],
name="CodeSigKey", name="CodeSigKey",
@ -69,6 +67,23 @@ da_sla_keys = [
e="010001"), e="010001"),
] ]
"""
SlaKey(vendor="Generic",
da_codes=[],
name="VERIFIED_BOOT_IMG_AUTH_KEY.ini",
d=0xDACD8B5FDA8A766FB7BCAA43F0B16915CE7B47714F1395FDEBCF12A2D41155B0FB587A51FECCCB4DDA1C8E5EB9EB69B86DAF2C620F6C2735215A5F22C0B6CE377AA0D07EB38ED340B5629FC2890494B078A63D6D07FDEACDBE3E7F27FDE4B143F49DB4971437E6D00D9E18B56F02DABEB0000B6E79516D0C8074B5A42569FD0D9196655D2A4030D42DFE05E9F64883E6D5F79A5BFA3E7014C9A62853DC1F21D5D626F4D0846DB16452187DD776E8886B48C210C9E208059E7CAFC997FD2CA210775C1A5D9AA261252FB975268D970C62733871D57814098A453DF92BC6CA19025CD9D430F02EE46F80DE6C63EA802BEF90673AAC4C6667F2883FB4501FA77455,
n=0x8BC9B1F7A559BCDD1717F3F7BFF8B858743892A6338D21D0BE2CE78D1BCB8F61A8D31822F694C476929897E4B10753DDBE45A2276C0EFEE594CF75E47016DA9CDB3D8EB6C3E4C5D69B8BCCE1AE443CF299C22B905300C85875E8DBB8231F4E9949D8CF9D8E0F40E93F29F843420F22CD9D080A45A4407F58F3609D03A7DB950D3D847B8B4E7D50DB6359D37A2DD730D3CE77F8FB2A33C095B0A6CF3E08593E4F70254DCDF671790F530EC07C3CD1E80199CB42F24ACA92DB5996F2119003F502E16D88EB4E4A8DEAE4036558D2A52F5C9960B0FBBC6F6FA75EFF6F5A173CE1A82539A35973D568B8918ED12F7610748BEB0239A5006257E19574C77F4133A269,
e="010001"),
""",
"""SlaKey(vendor="Generic",
da_codes=[],
name="AuthGen_SV5.ini",
d="9a3c3d4da0650cef38ed96ef833904c9c13835199367c7b9cb03a55e7aa482016a820dfe597cd54dd1f81fd879cf070ec0c25899ac5a49822db09675a92acf6a01e0f8f538bbe66de48ca9bdca313b616470d9ec2914356d03c95f7d9236549e5a21457e4dd5fcaf09046c47ca7436f06cd7b82cb6d2a936fca88b707f6ce28f33110fea1ec363e8482419db901cb0d38e574fe0c02ad117166b40ec78f59aaa7f3eafa425010a95614e046651273a6cb1371380c4e6ce81bdb892db6ff4892cc4d8c613a8fb3fec1e72c279052896872fc23da07fba63783374f3be8e16a15e0a04a139108dd6ac239f191135f4a895e27c670de065d2248e3f9c7e920fd001",
n="008C8BF38EB2FC7FC06D567DBF70E9C34BE4281C4239ED9C58A6B598C3AE7821815D94D0B463463EEBBD69FF6AF990AE0499B6C3B3CADCD91D54499CD66E5314DB610FC0C6CAEEB1F16B6F2D451E3F2B2D515008917FCEC50ADA4CE0699BCF247D5AE2A1DDD34C48624A657CCB11CE5F8C6CE92CAB6038EFC2A89E42E029488C02C3CF21947C86D51BBA8EF540A2A7CE85356F431891261D860B518E89DD73B2D240461ACB66BCC213403145DE83F6963147E65274EA1E45DB2D231E0774ECC86E4F2328F8A90835C4FDEF1088DDBA1D8F7CA0CA732A64BDA6816162C0F88F02CF97634D85530968CBF8B7CE6A8B67D53BBFB4910843EA413135D56FB5074445",
e="010001"),
"""
brom_sla_keys = [ brom_sla_keys = [
SlaKey(vendor="Generic", SlaKey(vendor="Generic",
da_codes=[], da_codes=[],
@ -76,13 +91,6 @@ brom_sla_keys = [
d="4BD992E9A2230CD2ABEF49E4F6A7E11D7E2ADD24847787B320239829C560D5EAB94B8304317C938E9358E94758AE60D9B13F2913DD1A749A9941FACAFAB574D70EBBFBCC0133A4BE2134CBA3CE7EE18A6D3CC98D33DAB06AEEE512F405A3248EA316ABC31A2758D4C5A7B9DFCC02C2508A492EF3760A0D4CDA827CFFCADD11ED", d="4BD992E9A2230CD2ABEF49E4F6A7E11D7E2ADD24847787B320239829C560D5EAB94B8304317C938E9358E94758AE60D9B13F2913DD1A749A9941FACAFAB574D70EBBFBCC0133A4BE2134CBA3CE7EE18A6D3CC98D33DAB06AEEE512F405A3248EA316ABC31A2758D4C5A7B9DFCC02C2508A492EF3760A0D4CDA827CFFCADD11ED",
n="5FFF0B70D5DE3FC5BF41CB824B4BFD14820571CE57EDD3E7C668CC570E718DB07DCC7A6CACD0E80DADC38AA33DB37816839D97980DF3E577A6E0B1169D708071E17DD259CFE538DBDA804A2FC07D795841F2F59DEE023A9919360D0A3F4647FDF5657D9FC5944C8BFA2802336BA23AFDCDE8D546E8806EB532AA7F95A01D8DD1", n="5FFF0B70D5DE3FC5BF41CB824B4BFD14820571CE57EDD3E7C668CC570E718DB07DCC7A6CACD0E80DADC38AA33DB37816839D97980DF3E577A6E0B1169D708071E17DD259CFE538DBDA804A2FC07D795841F2F59DEE023A9919360D0A3F4647FDF5657D9FC5944C8BFA2802336BA23AFDCDE8D546E8806EB532AA7F95A01D8DD1",
e="010001"), e="010001"),
"""SlaKey(vendor="Generic",
da_codes=[],
name="AuthGen_SV5.ini",
d="9a3c3d4da0650cef38ed96ef833904c9c13835199367c7b9cb03a55e7aa482016a820dfe597cd54dd1f81fd879cf070ec0c25899ac5a49822db09675a92acf6a01e0f8f538bbe66de48ca9bdca313b616470d9ec2914356d03c95f7d9236549e5a21457e4dd5fcaf09046c47ca7436f06cd7b82cb6d2a936fca88b707f6ce28f33110fea1ec363e8482419db901cb0d38e574fe0c02ad117166b40ec78f59aaa7f3eafa425010a95614e046651273a6cb1371380c4e6ce81bdb892db6ff4892cc4d8c613a8fb3fec1e72c279052896872fc23da07fba63783374f3be8e16a15e0a04a139108dd6ac239f191135f4a895e27c670de065d2248e3f9c7e920fd001",
n="008C8BF38EB2FC7FC06D567DBF70E9C34BE4281C4239ED9C58A6B598C3AE7821815D94D0B463463EEBBD69FF6AF990AE0499B6C3B3CADCD91D54499CD66E5314DB610FC0C6CAEEB1F16B6F2D451E3F2B2D515008917FCEC50ADA4CE0699BCF247D5AE2A1DDD34C48624A657CCB11CE5F8C6CE92CAB6038EFC2A89E42E029488C02C3CF21947C86D51BBA8EF540A2A7CE85356F431891261D860B518E89DD73B2D240461ACB66BCC213403145DE83F6963147E65274EA1E45DB2D231E0774ECC86E4F2328F8A90835C4FDEF1088DDBA1D8F7CA0CA732A64BDA6816162C0F88F02CF97634D85530968CBF8B7CE6A8B67D53BBFB4910843EA413135D56FB5074445",
e="010001"),
""",
SlaKey(vendor="Generic", SlaKey(vendor="Generic",
da_codes=[], da_codes=[],
name="ROWAN / 0_2048_key.pem / CHIP_TEST_KEY.ini / lk/files/pbp/keys/toolauth/sla_prvk.pem", name="ROWAN / 0_2048_key.pem / CHIP_TEST_KEY.ini / lk/files/pbp/keys/toolauth/sla_prvk.pem",

View file

@ -81,7 +81,7 @@ class DeviceClass(metaclass=LogBase):
def usbwrite(self, data, pktsize=None): def usbwrite(self, data, pktsize=None):
raise NotImplementedError() raise NotImplementedError()
def usbread(self, resplen=None, timeout=0): def usbread(self, resplen=None, timeout=0, w_max_packet_size=None):
raise NotImplementedError() raise NotImplementedError()
def usbxmlread(self, maxtimeout=100): def usbxmlread(self, maxtimeout=100):

View file

@ -4,11 +4,14 @@
import time import time
import sys import sys
import logging import logging
from queue import Queue
from mtkclient.Library.DA.xml.xml_param import max_xml_data_length from mtkclient.Library.DA.xml.xml_param import max_xml_data_length
import serial import serial
import serial.tools.list_ports import serial.tools.list_ports
import inspect import inspect
from mtkclient.Library.Connection.devicehandler import DeviceClass from mtkclient.Library.Connection.devicehandler import DeviceClass
if sys.platform != "win32": if sys.platform != "win32":
import termios import termios
@ -28,6 +31,7 @@ class SerialClass(DeviceClass):
super().__init__(loglevel, portconfig, devclass) super().__init__(loglevel, portconfig, devclass)
self.is_serial = True self.is_serial = True
self.device = None self.device = None
self.queue = Queue()
def connect(self, ep_in=-1, ep_out=-1): def connect(self, ep_in=-1, ep_out=-1):
if self.connected: if self.connected:
@ -193,7 +197,7 @@ class SerialClass(DeviceClass):
self.device.flushOutput() self.device.flushOutput()
return self.device.flush() return self.device.flush()
def usbread(self, resplen=None, maxtimeout=0, timeout=0): def usbread(self, resplen=None, maxtimeout=0, timeout=0, w_max_packet_size=None):
# print("Reading {} bytes".format(resplen)) # print("Reading {} bytes".format(resplen))
if timeout == 0 and maxtimeout != 0: if timeout == 0 and maxtimeout != 0:
timeout = maxtimeout / 1000 # Some code calls this with ms delays, some with seconds. timeout = maxtimeout / 1000 # Some code calls this with ms delays, some with seconds.
@ -209,14 +213,26 @@ class SerialClass(DeviceClass):
return b"" return b""
self.device.timeout = timeout self.device.timeout = timeout
epr = self.device.read epr = self.device.read
q = self.queue
extend = res.extend extend = res.extend
bytestoread = resplen bytestoread = resplen
while len(res) < bytestoread: while bytestoread:
bytestoread = resplen - len(res) if len(res) < resplen else 0
if not q.empty():
data = q.get(bytestoread)
extend(data)
if bytestoread <= 0:
break
try: try:
val = epr(bytestoread) val = epr(bytestoread)
if len(val) == 0: if len(val) == 0:
break break
extend(val) if len(val) > bytestoread:
self.warning("Buffer overflow")
q.put(val[bytestoread:])
extend(val[:bytestoread])
else:
extend(val)
except Exception as e: except Exception as e:
error = str(e) error = str(e)
if "timed out" in error: if "timed out" in error:

View file

@ -4,6 +4,7 @@
import logging import logging
import os import os
import sys import sys
from queue import Queue
import usb.core # pyusb import usb.core # pyusb
import usb.util import usb.util
import time import time
@ -127,6 +128,7 @@ class UsbClass(DeviceClass):
self.EP_IN = None self.EP_IN = None
self.EP_OUT = None self.EP_OUT = None
self.is_serial = False self.is_serial = False
self.queue = Queue()
if sys.platform.startswith('freebsd') or sys.platform.startswith('linux') or sys.platform.startswith('darwin'): if sys.platform.startswith('freebsd') or sys.platform.startswith('linux') or sys.platform.startswith('darwin'):
self.backend = usb.backend.libusb1.get_backend(find_library=lambda x: "libusb-1.0.so") self.backend = usb.backend.libusb1.get_backend(find_library=lambda x: "libusb-1.0.so")
elif sys.platform.startswith('win32'): elif sys.platform.startswith('win32'):
@ -376,8 +378,8 @@ class UsbClass(DeviceClass):
self.EP_IN = usb.util.find_descriptor(itf, self.EP_IN = usb.util.find_descriptor(itf,
# match the first OUT endpoint # match the first OUT endpoint
custom_match=lambda xe: \ custom_match=lambda xe: \
usb.util.endpoint_direction(xe.bEndpointAddress) == usb.util.endpoint_direction(xe.bEndpointAddress) ==
usb.util.ENDPOINT_IN) usb.util.ENDPOINT_IN)
self.connected = True self.connected = True
return True return True
print("Couldn't find CDC interface. Aborting.") print("Couldn't find CDC interface. Aborting.")
@ -456,7 +458,7 @@ class UsbClass(DeviceClass):
def get_write_packetsize(self): def get_write_packetsize(self):
return self.EP_OUT.wMaxPacketSize return self.EP_OUT.wMaxPacketSize
def usbread(self, resplen=None, maxtimeout=100): def usbread(self, resplen=None, maxtimeout=100, w_max_packet_size=None):
if resplen is None: if resplen is None:
resplen = self.maxsize resplen = self.maxsize
if resplen <= 0: if resplen <= 0:
@ -465,19 +467,38 @@ class UsbClass(DeviceClass):
timeout = 0 timeout = 0
loglevel = self.loglevel loglevel = self.loglevel
epr = self.EP_IN.read epr = self.EP_IN.read
w_max_packet_size = self.EP_IN.wMaxPacketSize q = self.queue
b = self.buffer
if w_max_packet_size is None:
w_max_packet_size = self.EP_IN.wMaxPacketSize
extend = res.extend extend = res.extend
fast = self.fast
buffer = None buffer = None
buflen = min(resplen, w_max_packet_size) buflen = min(resplen, w_max_packet_size)
if self.fast: if self.fast:
buffer = self.buffer[:buflen] buffer = b[:buflen]
while len(res) < resplen: bytestoread = resplen
while bytestoread > 0:
bytestoread = resplen - len(res) if len(res) < resplen else 0
if not q.empty():
extend(q.get(bytestoread))
if bytestoread <= 0:
break
sz = min(buflen, bytestoread)
try: try:
if self.fast: if fast:
rlen = epr(buffer, timeout) rlen = epr(buffer, timeout)
if rlen > sz:
self.warning("Buffer overflow")
q.put(buffer[rlen:])
if self.loglevel == logging.DEBUG:
self.warning(traceback.format_exc())
self.warning(f"{rlen} vs {sz}")
self.warning(buffer[sz:].hex())
sys.stdout.flush()
extend(buffer[:rlen]) extend(buffer[:rlen])
else: else:
extend(epr(buflen)) extend(epr(sz))
except usb.core.USBError as e: except usb.core.USBError as e:
error = str(e.strerror) error = str(e.strerror)
if "timed out" in error: if "timed out" in error:
@ -489,6 +510,9 @@ class UsbClass(DeviceClass):
elif "Overflow" in error: elif "Overflow" in error:
self.error("USB Overflow") self.error("USB Overflow")
return b"" return b""
elif "No such device" in error:
self.error("Device disconnected")
sys.exit(1)
else: else:
self.info(repr(e)) self.info(repr(e))
return b"" return b""

View file

@ -256,6 +256,8 @@ class DAconfig(metaclass=LogBase):
if loader.hw_version <= self.config.hwver: if loader.hw_version <= self.config.hwver:
if loader.sw_version <= self.config.swver: if loader.sw_version <= self.config.swver:
if self.da_loader is None: if self.da_loader is None:
if loader.v6:
self.config.chipconfig.damode = DAmodes.XML
self.da_loader = loader self.da_loader = loader
self.loader = loader.loader self.loader = loader.loader
if self.da_loader is None and dacode != 0x6261: if self.da_loader is None and dacode != 0x6261:

View file

@ -809,6 +809,8 @@ class DALegacy(metaclass=LogBase):
res = self.usbread(1) res = self.usbread(1)
if res == self.Rsp.ACK: if res == self.Rsp.ACK:
speed = self.usbread(1) speed = self.usbread(1)
if speed[0] > 0:
self.mtk.port.cdc.set_fast_mode(True)
return speed return speed
return None return None
@ -1099,7 +1101,7 @@ class DALegacy(metaclass=LogBase):
size = bytestoread size = bytestoread
if bytestoread > packetsize: if bytestoread > packetsize:
size = packetsize size = packetsize
tmp = self.usbread(size) tmp = self.usbread(size, w_max_packet_size=size)
rq.put(tmp[:size]) rq.put(tmp[:size])
bytestoread -= size bytestoread -= size
curpos += size curpos += size
@ -1124,8 +1126,8 @@ class DALegacy(metaclass=LogBase):
size = bytestoread size = bytestoread
if bytestoread > packetsize: if bytestoread > packetsize:
size = packetsize size = packetsize
buffer.extend(self.usbread(size)) buffer.extend(self.usbread(size, w_max_packet_size=size))
bytestoread -= size bytestoread = len(buffer)-length
checksum = unpack(">H", self.usbread(2))[0] checksum = unpack(">H", self.usbread(2))[0]
self.debug("Checksum: %04X" % checksum) self.debug("Checksum: %04X" % checksum)
self.usbwrite(self.Rsp.ACK) self.usbwrite(self.Rsp.ACK)

View file

@ -832,22 +832,28 @@ class DAXFlash(metaclass=LogBase):
worker.start() worker.start()
while bytestoread > 0: while bytestoread > 0:
status = self.usbread(4 + 4 + 4) status = self.usbread(4 + 4 + 4)
magic, datatype, slength = unpack("<III", status) try:
if magic == 0xFEEEEEEF: magic, datatype, slength = unpack("<III", status)
resdata = self.usbread(slength) if magic == 0xFEEEEEEF:
if slength > 4: resdata = self.usbread(slength, w_max_packet_size=slength)
rq.put(resdata) if slength > 4:
stmp = pack("<III", self.Cmd.MAGIC, self.DataType.DT_PROTOCOL_FLOW, 4) rq.put(resdata)
data = pack("<I", 0) stmp = pack("<III", self.Cmd.MAGIC, self.DataType.DT_PROTOCOL_FLOW, 4)
self.usbwrite(stmp) data = pack("<I", 0)
self.usbwrite(data) self.usbwrite(stmp)
bytestoread -= len(resdata) self.usbwrite(data)
bytesread += len(resdata) bytestoread -= len(resdata)
if display: bytesread += len(resdata)
self.mtk.daloader.progress.show_progress("Read", bytesread, total, display) if display:
elif slength == 4: self.mtk.daloader.progress.show_progress("Read", bytesread, total, display)
if unpack("<I", resdata)[0] != 0: elif slength == 4:
break if unpack("<I", resdata)[0] != 0:
break
else:
print("Error: Invalid slength")
except:
print("Error: Timeout")
status = self.usbread(4 + 4 + 4) status = self.usbread(4 + 4 + 4)
magic, datatype, slength = unpack("<III", status) magic, datatype, slength = unpack("<III", status)
if magic == 0xFEEEEEEF: if magic == 0xFEEEEEEF:
@ -1054,7 +1060,7 @@ class DAXFlash(metaclass=LogBase):
da2sig_len = self.daconfig.da_loader.region[2].m_sig_len da2sig_len = self.daconfig.da_loader.region[2].m_sig_len
bootldr.seek(da2offset) bootldr.seek(da2offset)
da2 = bootldr.read(self.daconfig.da_loader.region[2].m_len) da2 = bootldr.read(self.daconfig.da_loader.region[2].m_len)
if self.patch or not self.config.target_config["sbc"]: if self.patch or not self.config.target_config["sbc"] and not self.config.stock:
da1, da2 = self.patch_da(da1, da2) da1, da2 = self.patch_da(da1, da2)
else: else:
self.patch = False self.patch = False
@ -1141,11 +1147,13 @@ class DAXFlash(metaclass=LogBase):
for key in da_sla_keys: for key in da_sla_keys:
if da2.find(bytes.fromhex(key.n)) != -1: if da2.find(bytes.fromhex(key.n)) != -1:
sla_signature = generate_da_sla_signature(data=data, key=key.key) sla_signature = generate_da_sla_signature(data=data, key=key.key)
found = not self.set_remote_sec_policy(data=sla_signature) found = self.set_remote_sec_policy(data=sla_signature)
if found:
break
if not found: if not found:
print("No valid sla key found, using dummy auth ....") print("No valid sla key found, using dummy auth ....")
sla_signature = b"\x00" * 0x100 sla_signature = b"\x00" * 0x100
found = not self.set_remote_sec_policy(data=sla_signature) found = self.set_remote_sec_policy(data=sla_signature)
if found: if found:
print("SLA Signature was accepted.") print("SLA Signature was accepted.")
return found return found
@ -1210,12 +1218,10 @@ class DAXFlash(metaclass=LogBase):
if stage == 1: if stage == 1:
self.info("Uploading stage 2...") self.info("Uploading stage 2...")
stage = stage + 1 stage = stage + 1
if not self.mtk.daloader.patch: loaded = False
#if self.carbonara is not None: if not self.mtk.daloader.patch and not self.mtk.config.stock and connagent == b"preloader":
# loaded = self.carbonara.patchda1_and_upload_da2()
#else:
loaded = self.boot_to(self.daconfig.da_loader.region[stage].m_start_addr, self.daconfig.da2) loaded = self.boot_to(self.daconfig.da_loader.region[stage].m_start_addr, self.daconfig.da2)
else: if not loaded:
loaded = self.boot_to(self.daconfig.da_loader.region[stage].m_start_addr, self.daconfig.da2) loaded = self.boot_to(self.daconfig.da_loader.region[stage].m_start_addr, self.daconfig.da2)
if loaded: if loaded:
self.info("Successfully uploaded stage 2") self.info("Successfully uploaded stage 2")
@ -1224,7 +1230,6 @@ class DAXFlash(metaclass=LogBase):
self.info("DA SLA is enabled") self.info("DA SLA is enabled")
if not self.handle_sla(self.daconfig.da2): if not self.handle_sla(self.daconfig.da2):
self.error("Can't bypass DA SLA") self.error("Can't bypass DA SLA")
sys.exit(1)
else: else:
self.info("DA SLA is disabled") self.info("DA SLA is disabled")
self.reinit(True) self.reinit(True)

View file

@ -635,12 +635,14 @@ class XmlFlashExt(metaclass=LogBase):
if rpartition.name == "seccfg": if rpartition.name == "seccfg":
partition = rpartition partition = rpartition
seccfg_data = self.xflash.readflash( seccfg_data = self.xflash.readflash(
addr=partition.sector * self.mtk.daloader.daconfig.pagesize, addr=partition.sector * guid_gpt.sectorsize,
length=partition.sectors * self.mtk.daloader.daconfig.pagesize, length=partition.sectors * guid_gpt.sectorsize,
filename="", parttype="user", display=False) filename="", parttype="user", display=False)
break break
if seccfg_data is None: if seccfg_data is None:
return False, "Couldn't detect existing seccfg partition. Aborting unlock." return False, "Couldn't detect existing seccfg partition. Aborting unlock."
if seccfg_data.find(b"\x4D\x4D\x4D\x4D") == -1:
return False, "SecCfg is empty. Aborting unlock."
if seccfg_data[:4] != pack("<I", 0x4D4D4D4D): if seccfg_data[:4] != pack("<I", 0x4D4D4D4D):
return False, "Unknown seccfg partition header. Aborting unlock." return False, "Unknown seccfg partition header. Aborting unlock."
hwc = self.cryptosetup() hwc = self.cryptosetup()
@ -766,6 +768,8 @@ class XmlFlashExt(metaclass=LogBase):
self.info(f"CID : {cid}") self.info(f"CID : {cid}")
retval["cid"] = cid retval["cid"] = cid
if self.config.chipconfig.dxcc_base is not None: if self.config.chipconfig.dxcc_base is not None:
# self.info("Generating provision key...")
# platkey, provkey = hwc.aes_hwcrypt(btype="dxcc", mode="prov")
self.info("Generating dxcc rpmbkey...") self.info("Generating dxcc rpmbkey...")
rpmbkey = hwc.aes_hwcrypt(btype="dxcc", mode="rpmb") rpmbkey = hwc.aes_hwcrypt(btype="dxcc", mode="rpmb")
self.info("Generating dxcc mirpmbkey...") self.info("Generating dxcc mirpmbkey...")

View file

@ -6,7 +6,11 @@ import os
from struct import pack, unpack from struct import pack, unpack
from queue import Queue from queue import Queue
from threading import Thread from threading import Thread
from Cryptodome.Util.number import size
from Cryptodome.Cipher import PKCS1_OAEP
from Cryptodome.Hash import SHA256
from Cryptodome.PublicKey import RSA
from Cryptodome.Util.number import size, bytes_to_long
from mtkclient.Library.DA.xml.xml_param import DataType, FtSystemOSE, LogLevel from mtkclient.Library.DA.xml.xml_param import DataType, FtSystemOSE, LogLevel
from mtkclient.Library.utils import logsetup, LogBase from mtkclient.Library.utils import logsetup, LogBase
from mtkclient.Library.error import ErrorHandler from mtkclient.Library.error import ErrorHandler
@ -228,7 +232,7 @@ class DAXML(metaclass=LogBase):
bytestoread = length bytestoread = length
while bytestoread > 0: while bytestoread > 0:
sz = min(usbepsz, bytestoread) sz = min(usbepsz, bytestoread)
data.extend(self.usbread(sz)) data.extend(self.usbread(sz,w_max_packet_size=sz))
bytestoread -= sz bytestoread -= sz
if len(data) == length: if len(data) == length:
return data return data

View file

@ -61,7 +61,7 @@ class HwCrypto(metaclass=LogBase):
return self.sej.hw_aes128_cbc_encrypt(buf=data, encrypt=True) return self.sej.hw_aes128_cbc_encrypt(buf=data, encrypt=True)
elif mode == "sst": elif mode == "sst":
self.sej.sej_base = 0xC0016000 self.sej.sej_base = 0xC0016000
data2 = self.sej.generate_hw_meta(encrypt=True, data=data) data2 = self.sej.generate_hw_meta(encrypt=True, data=data, legacy=False)
data3 = self.sej.sst_secure_algo_with_level(buf=data, encrypt=True) data3 = self.sej.sst_secure_algo_with_level(buf=data, encrypt=True)
print(data2.hex()) print(data2.hex())
print(data3.hex()) print(data3.hex())

View file

@ -12,6 +12,14 @@ from Cryptodome.Cipher import AES
from Cryptodome.Util import Counter from Cryptodome.Util import Counter
from mtkclient.Library.utils import LogBase, logsetup from mtkclient.Library.utils import LogBase, logsetup
Lcs = 0xA
KceSet = 0xB
Kce = 0xC # CodeEncryptionKey
SASI_SB_HASH_BOOT_KEY_256B = 2 # 0x10
SASI_SB_HASH_BOOT_KEY_1_128B = 1 # 0x14
SASI_SW_VERSION_COUNTER1 = 1 # 0x18
SASI_SW_VERSION_COUNTER2 = 2 # 0x19
oem_pubk = "DACD8B5FDA8A766FB7BCAA43F0B16915" + \ oem_pubk = "DACD8B5FDA8A766FB7BCAA43F0B16915" + \
"CE7B47714F1395FDEBCF12A2D41155B0" + \ "CE7B47714F1395FDEBCF12A2D41155B0" + \
"FB587A51FECCCB4DDA1C8E5EB9EB69B8" + \ "FB587A51FECCCB4DDA1C8E5EB9EB69B8" + \
@ -1114,6 +1122,18 @@ class Dxcc(metaclass=LogBase):
self.tzcc_clk(0) self.tzcc_clk(0)
return rpmbkey return rpmbkey
def sasi_bsv_socid_compute(self):
key = bytes.fromhex("49")
salt = b"\x00"*32
keylength = 0x10
self.tzcc_clk(1)
dstaddr = self.da_payload_addr - 0x300
pubkey = self.sasi_bsv_pubkey_hash_get(SASI_SB_HASH_BOOT_KEY_256B)
derivedkey = self.sbrom_key_derivation(1, key, salt, keylength, dstaddr)
hash = hashlib.sha256(pubkey+derivedkey).digest()
self.tzcc_clk(0)
return hash
def generate_rpmb_mitee(self): def generate_rpmb_mitee(self):
rpmb_ikey = bytes.fromhex("AD1AC6B4BDF4EDB7") rpmb_ikey = bytes.fromhex("AD1AC6B4BDF4EDB7")
rpmb_salt = bytes.fromhex("69EF6584") rpmb_salt = bytes.fromhex("69EF6584")
@ -1124,37 +1144,120 @@ class Dxcc(metaclass=LogBase):
self.tzcc_clk(0) self.tzcc_clk(0)
return rpmbkey return rpmbkey
def salt_func(self, value): def sasi_bsv_otp_word_read(self, otpAddress):
if otpAddress>0x24:
return None
while True: while True:
val = self.read32(self.dxcc_base + (0x2AF * 4)) & 1 val = self.read32(self.dxcc_base + (0x2AF * 4)) & 1
if val != 0: if val != 0:
break break
self.write32(self.dxcc_base + (0x2A9 * 4), (4 * value) | 0x10000) self.write32(self.dxcc_base + (0x2A9 * 4), (4 * otpAddress) | 0x10000)
while True: while True:
val = self.read32(self.dxcc_base + (0x2AD * 4)) << 31 val = self.read32(self.dxcc_base + (0x2AD * 4)) & 1
if val != 0: if val != 0:
break break
res = self.read32(self.dxcc_base + (0x2AB * 4)) res = self.read32(self.dxcc_base + (0x2AB * 4))
return res return res
def sasi_bsv_lcs_get(self):
while True:
val = self.read32(self.dxcc_base + (0x2AF * 4)) & 1
if val != 0:
break
lcs = self.read32(self.dxcc_base + (0x2B5 * 4))
if lcs != 1:
if lcs != 5:
return 0
if self.read32(self.dxcc_base + (0x2B5 * 4)) & 0x100 != 0:
return 0xB000002
otp_word = self.sasi_bsv_otp_word_read(0xA)
if self.read32(self.dxcc_base + (0x2B5 * 4)) & 0x100 != 0:
if otp_word & 0xF0000 != 0x30000:
return 0xB000080
if self.read32(self.dxcc_base + (0x2B5 * 4)) & 0x200 == 0:
return 0
return 0xB000003
def sasi_bsv_pub_key_hash_get(self, keyindex=SASI_SB_HASH_BOOT_KEY_256B):
if keyindex == SASI_SB_HASH_BOOT_KEY_256B:
start = 0x10
length = 0x8
elif keyindex == SASI_SB_HASH_BOOT_KEY_1_128B:
start = 0x14
length = 0x4
else:
return None
hashval = bytearray()
for idx in range(start,start+length,0x1):
hashval.extend(int.to_bytes(self.sasi_bsv_otp_word_read(idx),4,'little'))
return hashval
def sbrom_decrypt_kcst(self):
pdesc = hw_desc_init()
pdesc[0] = 0
pdesc[1] = 0x3FFC000
pdesc[2] = 0
pdesc[3] = 0
pdesc[4] = 0
pdesc[5] = 0
self.sasi_sb_adddescsequence(pdesc)
self.sb_hal_wait_desc_completion()
def sbrom_aeslockenginekey(self):
pdesc = hw_desc_init()
pdesc[0] = 0
pdesc[1] = 0x8000081
pdesc[2] = 0
pdesc[3] = 0
pdesc[4] = 0x4801C20
pdesc[5] = 0
self.sasi_sb_adddescsequence(pdesc)
self.sb_hal_wait_desc_completion()
def sasi_bsv_customer_key_decrypt(self):
plat_key = b"KEY PLAT"
dstaddr = self.da_payload_addr - 0x300
salt = self.sasi_bsv_pub_key_hash_get(keyindex=SASI_SB_HASH_BOOT_KEY_256B)
platkey = self.sbrom_key_derivation(HwCryptoKey.PLATFORM_KEY, plat_key, salt, 0x10, dstaddr)
while True:
val = self.read32(self.dxcc_base + 0xAF4) & 1
if val != 0:
break
self.sbrom_decrypt_kcst()
while True:
val = self.read32(self.dxcc_base + 0xAF0) & 1
if val != 0:
break
self.write32(self.dxcc_base + 0xAC0, 0)
self.write32(self.dxcc_base + 0xAC4, 0)
self.write32(self.dxcc_base + 0xAC8, 0)
self.write32(self.dxcc_base + 0xACC, 0)
self.sbrom_aeslockenginekey()
def sasi_bsv_security_disable(self):
lcs = self.sasi_bsv_lcs_get()
if lcs == 7:
return
self.write32(self.dxcc_base + 0xAC0, 0)
self.write32(self.dxcc_base + 0xAC4, 0)
self.write32(self.dxcc_base + 0xAC8, 0)
self.write32(self.dxcc_base + 0xACC, 0)
self.write32(self.dxcc_base + 0xAD8, 1)
def generate_provision_key(self): def generate_provision_key(self):
plat_key = b"KEY PLAT" plat_key = b"KEY PLAT"
prov_key = b"PROVISION KEY" prov_key = b"PROVISION KEY"
self.tzcc_clk(1) self.tzcc_clk(1)
dstaddr = self.da_payload_addr - 0x300 dstaddr = self.da_payload_addr - 0x300
lcs = self.sasi_bsv_lcs_get()
salt = hashlib.sha256(bytes.fromhex(oem_pubk)).digest() #salt = hashlib.sha256(bytes.fromhex(oem_pubk)).digest()
""" salt = self.sasi_bsv_pub_key_hash_get(keyindex=SASI_SB_HASH_BOOT_KEY_256B)
salt = bytearray(b"\x00"*0x20) platkey = self.sbrom_key_derivation(HwCryptoKey.PLATFORM_KEY, plat_key, salt, 0x10, dstaddr)
for i in range(8):
salt[i*4]=self.salt_func(0x10+i)
"""
provkey = self.sbrom_key_derivation(HwCryptoKey.PROVISIONING_KEY, plat_key, salt, 0x10, dstaddr)
while True: while True:
val = self.read32(self.dxcc_base + 0xAF4) & 1 val = self.read32(self.dxcc_base + 0xAF4) & 1
if val != 0: if val != 0:
break break
platkey = self.sbrom_key_derivation(HwCryptoKey.PLATFORM_KEY, prov_key, salt, 0x10, dstaddr) provkey = self.sbrom_key_derivation(HwCryptoKey.PROVISIONING_KEY, prov_key, salt, 0x10, dstaddr)
self.write32(self.dxcc_base + 0xAC0, 0) self.write32(self.dxcc_base + 0xAC0, 0)
self.write32(self.dxcc_base + 0xAC4, 0) self.write32(self.dxcc_base + 0xAC4, 0)
self.write32(self.dxcc_base + 0xAC8, 0) self.write32(self.dxcc_base + 0xAC8, 0)
@ -1183,7 +1286,7 @@ class Dxcc(metaclass=LogBase):
def sbrom_key_derivation(self, aeskeytype, label, salt, requestedlen, destaddr): def sbrom_key_derivation(self, aeskeytype, label, salt, requestedlen, destaddr):
result = bytearray() result = bytearray()
if aeskeytype - 1 > 4 or (1 << (aeskeytype - 1) & 0x17) == 0: if aeskeytype <= HwCryptoKey.PLATFORM_KEY or (1 << (aeskeytype - 1) & 0x17) == 0:
return 0xF2000002 return 0xF2000002
if requestedlen > 0xFF or (requestedlen << 28) & 0xFFFFFFFF: if requestedlen > 0xFF or (requestedlen << 28) & 0xFFFFFFFF:
return 0xF2000003 return 0xF2000003

View file

@ -468,7 +468,7 @@ class Sej(metaclass=LogBase):
self.reg.HACC_ACON|=acon_setting self.reg.HACC_ACON|=acon_setting
""" """
def sst_secure_algo_with_level(self, buf, encrypt=True, aes_top_legacy=True): def sst_secure_algo_with_level(self, buf, encrypt=True, aes_top_legacy=True, legacyxor=True):
seed = (CustomSeed[2] << 16) | (CustomSeed[1] << 8) | CustomSeed[0] | (CustomSeed[3] << 24) seed = (CustomSeed[2] << 16) | (CustomSeed[1] << 8) | CustomSeed[0] | (CustomSeed[3] << 24)
_iv = [seed, (~seed) & 0xFFFFFFFF, (((seed >> 16) | (seed << 16)) & 0xFFFFFFFF), _iv = [seed, (~seed) & 0xFFFFFFFF, (((seed >> 16) | (seed << 16)) & 0xFFFFFFFF),
(~((seed >> 16) | (seed << 16)) & 0xFFFFFFFF)] (~((seed >> 16) | (seed << 16)) & 0xFFFFFFFF)]
@ -502,11 +502,11 @@ class Sej(metaclass=LogBase):
self.sej_aes_hw_init(attr, key, sej_param) self.sej_aes_hw_init(attr, key, sej_param)
for pos in range(3): for pos in range(3):
src = b"".join([int.to_bytes(val, 4, 'little') for val in self.g_CFG_RANDOM_PATTERN]) src = b"".join([int.to_bytes(val, 4, 'little') for val in self.g_CFG_RANDOM_PATTERN])
buf2 = self.sej_aes_hw_internal(src, encrypt=False, attr=attr, sej_param=sej_param) buf2 = self.sej_aes_hw_internal(src, encrypt=False, attr=attr, sej_param=sej_param, legacy=legacyxor)
attr = attr & 0xFFFFFFFA | 4 attr = attr & 0xFFFFFFFA | 4
else: else:
self.sst_init(attr=attr, iv=_iv, keylen=key.key_len, mparam=sej_param, key=key.key) self.sst_init(attr=attr, iv=_iv, keylen=key.key_len, mparam=sej_param, key=key.key)
buf2 = self.sej_aes_hw_internal(buf, encrypt=encrypt, attr=attr, sej_param=sej_param, legacy=False) buf2 = self.sej_aes_hw_internal(buf, encrypt=encrypt, attr=attr, sej_param=sej_param, legacy=legacyxor)
return buf2 return buf2
def sej_terminate(self): def sej_terminate(self):
@ -557,7 +557,7 @@ class Sej(metaclass=LogBase):
if legacy: if legacy:
self.reg.HACC_UNK |= 2 self.reg.HACC_UNK |= 2
# clear HACC_ASRC/HACC_ACFG/HACC_AOUT # clear HACC_ASRC/HACC_ACFG/HACC_AOUT
self.reg.HACC_ACON2 = 0x40000000 | self.HACC_AES_CLR self.reg.HACC_ACON2 |= 0x40000000
i = 0 i = 0
while i < 20: while i < 20:
if self.reg.HACC_ACON2 > 0x80000000: if self.reg.HACC_ACON2 > 0x80000000:
@ -598,12 +598,12 @@ class Sej(metaclass=LogBase):
self.reg.HACC_ACONK = 0 self.reg.HACC_ACONK = 0
return acon_setting return acon_setting
def hw_aes128_cbc_encrypt(self, buf, encrypt=True, iv=None): def hw_aes128_cbc_encrypt(self, buf, encrypt=True, iv=None, legacy=False):
if iv is None: if iv is None:
iv = self.g_HACC_CFG_1 iv = self.g_HACC_CFG_1
self.tz_pre_init() self.tz_pre_init()
self.info("HACC init") self.info("HACC init")
self.SEJ_V3_Init(ben=encrypt, iv=iv) self.SEJ_V3_Init(ben=encrypt, iv=iv, legacy=legacy)
self.info("HACC run") self.info("HACC run")
buf2 = self.sej_run(buf) buf2 = self.sej_run(buf)
self.info("HACC terminate") self.info("HACC terminate")
@ -693,8 +693,8 @@ class Sej(metaclass=LogBase):
break break
return data return data
def sej_sec_cfg_hw(self, data, encrypt=True): def sej_sec_cfg_hw(self, data, encrypt=True, noxor=False):
if encrypt: if encrypt and not noxor:
data = self.xor_data(bytearray(data)) data = self.xor_data(bytearray(data))
self.info("HACC init") self.info("HACC init")
self.SEJ_V3_Init(ben=encrypt, iv=self.g_HACC_CFG_1, legacy=True) self.SEJ_V3_Init(ben=encrypt, iv=self.g_HACC_CFG_1, legacy=True)
@ -702,12 +702,12 @@ class Sej(metaclass=LogBase):
dec = self.sej_run(data) dec = self.sej_run(data)
self.info("HACC terminate") self.info("HACC terminate")
self.sej_terminate() self.sej_terminate()
if not encrypt: if not encrypt and not noxor:
dec = self.xor_data(dec) dec = self.xor_data(dec)
return dec return dec
def sej_sec_cfg_hw_V3(self, data, encrypt=True): def sej_sec_cfg_hw_V3(self, data, encrypt=True, legacy=False):
return self.hw_aes128_cbc_encrypt(buf=data, encrypt=encrypt) return self.hw_aes128_cbc_encrypt(buf=data, encrypt=encrypt, legacy=legacy)
# seclib_get_msg_auth_key # seclib_get_msg_auth_key
def generate_rpmb(self, meid, otp, derivedlen=32): def generate_rpmb(self, meid, otp, derivedlen=32):
@ -782,7 +782,7 @@ class Sej(metaclass=LogBase):
self.sej_terminate() self.sej_terminate()
return dec return dec
def generate_hw_meta(self, otp=None, encrypt=False, data=b""): def generate_hw_meta(self, otp=None, encrypt=False, data=b"", legacy=False):
""" """
WR8 mt65 WR8 mt65
LR9 CRC RC4 AES128-CBC SBC=OFF LR9 CRC RC4 AES128-CBC SBC=OFF
@ -800,7 +800,7 @@ class Sej(metaclass=LogBase):
iv = [seed, (~seed) & 0xFFFFFFFF, (((seed >> 16) | (seed << 16)) & 0xFFFFFFFF), iv = [seed, (~seed) & 0xFFFFFFFF, (((seed >> 16) | (seed << 16)) & 0xFFFFFFFF),
(~((seed >> 16) | (seed << 16)) & 0xFFFFFFFF)] (~((seed >> 16) | (seed << 16)) & 0xFFFFFFFF)]
self.info("HACC init") self.info("HACC init")
self.SEJ_V3_Init(ben=encrypt, iv=iv) self.SEJ_V3_Init(ben=encrypt, iv=iv, legacy=legacy)
self.info("HACC run") self.info("HACC run")
dec = self.sej_run(data) dec = self.sej_run(data)
self.info("HACC terminate") self.info("HACC terminate")

View file

@ -60,7 +60,12 @@ class SecCfgV4(metaclass=LogBase):
if _hash == dec_hash: if _hash == dec_hash:
self.hwtype = "V3" self.hwtype = "V3"
else: else:
return False dec_hash = self.hwc.sej.sej_sec_cfg_hw_V3(self.hash, False, legacy=True)
if _hash == dec_hash:
self.hwtype = "V4"
else:
return False
""" """
LKS_DEFAULT = 0x01 LKS_DEFAULT = 0x01
LKS_MP_DEFAULT = 0x02 LKS_MP_DEFAULT = 0x02
@ -91,11 +96,13 @@ class SecCfgV4(metaclass=LogBase):
dec_hash = hashlib.sha256(seccfg_data).digest() dec_hash = hashlib.sha256(seccfg_data).digest()
enc_hash = b"" enc_hash = b""
if self.hwtype == "SW": if self.hwtype == "SW":
enc_hash = self.hwc.sej.sej_sec_cfg_sw(dec_hash, True) enc_hash = self.hwc.sej.sej_sec_cfg_sw(dec_hash, encrypt=True)
elif self.hwtype == "V2": elif self.hwtype == "V2":
enc_hash = self.hwc.sej.sej_sec_cfg_hw(dec_hash, True) enc_hash = self.hwc.sej.sej_sec_cfg_hw(dec_hash, encrypt=True)
elif self.hwtype == "V3": elif self.hwtype == "V3":
enc_hash = self.hwc.sej.sej_sec_cfg_hw_V3(dec_hash, True) enc_hash = self.hwc.sej.sej_sec_cfg_hw_V3(dec_hash, encrypt=True)
elif self.hwtype == "V4":
enc_hash = self.hwc.sej.sej_sec_cfg_hw_V3(dec_hash, encrypt=True, legacy=True)
indata = seccfg_data + enc_hash indata = seccfg_data + enc_hash
while len(indata) % 0x200 != 0: while len(indata) % 0x200 != 0:
indata += b"\x00" indata += b"\x00"
@ -199,14 +206,18 @@ class SecCfgV3(metaclass=LogBase):
if self.magic != 0x4D4D4D4D or self.endflag != 0x45454545: if self.magic != 0x4D4D4D4D or self.endflag != 0x45454545:
self.error("Unknown V3 seccfg structure !") self.error("Unknown V3 seccfg structure !")
return False return False
err = self.hwc.sej.sej_sec_cfg_sw(self.data, False) err = self.hwc.sej.sej_sec_cfg_sw(self.data, encrypt=False)
if err[:4] not in [b"IIII", b"CCCC", b"\x00\x00\x00\x00"]: if err[:4] not in [b"IIII", b"CCCC", b"\x00\x00\x00\x00"]:
err = self.hwc.sej.sej_sec_cfg_hw_V3(self.data, False) err = self.hwc.sej.sej_sec_cfg_hw_V3(self.data, encrypt=False)
if err[:4] not in [b"IIII", b"CCCC", b"\x00\x00\x00\x00"]: if err[:4] not in [b"IIII", b"CCCC", b"\x00\x00\x00\x00"]:
err = self.hwc.sej.sej_sec_cfg_hw(self.data, False) err = self.hwc.sej.sej_sec_cfg_hw(self.data, encrypt=False)
if err[:4] not in [b"IIII", b"CCCC", b"\x00\x00\x00\x00"]: if err[:4] not in [b"IIII", b"CCCC", b"\x00\x00\x00\x00"]:
self.error("Unknown V3 seccfg encryption !") err = self.hwc.sej.sej_sec_cfg_hw_V3(self.data, encrypt=False, legacy=True)
return False if err[:4] not in [b"IIII", b"CCCC", b"\x00\x00\x00\x00"]:
self.error("Unknown V3 seccfg encryption !")
return False
else:
self.hwtype = "V4"
else: else:
self.hwtype = "V3" self.hwtype = "V3"
else: else:
@ -267,11 +278,13 @@ class SecCfgV3(metaclass=LogBase):
ed.write(self.seccfg_ext) ed.write(self.seccfg_ext)
indata = ed.getbuffer() indata = ed.getbuffer()
if self.hwtype == "SW": if self.hwtype == "SW":
indata = self.hwc.sej.sej_sec_cfg_sw(indata, True) indata = self.hwc.sej.sej_sec_cfg_sw(indata, encrypt=True)
elif self.hwtype == "V2": elif self.hwtype == "V2":
indata = self.hwc.sej.sej_sec_cfg_hw(indata, True) indata = self.hwc.sej.sej_sec_cfg_hw(indata, encrypt=True)
elif self.hwtype == "V3": elif self.hwtype == "V3":
indata = self.hwc.sej.sej_sec_cfg_hw_V3(indata, True) indata = self.hwc.sej.sej_sec_cfg_hw_V3(indata, encrypt=True)
elif self.hwtype == "V4":
indata = self.hwc.sej.sej_sec_cfg_hw_V3(indata, encrypt=True, legacy=True)
else: else:
return False, "Unknown error" return False, "Unknown error"
wf.write(indata) wf.write(indata)
@ -297,7 +310,7 @@ if __name__ == "__main__":
sej_base = None sej_base = None
v3 = SecCfgV3(hwc, MTK) v4 = SecCfgV4(hwc, MTK)
v3.parse(data) v4.parse(data)
ret, newdata = v3.create("lock") ret, newdata = v4.create("lock")
print(newdata.hex()) print(newdata.hex())

View file

@ -42,6 +42,13 @@ class ArgHandler(metaclass=LogBase):
config.pid = getint(args.pid) config.pid = getint(args.pid)
except AttributeError: except AttributeError:
pass pass
config.stock = True
try:
if args.stock is not None:
config.stock = args.stock
except AttributeError:
pass
config.reconnect = True config.reconnect = True
try: try:
if args.noreconnect is not None: if args.noreconnect is not None:

View file

@ -82,8 +82,8 @@ class PLTools(metaclass=LogBase):
return True return True
elif response_ack == b"\xc1\xc2\xc3\xc4": elif response_ack == b"\xc1\xc2\xc3\xc4":
if "preloader" in rf.name: if "preloader" in rf.name:
ack = self.mtk.port.usbread(4) rack = self.mtk.port.usbread(4)
if ack == b"\xC0\xC0\xC0\xC0": if rack == b"\xC0\xC0\xC0\xC0":
with open("preloader.bin", 'wb') as wf: with open("preloader.bin", 'wb') as wf:
print_progress(0, 100, prefix='Progress:', suffix='Complete', bar_length=50) print_progress(0, 100, prefix='Progress:', suffix='Complete', bar_length=50)
for pos in range(0, 0x40000, 64): for pos in range(0, 0x40000, 64):

View file

@ -1115,7 +1115,7 @@ hwconfig = {
socid_addr=0x102BA8, socid_addr=0x102BA8,
efuse_addr=0x11cb0000, efuse_addr=0x11cb0000,
damode=DAmodes.XFLASH, damode=DAmodes.XFLASH,
dacode=0x1066, dacode=0x6781,
name="MT6781", name="MT6781",
description="Helio G96", description="Helio G96",
loader="mt6781_payload.bin" loader="mt6781_payload.bin"
@ -1471,7 +1471,7 @@ hwconfig = {
damode=DAmodes.XML, damode=DAmodes.XML,
dacode=0x1172, dacode=0x1172,
name="MT6895", name="MT6895",
description="Dimensity 8100" description="Dimensity 8200"
# loader="mt6893_payload.bin" # loader="mt6893_payload.bin"
), ),
# MT6789 Oppo Realme 10 / Gigaset GX4 # MT6789 Oppo Realme 10 / Gigaset GX4

View file

@ -69,6 +69,7 @@ class MtkConfig(metaclass=LogBase):
self.sram = None self.sram = None
self.dram = None self.dram = None
self.otp = None self.otp = None
self.stock = False
if loglevel == logging.DEBUG: if loglevel == logging.DEBUG:
logfilename = os.path.join("logs", "log.txt") logfilename = os.path.join("logs", "log.txt")
fh = logging.FileHandler(logfilename) fh = logging.FileHandler(logfilename)

View file

@ -13,7 +13,7 @@ maintainers = [
] ]
readme = "README.md" readme = "README.md"
license = {file = "LICENSE"} license = {file = "LICENSE"}
version = "2.0.1" version = "2.0.2"
requires-python = ">= 3.8" requires-python = ">= 3.8"
dependencies = [ dependencies = [
"pyusb", "pyusb",