diff --git a/arm9/source/firm.c b/arm9/source/firm.c index 692dcf15..ddc973c9 100755 --- a/arm9/source/firm.c +++ b/arm9/source/firm.c @@ -39,6 +39,7 @@ #include "chainloader.h" static Firm *firm = (Firm *)0x20001000; +u32 firmProtoVersion = 0; static __attribute__((noinline)) bool overlaps(u32 as, u32 ae, u32 bs, u32 be) { @@ -203,29 +204,38 @@ u32 loadNintendoFirm(FirmwareType *firmType, FirmwareSource nandType, bool loadF { firmVersion = 0xFFFFFFFF; - if(!ISN3DS && *firmType == NATIVE_FIRM) + if(!ISN3DS && (*firmType == NATIVE_FIRM || *firmType == NATIVE_FIRM1X2X)) { - __attribute__((aligned(4))) static const u8 hashes[3][0x20] = { + __attribute__((aligned(4))) static const u8 hashes[4][0x20] = { + {0xD7, 0x43, 0x0F, 0x27, 0x8D, 0xC9, 0x3F, 0x4C, 0x96, 0xB5, 0xA8, 0x91, 0x48, 0xDB, 0x08, 0x8A, + 0x7E, 0x46, 0xB3, 0x95, 0x65, 0xA2, 0x05, 0xF1, 0xF2, 0x41, 0x21, 0xF1, 0x0C, 0x59, 0x6A, 0x9D}, {0x39, 0x75, 0xB5, 0x28, 0x24, 0x5E, 0x8B, 0x56, 0xBC, 0x83, 0x79, 0x41, 0x09, 0x2C, 0x42, 0xE6, 0x26, 0xB6, 0x80, 0x59, 0xA5, 0x56, 0xF9, 0xF9, 0x6E, 0xF3, 0x63, 0x05, 0x58, 0xDF, 0x35, 0xEF}, {0x81, 0x9E, 0x71, 0x58, 0xE5, 0x44, 0x73, 0xF7, 0x48, 0x78, 0x7C, 0xEF, 0x5E, 0x30, 0xE2, 0x28, 0x78, 0x0B, 0x21, 0x23, 0x94, 0x63, 0xE8, 0x4E, 0x06, 0xBB, 0xD6, 0x8D, 0xA0, 0x99, 0xAE, 0x98}, {0x1D, 0xD5, 0xB0, 0xC2, 0xD9, 0x4A, 0x4A, 0xF3, 0x23, 0xDD, 0x2F, 0x65, 0x21, 0x95, 0x9B, 0x7E, - 0xF2, 0x71, 0x7E, 0xB6, 0x7A, 0x3A, 0x74, 0x78, 0x0D, 0xE3, 0xB5, 0x0C, 0x2B, 0x7F, 0x85, 0x37} + 0xF2, 0x71, 0x7E, 0xB6, 0x7A, 0x3A, 0x74, 0x78, 0x0D, 0xE3, 0xB5, 0x0C, 0x2B, 0x7F, 0x85, 0x37}, }; u32 i; - for(i = 0; i < 3; i++) if(memcmp(firm->section[1].hash, hashes[i], 0x20) == 0) break; + for(i = 0; i < 4; i++) if(memcmp(firm->section[1].hash, hashes[i], 0x20) == 0) break; switch(i) { + // Beta case 0: + firmVersion = 0x0; + firmProtoVersion = 243; + *firmType = NATIVE_PROTOTYPE; + break; + // Release + case 1: firmVersion = 0x18; break; - case 1: + case 2: firmVersion = 0x1D; break; - case 2: + case 3: firmVersion = 0x1F; break; default: @@ -737,6 +747,26 @@ u32 patch1x2xNativeAndSafeFirm(void) return ret; } +u32 patchPrototypeNative(void) +{ + u8 *arm9Section = (u8 *)firm + firm->section[2].offset; + + //Find the Process9 .code location, size and memory address + u32 process9Size, + process9MemAddr; + u8 *process9Offset = getProcess9Info(arm9Section, firm->section[2].size, &process9Size, &process9MemAddr); + + u32 kernel9Size = (u32)(process9Offset - arm9Section) - sizeof(Cxi) - 0x200, + ret = 0; + + ret += patchProtoNandSignatureCheck(process9Offset, process9Size); + + //Arm9 exception handlers + ret += patchArm9ExceptionHandlersInstall(arm9Section, kernel9Size); + + return ret; +} + void launchFirm(int argc, char **argv) { prepareArm11ForFirmlaunch(); diff --git a/arm9/source/firm.h b/arm9/source/firm.h index 591ec2fa..fbb3ff01 100644 --- a/arm9/source/firm.h +++ b/arm9/source/firm.h @@ -35,4 +35,5 @@ u32 patchNativeFirm(u32 firmVersion, FirmwareSource nandType, bool loadFromStora u32 patchTwlFirm(u32 firmVersion, bool loadFromStorage, bool doUnitinfoPatch); u32 patchAgbFirm(bool loadFromStorage, bool doUnitinfoPatch); u32 patch1x2xNativeAndSafeFirm(void); +u32 patchPrototypeNative(void); void launchFirm(int argc, char **argv); diff --git a/arm9/source/main.c b/arm9/source/main.c index 248bbff3..02305ecf 100644 --- a/arm9/source/main.c +++ b/arm9/source/main.c @@ -386,6 +386,9 @@ boot: case NATIVE_FIRM1X2X: res = patch1x2xNativeAndSafeFirm(); break; + case NATIVE_PROTOTYPE: + res = patchPrototypeNative(); + break; } if(res != 0) error("Failed to apply %u FIRM patch(es).", res); diff --git a/arm9/source/patches.c b/arm9/source/patches.c index 6a2152cc..4c3823cf 100644 --- a/arm9/source/patches.c +++ b/arm9/source/patches.c @@ -45,6 +45,7 @@ #define K11EXT_VA 0x70000000 extern u16 launchedPath[]; +extern u32 firmProtoVersion; u8 *getProcess9Info(u8 *pos, u32 size, u32 *process9Size, u32 *process9MemAddr) { @@ -54,10 +55,20 @@ u8 *getProcess9Info(u8 *pos, u32 size, u32 *process9Size, u32 *process9MemAddr) Cxi *off = (Cxi *)(temp - 0x100); - *process9Size = (off->ncch.exeFsSize - 1) * 0x200; *process9MemAddr = off->exHeader.systemControlInfo.textCodeSet.address; - - return (u8 *)off + (off->ncch.exeFsOffset + 1) * 0x200; + + // Prototype FW has a different NCCH format + if (firmProtoVersion && firmProtoVersion <= 243) + { + *process9Size = off->ncch.exeFsSize; + return (u8 *)off + off->ncch.exeFsOffset; + } + else + { + *process9Size = (off->ncch.exeFsSize - 1) * 0x200; + return (u8 *)off + (off->ncch.exeFsOffset + 1) * 0x200; + } + } u32 *getKernel11Info(u8 *pos, u32 size, u32 *baseK11VA, u8 **freeK11Space, u32 **arm11SvcHandler, u32 **arm11ExceptionsPage) @@ -834,3 +845,20 @@ u32 patchLgyK11(u8 *section1, u32 section1Size, u8 *section2, u32 section2Size) return 0; } + +u32 patchProtoNandSignatureCheck(u8 *pos, u32 size) { + if (firmProtoVersion == 243) { + static const u8 pattern[] = {0x08, 0x31, 0x9F, 0xE5}; + + // Signature check function returns 0 if failed and 1 if succeeded. + // Proc9 breaks if the returned value is 0, change it to break if + // the returned value is 2 (never). + u8 *off = memsearch(pos, pattern, size, sizeof(pattern)) + 0x20; + if (!off) + return 1; + + *off = 2; + } + + return 0; +} \ No newline at end of file diff --git a/arm9/source/patches.h b/arm9/source/patches.h index b77d092a..75eb03a9 100644 --- a/arm9/source/patches.h +++ b/arm9/source/patches.h @@ -31,6 +31,7 @@ * FIRM partition writes patches by delebile * Idea for svcBreak patches from yellows8 and others on #3dsdev * TWL_FIRM patches by Steveice10 and others +* Signature patches for prototype FW by PabloMK7 */ #pragma once @@ -68,3 +69,4 @@ u32 patchTwlShaHashChecks(u8 *pos, u32 size); u32 patchAgbBootSplash(u8 *pos, u32 size); void patchTwlBg(u8 *pos, u32 size); // silently fails u32 patchLgyK11(u8 *section1, u32 section1Size, u8 *section2, u32 section2Size); +u32 patchProtoNandSignatureCheck(u8 *pos, u32 size); \ No newline at end of file diff --git a/arm9/source/types.h b/arm9/source/types.h index 357c5d76..7b77f502 100644 --- a/arm9/source/types.h +++ b/arm9/source/types.h @@ -134,7 +134,8 @@ typedef enum FirmwareType AGB_FIRM, SAFE_FIRM, SYSUPDATER_FIRM, - NATIVE_FIRM1X2X + NATIVE_FIRM1X2X, + NATIVE_PROTOTYPE, } FirmwareType; typedef enum bootType