diff --git a/README.md b/README.md index 6a04ea8..0945b01 100644 --- a/README.md +++ b/README.md @@ -171,12 +171,17 @@ sudo reboot ### 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: ``` -python mtk_gui +python mtk_gui.py +``` + +### Using stock mtk functionality without exploits : +``` +python mtk.py --stock ``` ### Run multiple commands ```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 @@ -184,12 +189,12 @@ See the file "[run.example](https://github.com/bkerler/mtkclient/blob/main/run.e 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 ``` -python mtk reset +python mtk.py reset ``` 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 ``` -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 ``` -python mtk reset +python mtk.py reset ``` 10. Disconnect usb cable and enjoy your rooted phone :) @@ -235,7 +240,7 @@ python mtk reset Example: ``` -python mtk payload --metamode FASTBOOT +python mtk.py payload --metamode FASTBOOT ``` ### Read efuses @@ -243,28 +248,28 @@ python mtk payload --metamode FASTBOOT Example: ``` -python mtk da efuse +python mtk.py da efuse ``` ### Unlock bootloader 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: ``` -python mtk da seccfg unlock +python mtk.py da seccfg unlock ``` for relocking use: ``` -python mtk da seccfg lock +python mtk.py da seccfg lock ``` 3. Reboot the phone: ``` -python mtk reset +python mtk.py reset ``` 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 ``` -python mtk r boot boot.bin +python mtk.py r boot boot.bin ``` 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 ``` -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) ``` -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): ``` -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) ``` -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) ``` -python mtk rl out +python mtk.py rl out ``` Show gpt (use --preloader for brom) ``` -python mtk printgpt +python mtk.py printgpt ``` Mount the flash as a filesystem ``` -python mtk fs /mnt/mtk +python mtk.py fs /mnt/mtk ``` ### Write flash @@ -338,83 +343,83 @@ python mtk fs /mnt/mtk 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) ``` -python mtk wf flash.bin +python mtk.py wf flash.bin ``` 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) ``` -python mtk wo 0x128000 0x200000 flash.bin +python mtk.py wo 0x128000 0x200000 flash.bin ``` ### Erase flash Erase boot partition ``` -python mtk e boot +python mtk.py e boot ``` Erase boot sectors ``` -python mtk es boot [sector count] +python mtk.py es boot [sector count] ``` ### DA commands: 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 ``` -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) ``` -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] ``` -python mtk da rpmb w filename +python mtk.py da rpmb w filename ``` Generate and display rpmb1-3 key ``` -python mtk da generatekeys +python mtk.py da generatekeys ``` 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) `` -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". ### Dump preloader - 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 @@ -425,12 +430,12 @@ python mtk dumppreloader [--ptype=["amonet","kamakiri","kamakiri2","hashimoto"]] 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 : ``` -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. @@ -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 ``` -python mtk crash [--vid=vid] [--pid=pid] [--interface=interface] +python mtk.py crash [--vid=vid] [--pid=pid] [--interface=interface] ``` ### Read memory using patched preloader - 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 ``` -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 -### Run python mtk stage (brom) or mtk plstage (preloader) +### Run python mtk.py stage (brom) or mtk plstage (preloader) #### Run stage2 in bootrom `` -python mtk stage +python mtk.py stage `` #### Run stage2 in preloader `` -python mtk plstage +python mtk.py plstage `` #### Run stage2 plstage in bootrom - Boot in Brom or crash to Brom ``` -python mtk plstage --preloader=preloader.bin +python mtk.py plstage --preloader=preloader.bin ``` ### Use stage2 tool @@ -479,42 +484,42 @@ python mtk plstage --preloader=preloader.bin ### Leave stage2 and reboot `` -python stage2 reboot +python stage2.py reboot `` ### Read rpmb in stage2 mode `` -python stage2 rpmb +python stage2.py rpmb `` ### Read preloader in stage2 mode `` -python stage2 preloader +python stage2.py preloader `` ### 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 `` -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 `` -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 `` -python stage2 memwrite [start addr] --filename filename.bin +python stage2.py memwrite [start addr] --filename filename.bin `` ### 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 @@ -529,16 +534,3 @@ For dxcc, you need to use plstage instead of stage ### Chip details / configs - Go to config/brom_config.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/) diff --git a/Tools/da_parser.py b/Tools/da_parser.py index 5a655a4..8c8e727 100755 --- a/Tools/da_parser.py +++ b/Tools/da_parser.py @@ -92,9 +92,15 @@ def main(): with open(loader, "rb") as rf: rf.seek(mbuf) 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") 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')) if hashidx != -1: print("Hash check found.") @@ -111,7 +117,11 @@ def main(): if hashidx is not None: print("Hash check 4 (V6) found.") 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", hex(da[0]["hw_code"])[2:] + "_" + hex(startaddr)[2:] + os.path.basename( diff --git a/learning_resources.md b/learning_resources.md new file mode 100644 index 0000000..e11c95c --- /dev/null +++ b/learning_resources.md @@ -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/) + diff --git a/mtk.py b/mtk.py index 4aca4c3..5145d49 100755 --- a/mtk.py +++ b/mtk.py @@ -942,6 +942,26 @@ if __name__ == '__main__': da_dump.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_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)') diff --git a/mtkclient/Library/Auth/sla_keys.py b/mtkclient/Library/Auth/sla_keys.py index d81369b..daf2505 100644 --- a/mtkclient/Library/Auth/sla_keys.py +++ b/mtkclient/Library/Auth/sla_keys.py @@ -33,6 +33,12 @@ class SlaKey: 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 SlaKey(vendor="KaiOS", da_codes=[], @@ -47,14 +53,6 @@ da_sla_keys = [ d="09976537029b4362591c5b13873f223de5525d55df52dde283e52afa67f6c9dbf1408d2fb586a624efc93426f5f3be981f80e861ddd975a1e5e662db84f5164804a3ae717605d7f15866df9ed1497c38fdd6197243163ef22f958d7b822c57317203e9a1e7d18dad01f15054facdbddb9261a1272638da661fe4f9f0714ecf00e6541cc435afb1fd75a27d34b17ad400e9474ba850dafce266799caff32a058ff71e4c2daacaf8ba709e9ca4dc87584a7ffe8aa9a0a160ed069c3970b7dae3987ded71bd0bc824356987bd74363d46682c71913c3edbdb2a911f701f23aee3f8dd98180b5a138fd5ad74743682d2d2d1bb3d92786710248f316dd8391178ea81", n="D16403466C530EF9BB53C1E8A96A61A4E332E17DC0F55BB46D207AC305BAE9354EAAC2CB3077B33740D275036B822DB268200DE17DA3DB7266B27686B8970B85737050F084F8D576904E74CD6C53B31F0BB0CD60686BF67C60DA0EC20F563EEA715CEBDBF76D1C5C10E982AB2955D833DE553C9CDAFD7EA2388C02823CFE7DD9AC83FA2A8EB0685ABDAB56A92DF1A7805E8AC0BD10C0F3DCB1770A9E6BBC3418C5F84A48B7CB2316B2C8F64972F391B116A58C9395A9CE9E743569A367086D7771D39FEC8EBBBA3DD2B519785A76A9F589D36D637AF884543FD65BAC75BE823C0C50AA16D58187B97223625C54C66B5A5E4DBAEAB7BE89A4E340A2E241B09B2F", 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="CodeSigKey", @@ -69,6 +67,23 @@ da_sla_keys = [ 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 = [ SlaKey(vendor="Generic", da_codes=[], @@ -76,13 +91,6 @@ brom_sla_keys = [ d="4BD992E9A2230CD2ABEF49E4F6A7E11D7E2ADD24847787B320239829C560D5EAB94B8304317C938E9358E94758AE60D9B13F2913DD1A749A9941FACAFAB574D70EBBFBCC0133A4BE2134CBA3CE7EE18A6D3CC98D33DAB06AEEE512F405A3248EA316ABC31A2758D4C5A7B9DFCC02C2508A492EF3760A0D4CDA827CFFCADD11ED", n="5FFF0B70D5DE3FC5BF41CB824B4BFD14820571CE57EDD3E7C668CC570E718DB07DCC7A6CACD0E80DADC38AA33DB37816839D97980DF3E577A6E0B1169D708071E17DD259CFE538DBDA804A2FC07D795841F2F59DEE023A9919360D0A3F4647FDF5657D9FC5944C8BFA2802336BA23AFDCDE8D546E8806EB532AA7F95A01D8DD1", e="010001"), - """SlaKey(vendor="Generic", - da_codes=[], - name="AuthGen_SV5.ini", - d="9a3c3d4da0650cef38ed96ef833904c9c13835199367c7b9cb03a55e7aa482016a820dfe597cd54dd1f81fd879cf070ec0c25899ac5a49822db09675a92acf6a01e0f8f538bbe66de48ca9bdca313b616470d9ec2914356d03c95f7d9236549e5a21457e4dd5fcaf09046c47ca7436f06cd7b82cb6d2a936fca88b707f6ce28f33110fea1ec363e8482419db901cb0d38e574fe0c02ad117166b40ec78f59aaa7f3eafa425010a95614e046651273a6cb1371380c4e6ce81bdb892db6ff4892cc4d8c613a8fb3fec1e72c279052896872fc23da07fba63783374f3be8e16a15e0a04a139108dd6ac239f191135f4a895e27c670de065d2248e3f9c7e920fd001", - n="008C8BF38EB2FC7FC06D567DBF70E9C34BE4281C4239ED9C58A6B598C3AE7821815D94D0B463463EEBBD69FF6AF990AE0499B6C3B3CADCD91D54499CD66E5314DB610FC0C6CAEEB1F16B6F2D451E3F2B2D515008917FCEC50ADA4CE0699BCF247D5AE2A1DDD34C48624A657CCB11CE5F8C6CE92CAB6038EFC2A89E42E029488C02C3CF21947C86D51BBA8EF540A2A7CE85356F431891261D860B518E89DD73B2D240461ACB66BCC213403145DE83F6963147E65274EA1E45DB2D231E0774ECC86E4F2328F8A90835C4FDEF1088DDBA1D8F7CA0CA732A64BDA6816162C0F88F02CF97634D85530968CBF8B7CE6A8B67D53BBFB4910843EA413135D56FB5074445", - e="010001"), - """, SlaKey(vendor="Generic", da_codes=[], name="ROWAN / 0_2048_key.pem / CHIP_TEST_KEY.ini / lk/files/pbp/keys/toolauth/sla_prvk.pem", diff --git a/mtkclient/Library/Connection/devicehandler.py b/mtkclient/Library/Connection/devicehandler.py index f72d59b..a53e0ef 100755 --- a/mtkclient/Library/Connection/devicehandler.py +++ b/mtkclient/Library/Connection/devicehandler.py @@ -81,7 +81,7 @@ class DeviceClass(metaclass=LogBase): def usbwrite(self, data, pktsize=None): raise NotImplementedError() - def usbread(self, resplen=None, timeout=0): + def usbread(self, resplen=None, timeout=0, w_max_packet_size=None): raise NotImplementedError() def usbxmlread(self, maxtimeout=100): diff --git a/mtkclient/Library/Connection/seriallib.py b/mtkclient/Library/Connection/seriallib.py index 647f45f..a767b5c 100755 --- a/mtkclient/Library/Connection/seriallib.py +++ b/mtkclient/Library/Connection/seriallib.py @@ -4,11 +4,14 @@ import time import sys import logging +from queue import Queue + from mtkclient.Library.DA.xml.xml_param import max_xml_data_length import serial import serial.tools.list_ports import inspect from mtkclient.Library.Connection.devicehandler import DeviceClass + if sys.platform != "win32": import termios @@ -28,6 +31,7 @@ class SerialClass(DeviceClass): super().__init__(loglevel, portconfig, devclass) self.is_serial = True self.device = None + self.queue = Queue() def connect(self, ep_in=-1, ep_out=-1): if self.connected: @@ -193,7 +197,7 @@ class SerialClass(DeviceClass): self.device.flushOutput() 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)) if timeout == 0 and maxtimeout != 0: timeout = maxtimeout / 1000 # Some code calls this with ms delays, some with seconds. @@ -209,14 +213,26 @@ class SerialClass(DeviceClass): return b"" self.device.timeout = timeout epr = self.device.read + q = self.queue extend = res.extend 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: val = epr(bytestoread) if len(val) == 0: 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: error = str(e) if "timed out" in error: diff --git a/mtkclient/Library/Connection/usblib.py b/mtkclient/Library/Connection/usblib.py index e7bdc3f..f6ce3ad 100755 --- a/mtkclient/Library/Connection/usblib.py +++ b/mtkclient/Library/Connection/usblib.py @@ -4,6 +4,7 @@ import logging import os import sys +from queue import Queue import usb.core # pyusb import usb.util import time @@ -127,6 +128,7 @@ class UsbClass(DeviceClass): self.EP_IN = None self.EP_OUT = None self.is_serial = False + self.queue = Queue() 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") elif sys.platform.startswith('win32'): @@ -376,8 +378,8 @@ class UsbClass(DeviceClass): self.EP_IN = usb.util.find_descriptor(itf, # match the first OUT endpoint custom_match=lambda xe: \ - usb.util.endpoint_direction(xe.bEndpointAddress) == - usb.util.ENDPOINT_IN) + usb.util.endpoint_direction(xe.bEndpointAddress) == + usb.util.ENDPOINT_IN) self.connected = True return True print("Couldn't find CDC interface. Aborting.") @@ -456,7 +458,7 @@ class UsbClass(DeviceClass): def get_write_packetsize(self): 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: resplen = self.maxsize if resplen <= 0: @@ -465,19 +467,38 @@ class UsbClass(DeviceClass): timeout = 0 loglevel = self.loglevel 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 + fast = self.fast buffer = None buflen = min(resplen, w_max_packet_size) if self.fast: - buffer = self.buffer[:buflen] - while len(res) < resplen: + buffer = b[:buflen] + 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: - if self.fast: + if fast: 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]) else: - extend(epr(buflen)) + extend(epr(sz)) except usb.core.USBError as e: error = str(e.strerror) if "timed out" in error: @@ -489,6 +510,9 @@ class UsbClass(DeviceClass): elif "Overflow" in error: self.error("USB Overflow") return b"" + elif "No such device" in error: + self.error("Device disconnected") + sys.exit(1) else: self.info(repr(e)) return b"" diff --git a/mtkclient/Library/DA/daconfig.py b/mtkclient/Library/DA/daconfig.py index 55abc98..f1c9deb 100755 --- a/mtkclient/Library/DA/daconfig.py +++ b/mtkclient/Library/DA/daconfig.py @@ -256,6 +256,8 @@ class DAconfig(metaclass=LogBase): if loader.hw_version <= self.config.hwver: if loader.sw_version <= self.config.swver: if self.da_loader is None: + if loader.v6: + self.config.chipconfig.damode = DAmodes.XML self.da_loader = loader self.loader = loader.loader if self.da_loader is None and dacode != 0x6261: diff --git a/mtkclient/Library/DA/legacy/dalegacy_lib.py b/mtkclient/Library/DA/legacy/dalegacy_lib.py index 1a2d543..0fe5f9e 100755 --- a/mtkclient/Library/DA/legacy/dalegacy_lib.py +++ b/mtkclient/Library/DA/legacy/dalegacy_lib.py @@ -809,6 +809,8 @@ class DALegacy(metaclass=LogBase): res = self.usbread(1) if res == self.Rsp.ACK: speed = self.usbread(1) + if speed[0] > 0: + self.mtk.port.cdc.set_fast_mode(True) return speed return None @@ -1099,7 +1101,7 @@ class DALegacy(metaclass=LogBase): size = bytestoread if bytestoread > packetsize: size = packetsize - tmp = self.usbread(size) + tmp = self.usbread(size, w_max_packet_size=size) rq.put(tmp[:size]) bytestoread -= size curpos += size @@ -1124,8 +1126,8 @@ class DALegacy(metaclass=LogBase): size = bytestoread if bytestoread > packetsize: size = packetsize - buffer.extend(self.usbread(size)) - bytestoread -= size + buffer.extend(self.usbread(size, w_max_packet_size=size)) + bytestoread = len(buffer)-length checksum = unpack(">H", self.usbread(2))[0] self.debug("Checksum: %04X" % checksum) self.usbwrite(self.Rsp.ACK) diff --git a/mtkclient/Library/DA/xflash/xflash_lib.py b/mtkclient/Library/DA/xflash/xflash_lib.py index 119c6d0..7fad00a 100755 --- a/mtkclient/Library/DA/xflash/xflash_lib.py +++ b/mtkclient/Library/DA/xflash/xflash_lib.py @@ -832,22 +832,28 @@ class DAXFlash(metaclass=LogBase): worker.start() while bytestoread > 0: status = self.usbread(4 + 4 + 4) - magic, datatype, slength = unpack(" 4: - rq.put(resdata) - stmp = pack(" 4: + rq.put(resdata) + stmp = pack(" 0: sz = min(usbepsz, bytestoread) - data.extend(self.usbread(sz)) + data.extend(self.usbread(sz,w_max_packet_size=sz)) bytestoread -= sz if len(data) == length: return data diff --git a/mtkclient/Library/Hardware/hwcrypto.py b/mtkclient/Library/Hardware/hwcrypto.py index b6ad2bf..241d47f 100755 --- a/mtkclient/Library/Hardware/hwcrypto.py +++ b/mtkclient/Library/Hardware/hwcrypto.py @@ -61,7 +61,7 @@ class HwCrypto(metaclass=LogBase): return self.sej.hw_aes128_cbc_encrypt(buf=data, encrypt=True) elif mode == "sst": 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) print(data2.hex()) print(data3.hex()) diff --git a/mtkclient/Library/Hardware/hwcrypto_dxcc.py b/mtkclient/Library/Hardware/hwcrypto_dxcc.py index 2f1d016..c991c74 100755 --- a/mtkclient/Library/Hardware/hwcrypto_dxcc.py +++ b/mtkclient/Library/Hardware/hwcrypto_dxcc.py @@ -12,6 +12,14 @@ from Cryptodome.Cipher import AES from Cryptodome.Util import Counter 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" + \ "CE7B47714F1395FDEBCF12A2D41155B0" + \ "FB587A51FECCCB4DDA1C8E5EB9EB69B8" + \ @@ -1114,6 +1122,18 @@ class Dxcc(metaclass=LogBase): self.tzcc_clk(0) 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): rpmb_ikey = bytes.fromhex("AD1AC6B4BDF4EDB7") rpmb_salt = bytes.fromhex("69EF6584") @@ -1124,37 +1144,120 @@ class Dxcc(metaclass=LogBase): self.tzcc_clk(0) return rpmbkey - def salt_func(self, value): + def sasi_bsv_otp_word_read(self, otpAddress): + if otpAddress>0x24: + return None while True: val = self.read32(self.dxcc_base + (0x2AF * 4)) & 1 if val != 0: break - self.write32(self.dxcc_base + (0x2A9 * 4), (4 * value) | 0x10000) + self.write32(self.dxcc_base + (0x2A9 * 4), (4 * otpAddress) | 0x10000) while True: - val = self.read32(self.dxcc_base + (0x2AD * 4)) << 31 + val = self.read32(self.dxcc_base + (0x2AD * 4)) & 1 if val != 0: break res = self.read32(self.dxcc_base + (0x2AB * 4)) 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): plat_key = b"KEY PLAT" prov_key = b"PROVISION KEY" self.tzcc_clk(1) dstaddr = self.da_payload_addr - 0x300 - - salt = hashlib.sha256(bytes.fromhex(oem_pubk)).digest() - """ - salt = bytearray(b"\x00"*0x20) - 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) + lcs = self.sasi_bsv_lcs_get() + #salt = hashlib.sha256(bytes.fromhex(oem_pubk)).digest() + 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 - 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 + 0xAC4, 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): 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 if requestedlen > 0xFF or (requestedlen << 28) & 0xFFFFFFFF: return 0xF2000003 diff --git a/mtkclient/Library/Hardware/hwcrypto_sej.py b/mtkclient/Library/Hardware/hwcrypto_sej.py index bb809a6..8ad03ad 100755 --- a/mtkclient/Library/Hardware/hwcrypto_sej.py +++ b/mtkclient/Library/Hardware/hwcrypto_sej.py @@ -468,7 +468,7 @@ class Sej(metaclass=LogBase): 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) _iv = [seed, (~seed) & 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) for pos in range(3): 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 else: 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 def sej_terminate(self): @@ -557,7 +557,7 @@ class Sej(metaclass=LogBase): if legacy: self.reg.HACC_UNK |= 2 # clear HACC_ASRC/HACC_ACFG/HACC_AOUT - self.reg.HACC_ACON2 = 0x40000000 | self.HACC_AES_CLR + self.reg.HACC_ACON2 |= 0x40000000 i = 0 while i < 20: if self.reg.HACC_ACON2 > 0x80000000: @@ -598,12 +598,12 @@ class Sej(metaclass=LogBase): self.reg.HACC_ACONK = 0 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: iv = self.g_HACC_CFG_1 self.tz_pre_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") buf2 = self.sej_run(buf) self.info("HACC terminate") @@ -693,8 +693,8 @@ class Sej(metaclass=LogBase): break return data - def sej_sec_cfg_hw(self, data, encrypt=True): - if encrypt: + def sej_sec_cfg_hw(self, data, encrypt=True, noxor=False): + if encrypt and not noxor: data = self.xor_data(bytearray(data)) self.info("HACC init") 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) self.info("HACC terminate") self.sej_terminate() - if not encrypt: + if not encrypt and not noxor: dec = self.xor_data(dec) return dec - def sej_sec_cfg_hw_V3(self, data, encrypt=True): - return self.hw_aes128_cbc_encrypt(buf=data, encrypt=encrypt) + def sej_sec_cfg_hw_V3(self, data, encrypt=True, legacy=False): + return self.hw_aes128_cbc_encrypt(buf=data, encrypt=encrypt, legacy=legacy) # seclib_get_msg_auth_key def generate_rpmb(self, meid, otp, derivedlen=32): @@ -782,7 +782,7 @@ class Sej(metaclass=LogBase): self.sej_terminate() 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 LR9 CRC RC4 AES128-CBC SBC=OFF @@ -800,7 +800,7 @@ class Sej(metaclass=LogBase): iv = [seed, (~seed) & 0xFFFFFFFF, (((seed >> 16) | (seed << 16)) & 0xFFFFFFFF), (~((seed >> 16) | (seed << 16)) & 0xFFFFFFFF)] 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") dec = self.sej_run(data) self.info("HACC terminate") diff --git a/mtkclient/Library/Hardware/seccfg.py b/mtkclient/Library/Hardware/seccfg.py index e524c40..5188393 100755 --- a/mtkclient/Library/Hardware/seccfg.py +++ b/mtkclient/Library/Hardware/seccfg.py @@ -60,7 +60,12 @@ class SecCfgV4(metaclass=LogBase): if _hash == dec_hash: self.hwtype = "V3" 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_MP_DEFAULT = 0x02 @@ -91,11 +96,13 @@ class SecCfgV4(metaclass=LogBase): dec_hash = hashlib.sha256(seccfg_data).digest() enc_hash = b"" 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": - 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": - 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 while len(indata) % 0x200 != 0: indata += b"\x00" @@ -199,14 +206,18 @@ class SecCfgV3(metaclass=LogBase): if self.magic != 0x4D4D4D4D or self.endflag != 0x45454545: self.error("Unknown V3 seccfg structure !") 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"]: - 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"]: - 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"]: - self.error("Unknown V3 seccfg encryption !") - return False + err = self.hwc.sej.sej_sec_cfg_hw_V3(self.data, encrypt=False, legacy=True) + 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: self.hwtype = "V3" else: @@ -267,11 +278,13 @@ class SecCfgV3(metaclass=LogBase): ed.write(self.seccfg_ext) indata = ed.getbuffer() 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": - 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": - 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: return False, "Unknown error" wf.write(indata) @@ -297,7 +310,7 @@ if __name__ == "__main__": sej_base = None - v3 = SecCfgV3(hwc, MTK) - v3.parse(data) - ret, newdata = v3.create("lock") + v4 = SecCfgV4(hwc, MTK) + v4.parse(data) + ret, newdata = v4.create("lock") print(newdata.hex()) diff --git a/mtkclient/Library/mtk_main.py b/mtkclient/Library/mtk_main.py index a5bc2aa..0cab23c 100755 --- a/mtkclient/Library/mtk_main.py +++ b/mtkclient/Library/mtk_main.py @@ -42,6 +42,13 @@ class ArgHandler(metaclass=LogBase): config.pid = getint(args.pid) except AttributeError: pass + config.stock = True + try: + if args.stock is not None: + config.stock = args.stock + except AttributeError: + pass + config.reconnect = True try: if args.noreconnect is not None: diff --git a/mtkclient/Library/pltools.py b/mtkclient/Library/pltools.py index 28cb39f..f8ba780 100755 --- a/mtkclient/Library/pltools.py +++ b/mtkclient/Library/pltools.py @@ -82,8 +82,8 @@ class PLTools(metaclass=LogBase): return True elif response_ack == b"\xc1\xc2\xc3\xc4": if "preloader" in rf.name: - ack = self.mtk.port.usbread(4) - if ack == b"\xC0\xC0\xC0\xC0": + rack = self.mtk.port.usbread(4) + if rack == b"\xC0\xC0\xC0\xC0": with open("preloader.bin", 'wb') as wf: print_progress(0, 100, prefix='Progress:', suffix='Complete', bar_length=50) for pos in range(0, 0x40000, 64): diff --git a/mtkclient/config/brom_config.py b/mtkclient/config/brom_config.py index 7a4be8f..a10a663 100755 --- a/mtkclient/config/brom_config.py +++ b/mtkclient/config/brom_config.py @@ -1115,7 +1115,7 @@ hwconfig = { socid_addr=0x102BA8, efuse_addr=0x11cb0000, damode=DAmodes.XFLASH, - dacode=0x1066, + dacode=0x6781, name="MT6781", description="Helio G96", loader="mt6781_payload.bin" @@ -1471,7 +1471,7 @@ hwconfig = { damode=DAmodes.XML, dacode=0x1172, name="MT6895", - description="Dimensity 8100" + description="Dimensity 8200" # loader="mt6893_payload.bin" ), # MT6789 Oppo Realme 10 / Gigaset GX4 diff --git a/mtkclient/config/mtk_config.py b/mtkclient/config/mtk_config.py index d240b4a..69f83a3 100755 --- a/mtkclient/config/mtk_config.py +++ b/mtkclient/config/mtk_config.py @@ -69,6 +69,7 @@ class MtkConfig(metaclass=LogBase): self.sram = None self.dram = None self.otp = None + self.stock = False if loglevel == logging.DEBUG: logfilename = os.path.join("logs", "log.txt") fh = logging.FileHandler(logfilename) diff --git a/pyproject.toml b/pyproject.toml index 6708e71..6cbb0f1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,7 +13,7 @@ maintainers = [ ] readme = "README.md" license = {file = "LICENSE"} -version = "2.0.1" +version = "2.0.2" requires-python = ">= 3.8" dependencies = [ "pyusb",