Merge branch 'master' into developer
Conflicts: source/firm.c
This commit is contained in:
commit
8dd9c1a1af
@ -3,10 +3,10 @@
|
|||||||
|
|
||||||
**Compiling:**
|
**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.
|
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!).
|
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.
|
You can find the compiled files in the 'out' folder.
|
||||||
|
|
||||||
**Setup / Usage / Features:**
|
**Setup / Usage / Features:**
|
||||||
|
@ -364,11 +364,11 @@ void arm9Loader(u8 *arm9Section, u32 mode)
|
|||||||
|
|
||||||
if(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];
|
u8 keyX[0x10];
|
||||||
|
|
||||||
//Set 0x11 to key2 for the arm9bin and misc keys
|
aes_setkey(0x11, mode == 1 ? key1 : key2, AES_KEYNORMAL, AES_INPUT_BE | AES_INPUT_NORMAL);
|
||||||
aes_setkey(0x11, key2, AES_KEYNORMAL, AES_INPUT_BE | AES_INPUT_NORMAL);
|
|
||||||
aes_use_keyslot(0x11);
|
aes_use_keyslot(0x11);
|
||||||
aes(keyX, arm9Section + 0x60, 1, NULL, AES_ECB_DECRYPT_MODE, 0);
|
aes(keyX, arm9Section + 0x60, 1, NULL, AES_ECB_DECRYPT_MODE, 0);
|
||||||
aes_setkey(arm9BinSlot, keyX, AES_KEYX, AES_INPUT_BE | AES_INPUT_NORMAL);
|
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);
|
aes(arm9Section + 0x800, arm9Section + 0x800, arm9BinSize / AES_BLOCK_SIZE, arm9BinCTR, AES_CTR_MODE, AES_INPUT_BE | AES_INPUT_NORMAL);
|
||||||
|
|
||||||
//Set >=9.6 KeyXs
|
//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},
|
u8 keyData[0x10] = {0xDD, 0xDA, 0xA4, 0xC6, 0x2C, 0xC4, 0x50, 0xE9, 0xDA, 0xB6, 0x9B, 0x0D, 0x9D, 0x2A, 0x21, 0x98},
|
||||||
decKey[0x10];
|
decKey[0x10];
|
||||||
|
@ -43,9 +43,9 @@ u32 getSDMMC(u8 *pos, u32 size)
|
|||||||
{
|
{
|
||||||
//Look for struct code
|
//Look for struct code
|
||||||
const u8 pattern[] = {0x21, 0x20, 0x18, 0x20};
|
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)
|
void getEmuRW(u8 *pos, u32 size, u32 *readOff, u32 *writeOff)
|
||||||
|
@ -280,8 +280,19 @@ static inline void patchNativeFirm(u32 nandType, u32 emuHeader, u32 a9lhMode)
|
|||||||
|
|
||||||
if(console)
|
if(console)
|
||||||
{
|
{
|
||||||
//Determine if we're booting the 9.0 FIRM
|
//Determine the NATIVE_FIRM version
|
||||||
nativeFirmType = arm9Section[0x51] != 0xFF;
|
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
|
//Decrypt ARM9Bin and patch ARM9 entrypoint to skip arm9loader
|
||||||
arm9Loader(arm9Section, nativeFirmType);
|
arm9Loader(arm9Section, nativeFirmType);
|
||||||
@ -325,8 +336,8 @@ static inline void patchNativeFirm(u32 nandType, u32 emuHeader, u32 a9lhMode)
|
|||||||
*unitInfoOffset = unitInfoPatch;
|
*unitInfoOffset = unitInfoPatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Replace the FIRM loader with the injector
|
//Replace the FIRM loader with the injector while copying section0
|
||||||
injectLoader();
|
copySection0AndInjectLoader();
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void patchEmuNAND(u8 *arm9Section, u8 *proc9Offset, u32 emuHeader)
|
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;
|
*pos_fopen = fOpenOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void injectLoader(void)
|
static inline void copySection0AndInjectLoader(void)
|
||||||
{
|
{
|
||||||
u32 loaderSize;
|
u32 loaderSize;
|
||||||
|
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);
|
||||||
|
|
||||||
void *loaderOffset = getLoader((u8 *)firm + section[0].offset, section[0].size, &loaderSize);
|
memcpy(section[0].address, arm11Section0, injectorOffset);
|
||||||
|
memcpy(section[0].address + injectorOffset, injector, injector_size);
|
||||||
//Check that the injector CXI isn't larger than the original
|
memcpy(section[0].address + injectorOffset + injector_size, arm11Section0 + section[0].size - remaining, remaining);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void patchLegacyFirm(u32 firmType)
|
static inline void patchLegacyFirm(u32 firmType)
|
||||||
@ -483,7 +489,7 @@ static void patchFirmWrites(u8 *arm9Section, u32 mode)
|
|||||||
static inline void launchFirm(u32 bootType)
|
static inline void launchFirm(u32 bootType)
|
||||||
{
|
{
|
||||||
//Copy FIRM sections to respective memory locations
|
//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);
|
memcpy(section[i].address, (u8 *)firm + section[i].offset, section[i].size);
|
||||||
|
|
||||||
//Determine the ARM11 entry to use
|
//Determine the ARM11 entry to use
|
||||||
|
@ -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 patchNativeFirm(u32 nandType, u32 emuHeader, u32 a9lhMode);
|
||||||
static inline void patchEmuNAND(u8 *arm9Section, u8 *proc9Offset, u32 emuHeader);
|
static inline void patchEmuNAND(u8 *arm9Section, u8 *proc9Offset, u32 emuHeader);
|
||||||
static inline void patchReboots(u8 *arm9Section, u8 *proc9Offset);
|
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 patchLegacyFirm(u32 firmType);
|
||||||
static inline void patchSafeFirm(void);
|
static inline void patchSafeFirm(void);
|
||||||
static void patchFirmWrites(u8 *arm9Section, u32 mode);
|
static void patchFirmWrites(u8 *arm9Section, u32 mode);
|
||||||
|
@ -84,9 +84,16 @@ u8 *getUnitInfoValueSet(u8 *pos, u32 size)
|
|||||||
|
|
||||||
void *getLoader(u8 *pos, u32 size, u32 *loaderSize)
|
void *getLoader(u8 *pos, u32 size, u32 *loaderSize)
|
||||||
{
|
{
|
||||||
u8 *const off = memsearch(pos, "loade", size, 5);
|
u8 *off = pos;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if(*(u32 *)(off + 0x200) == 0x64616F6C) break; //"load"
|
||||||
|
off += *(u32 *)(off + 0x104) * 0x200; //size of the CXI
|
||||||
|
}
|
||||||
|
while(off < pos + size);
|
||||||
|
|
||||||
*loaderSize = *(u32 *)(off - 0xFC) * 0x200;
|
if(off >= pos + size) return NULL;
|
||||||
|
|
||||||
return off - 0x200;
|
*loaderSize = *(u32 *)(off + 0x104) * 0x200;
|
||||||
|
return off;
|
||||||
}
|
}
|
Reference in New Issue
Block a user