diff options
author | Arisotura <thetotalworm@gmail.com> | 2020-03-30 11:04:50 +0200 |
---|---|---|
committer | Arisotura <thetotalworm@gmail.com> | 2020-03-30 11:04:50 +0200 |
commit | 104b2a03aad74121358828a2c7c3a1a636f66a42 (patch) | |
tree | d5dc79810d966b31bf79261665428178ab6a7d03 /src | |
parent | 5f99a681512627aa6f63325a676301bc7fa4d927 (diff) |
properly handle ROMs with encrypted secure area
Diffstat (limited to 'src')
-rw-r--r-- | src/NDS.cpp | 19 | ||||
-rw-r--r-- | src/NDSCart.cpp | 70 | ||||
-rw-r--r-- | src/NDSCart.h | 1 |
3 files changed, 68 insertions, 22 deletions
diff --git a/src/NDS.cpp b/src/NDS.cpp index 09d255d..a2ab6ce 100644 --- a/src/NDS.cpp +++ b/src/NDS.cpp @@ -318,7 +318,24 @@ void SetupDirectBoot() MapSharedWRAM(3); - for (u32 i = 0; i < bootparams[3]; i+=4) + u32 arm9start = 0; + + // load the ARM9 secure area + if (bootparams[0] >= 0x4000 && bootparams[0] < 0x8000) + { + u8 securearea[0x800]; + NDSCart::DecryptSecureArea(securearea); + + for (u32 i = 0; i < 0x800; i+=4) + { + ARM9Write32(bootparams[2]+i, *(u32*)&securearea[i]); + arm9start += 4; + } + } + + // CHECKME: firmware seems to load this in 0x200 byte chunks + + for (u32 i = arm9start; i < bootparams[3]; i+=4) { u32 tmp = *(u32*)&NDSCart::CartROM[bootparams[0]+i]; ARM9Write32(bootparams[2]+i, tmp); diff --git a/src/NDSCart.cpp b/src/NDSCart.cpp index c313011..cd04470 100644 --- a/src/NDSCart.cpp +++ b/src/NDSCart.cpp @@ -865,6 +865,35 @@ bool ReadROMParams(u32 gamecode, u32* params) } +void DecryptSecureArea(u8* out) +{ + u32 gamecode = *(u32*)&CartROM[0x0C]; + u32 arm9base = *(u32*)&CartROM[0x20]; + + memcpy(out, &CartROM[arm9base], 0x800); + + Key1_InitKeycode(gamecode, 2, 2); + Key1_Decrypt((u32*)&out[0]); + + Key1_InitKeycode(gamecode, 3, 2); + for (u32 i = 0; i < 0x800; i += 8) + Key1_Decrypt((u32*)&out[i]); + + if (!strncasecmp((const char*)out, "encryObj", 8)) + { + printf("Secure area decryption OK\n"); + *(u32*)&out[0] = 0xE7FFDEFF; + *(u32*)&out[4] = 0xE7FFDEFF; + } + else + { + printf("Secure area decryption failed\n"); + for (u32 i = 0; i < 0x800; i += 4) + *(u32*)&out[i] = 0xE7FFDEFF; + } +} + + bool LoadROM(const char* path, const char* sram, bool direct) { // TODO: streaming mode? for really big ROMs or systems with limited RAM @@ -933,28 +962,8 @@ bool LoadROM(const char* path, const char* sram, bool direct) printf("Cart ID: %08X\n", CartID); - if (*(u32*)&CartROM[0x20] < 0x4000) - { - //ApplyDLDIPatch(); - } - - if (direct) - { - // TODO: in the case of an already-encrypted secure area, direct boot - // needs it decrypted - NDS::SetupDirectBoot(); - CmdEncMode = 2; - } - - CartInserted = true; - - // TODO: support more fancy cart types (homebrew?, flashcarts, etc) - if (CartID & 0x08000000) - ROMCommandHandler = ROMCommand_RetailNAND; - else - ROMCommandHandler = ROMCommand_Retail; - u32 arm9base = *(u32*)&CartROM[0x20]; + if (arm9base < 0x8000) { if (arm9base >= 0x4000) @@ -975,9 +984,28 @@ bool LoadROM(const char* path, const char* sram, bool direct) } } else + { CartIsHomebrew = true; + //ApplyDLDIPatch(); + } + } + + if (direct) + { + // TODO: in the case of an already-encrypted secure area, direct boot + // needs it decrypted + NDS::SetupDirectBoot(); + CmdEncMode = 2; } + CartInserted = true; + + // TODO: support more fancy cart types (homebrew?, flashcarts, etc) + if (CartID & 0x08000000) + ROMCommandHandler = ROMCommand_RetailNAND; + else + ROMCommandHandler = ROMCommand_Retail; + // encryption Key1_InitKeycode(gamecode, 2, 2); diff --git a/src/NDSCart.h b/src/NDSCart.h index 4167aa6..f19aea1 100644 --- a/src/NDSCart.h +++ b/src/NDSCart.h @@ -44,6 +44,7 @@ void Reset(); void DoSavestate(Savestate* file); +void DecryptSecureArea(u8* out); bool LoadROM(const char* path, const char* sram, bool direct); void RelocateSave(const char* path, bool write); |