aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArisotura <thetotalworm@gmail.com>2020-03-30 11:04:50 +0200
committerArisotura <thetotalworm@gmail.com>2020-03-30 11:04:50 +0200
commit104b2a03aad74121358828a2c7c3a1a636f66a42 (patch)
treed5dc79810d966b31bf79261665428178ab6a7d03
parent5f99a681512627aa6f63325a676301bc7fa4d927 (diff)
properly handle ROMs with encrypted secure area
-rw-r--r--src/NDS.cpp19
-rw-r--r--src/NDSCart.cpp70
-rw-r--r--src/NDSCart.h1
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);