diff --git a/README.md b/README.md index 06fb1d6..4c279ca 100644 --- a/README.md +++ b/README.md @@ -3,10 +3,10 @@ **Compiling:** -First you need to clone the repository recursively with: 'git clone --recursive https://github.com/AuroraWright/Luma3DS.git' +First you need to clone the repository recursively with: `git clone --recursive https://github.com/AuroraWright/Luma3DS.git` To compile, you'll need [armips](https://github.com/Kingcom/armips), [bin2c](https://sourceforge.net/projects/bin2c/), and a recent build of [makerom](https://github.com/profi200/Project_CTR) added to your PATH. For your convenience, here are [Windows](http://www91.zippyshare.com/v/ePGpjk9r/file.html) and [Linux](https://mega.nz/#!uQ1T1IAD!Q91O0e12LXKiaXh_YjXD3D5m8_W3FuMI-hEa6KVMRDQ) builds of armips (thanks to who compiled them!). -Finally just run 'make' and everything should work! +Finally just run `make` and everything should work! You can find the compiled files in the 'out' folder. **Setup / Usage / Features:** @@ -20,4 +20,4 @@ See https://github.com/AuroraWright/Luma3DS/wiki/Credits **Licensing:** This software is licensed under the terms of the GPLv3. -You can find a copy of the license in the LICENSE.txt file. \ No newline at end of file +You can find a copy of the license in the LICENSE.txt file. diff --git a/source/crypto.c b/source/crypto.c index 9819af8..7d88376 100755 --- a/source/crypto.c +++ b/source/crypto.c @@ -364,11 +364,11 @@ void arm9Loader(u8 *arm9Section, u32 mode) if(mode) { - const u8 key2[0x10] = {0x42, 0x3F, 0x81, 0x7A, 0x23, 0x52, 0x58, 0x31, 0x6E, 0x75, 0x8E, 0x3A, 0x39, 0x43, 0x2E, 0xD0}; + const u8 key1[0x10] = {0x07, 0x29, 0x44, 0x38, 0xF8, 0xC9, 0x75, 0x93, 0xAA, 0x0E, 0x4A, 0xB4, 0xAE, 0x84, 0xC1, 0xD8}, + key2[0x10] = {0x42, 0x3F, 0x81, 0x7A, 0x23, 0x52, 0x58, 0x31, 0x6E, 0x75, 0x8E, 0x3A, 0x39, 0x43, 0x2E, 0xD0}; u8 keyX[0x10]; - //Set 0x11 to key2 for the arm9bin and misc keys - aes_setkey(0x11, key2, AES_KEYNORMAL, AES_INPUT_BE | AES_INPUT_NORMAL); + aes_setkey(0x11, mode == 1 ? key1 : key2, AES_KEYNORMAL, AES_INPUT_BE | AES_INPUT_NORMAL); aes_use_keyslot(0x11); aes(keyX, arm9Section + 0x60, 1, NULL, AES_ECB_DECRYPT_MODE, 0); aes_setkey(arm9BinSlot, keyX, AES_KEYX, AES_INPUT_BE | AES_INPUT_NORMAL); @@ -382,7 +382,7 @@ void arm9Loader(u8 *arm9Section, u32 mode) aes(arm9Section + 0x800, arm9Section + 0x800, arm9BinSize / AES_BLOCK_SIZE, arm9BinCTR, AES_CTR_MODE, AES_INPUT_BE | AES_INPUT_NORMAL); //Set >=9.6 KeyXs - if(mode) + if(mode == 2) { u8 keyData[0x10] = {0xDD, 0xDA, 0xA4, 0xC6, 0x2C, 0xC4, 0x50, 0xE9, 0xDA, 0xB6, 0x9B, 0x0D, 0x9D, 0x2A, 0x21, 0x98}, decKey[0x10]; diff --git a/source/emunand.c b/source/emunand.c index c6efbb6..26e0f53 100644 --- a/source/emunand.c +++ b/source/emunand.c @@ -43,9 +43,9 @@ u32 getSDMMC(u8 *pos, u32 size) { //Look for struct code const u8 pattern[] = {0x21, 0x20, 0x18, 0x20}; - const u8 *off = memsearch(pos, pattern, size, 4) - 1; + const u8 *off = memsearch(pos, pattern, size, 4); - return *(u32 *)(off + 0x0A) + *(u32 *)(off + 0x0E); + return *(u32 *)(off + 9) + *(u32 *)(off + 0xD); } void getEmuRW(u8 *pos, u32 size, u32 *readOff, u32 *writeOff) diff --git a/source/firm.c b/source/firm.c index 4b8245e..6f2a036 100755 --- a/source/firm.c +++ b/source/firm.c @@ -280,8 +280,19 @@ static inline void patchNativeFirm(u32 nandType, u32 emuHeader, u32 a9lhMode) if(console) { - //Determine if we're booting the 9.0 FIRM - nativeFirmType = arm9Section[0x51] != 0xFF; + //Determine the NATIVE_FIRM version + switch(arm9Section[0x53]) + { + case 0xFF: + nativeFirmType = 0; + break; + case '1': + nativeFirmType = 1; + break; + default: + nativeFirmType = 2; + break; + } //Decrypt ARM9Bin and patch ARM9 entrypoint to skip arm9loader arm9Loader(arm9Section, nativeFirmType); @@ -325,8 +336,8 @@ static inline void patchNativeFirm(u32 nandType, u32 emuHeader, u32 a9lhMode) *unitInfoOffset = unitInfoPatch; } - //Replace the FIRM loader with the injector - injectLoader(); + //Replace the FIRM loader with the injector while copying section0 + copySection0AndInjectLoader(); } static inline void patchEmuNAND(u8 *arm9Section, u8 *proc9Offset, u32 emuHeader) @@ -384,21 +395,16 @@ static inline void patchReboots(u8 *arm9Section, u8 *proc9Offset) *pos_fopen = fOpenOffset; } -static inline void injectLoader(void) +static inline void copySection0AndInjectLoader(void) { u32 loaderSize; - - void *loaderOffset = getLoader((u8 *)firm + section[0].offset, section[0].size, &loaderSize); - - //Check that the injector CXI isn't larger than the original - if((u32)injector_size <= loaderSize) - { - memcpy(loaderOffset, injector, injector_size); - - //Patch content size and ExeFS size to match the repaced loader's ones - *((u32 *)loaderOffset + 0x41) = loaderSize / 0x200; - *((u32 *)loaderOffset + 0x69) = loaderSize / 0x200 - 5; - } + u8 *arm11Section0 = (u8 *)firm + section[0].offset; + u32 injectorOffset = (u8 *)getLoader((u8 *)firm + section[0].offset, section[0].size, &loaderSize) - arm11Section0; + u32 remaining = section[0].size - (injectorOffset + loaderSize); + + memcpy(section[0].address, arm11Section0, injectorOffset); + memcpy(section[0].address + injectorOffset, injector, injector_size); + memcpy(section[0].address + injectorOffset + injector_size, arm11Section0 + section[0].size - remaining, remaining); } static inline void patchLegacyFirm(u32 firmType) @@ -483,7 +489,7 @@ static void patchFirmWrites(u8 *arm9Section, u32 mode) static inline void launchFirm(u32 bootType) { //Copy FIRM sections to respective memory locations - for(u32 i = 0; i < 4 && section[i].size; i++) + for(u32 i = 1; i < 4 && section[i].size; i++) memcpy(section[i].address, (u8 *)firm + section[i].offset, section[i].size); //Determine the ARM11 entry to use diff --git a/source/firm.h b/source/firm.h index 3786460..e8a72bf 100644 --- a/source/firm.h +++ b/source/firm.h @@ -40,7 +40,7 @@ static inline void loadFirm(u32 firmType, u32 externalFirm); static inline void patchNativeFirm(u32 nandType, u32 emuHeader, u32 a9lhMode); static inline void patchEmuNAND(u8 *arm9Section, u8 *proc9Offset, u32 emuHeader); static inline void patchReboots(u8 *arm9Section, u8 *proc9Offset); -static inline void injectLoader(void); +static inline void copySection0AndInjectLoader(void); static inline void patchLegacyFirm(u32 firmType); static inline void patchSafeFirm(void); static void patchFirmWrites(u8 *arm9Section, u32 mode); diff --git a/source/patches.c b/source/patches.c index 5252543..eae6ef0 100644 --- a/source/patches.c +++ b/source/patches.c @@ -84,9 +84,16 @@ u8 *getUnitInfoValueSet(u8 *pos, u32 size) void *getLoader(u8 *pos, u32 size, u32 *loaderSize) { - u8 *const off = memsearch(pos, "loade", size, 5); - - *loaderSize = *(u32 *)(off - 0xFC) * 0x200; - - return off - 0x200; + u8 *off = pos; + do + { + if(*(u32 *)(off + 0x200) == 0x64616F6C) break; //"load" + off += *(u32 *)(off + 0x104) * 0x200; //size of the CXI + } + while(off < pos + size); + + if(off >= pos + size) return NULL; + + *loaderSize = *(u32 *)(off + 0x104) * 0x200; + return off; } \ No newline at end of file