9.6+ emunand!

This commit is contained in:
Reisyukaku 2016-01-13 15:16:03 -05:00
parent b914674325
commit 475ddf8b6a
10 changed files with 228 additions and 209 deletions

View File

@ -1,5 +1,5 @@
# ReiNand # ReiNand
3DS CFW for N3DS The original open source N3DS CFW!
**Compiling:** **Compiling:**

View File

@ -1,155 +1,50 @@
.nds .nds
sdmmc equ 0x80D86F0 sdmmc equ 0x080D86F0
sdmmc_unk1 equ 0x080788C0
aes_unk equ 0x0805F9E4
aes_setkey equ 0x08057458
sdmmc_unk2 equ 0x080786A0
sdmmc_unk0 equ 0x08062890
.create "emunand.bin", 0x0801A4C0 .create "emunand.bin", 0x0801A4C0
.org 0x0801A4C0 .org 0x0801A4C0
.arm .arm
EMU_WRITE: nand_sd:
stmfd sp!, {r0-r3} ; Original code that still needs to be executed.
mov r3, r0 mov r4, r0
ldr r1, =orig_sector mov r5, r1
ldr r2, [r3,#4] mov r7, r2
str r2, [r1,#4] mov r6, r3
ldr r0, =sdmmc ; End.
cmp r2, r0
ldr r2, [r3,#8]
str r2, [r1]
beq @@orig_code
ldr r1, =sdmmc
str r1, [r3,#4]
cmp r2, #0
ldr r0, =nand_offset
ldrne r0, [r0]
addne r0, r2
ldreq r0, [r0, #(ncsd_header_offset - nand_offset)]
str r0, [r3,#8]
@@orig_code:
ldmfd sp!, {r0-r3}
movs r4, r0
movs r5, r1
movs r7, r2
movs r6, r3
movs r0, r1, lsl#23
beq loc_801a534
stmfd sp!, {r4}
ldr r4, =(sdmmc_unk0 + 1)
blx r4
ldmfd sp!, {r4}
loc_801a534:
ldr r0, [r4,#4]
ldr r1, [r0]
ldr r1, [r1,#0x18]
blx r1
ldr r1, [r4,#4]
movs r3, r0
ldr r0, [r1,#0x20]
movs r2, r5, lsr#9
mov r12, r0
ldr r0, [r4,#8]
str r7, [sp,#4]
adds r0, r0, r2
cmp r1, #0
str r6, [sp,#8]
str r0, [sp]
beq loc_801a578
adds r1, r1, #8
loc_801a578:
movs r2, r4
adds r2, r2, #0xc
mov r0, r12
ldr r5, =(sdmmc_unk1 + 1) ; called by the original function
blx r5
stmfd sp!, {r0-r3}
ldr r2, =orig_sector
ldr r1, [r2]
str r1, [r4,#8]
ldr r1, [r2,#4]
str r1, [r4,#4]
ldmfd sp!, {r0-r3}
ldmfd sp!, {r1-r7,lr}
bx lr
EMU_READ: ; If we're already trying to access the SD, return.
stmfd sp!, {r0-r3} ldr r2, [r0, #4]
mov r3, r0 ldr r1, =sdmmc
ldr r1, =orig_sector cmp r2, r1
ldr r2, [r3,#4] beq nand_sd_ret
str r2, [r1,#4]
ldr r0, =sdmmc
cmp r2, r0
ldr r2, [r3,#8]
str r2, [r1]
beq @@orig_code
ldr r1, =sdmmc
str r1, [r3,#4]
cmp r2, #0
ldr r0, =nand_offset
ldrne r0, [r0]
addne r0, r2
ldreq r0, [r0, #(ncsd_header_offset - nand_offset)]
str r0, [r3,#8]
@@orig_code:
ldmfd sp!, {r0-r3}
movs r4, r0
movs r5, r1
movs r7, r2
movs r6, r3
movs r0, r1, lsl#23
beq loc_801a624
stmfd sp!, {r4}
ldr r4, =(sdmmc_unk0 + 1)
blx r4
ldmfd sp!, {r4}
loc_801a624:
ldr r0, [r4,#4]
ldr r1, [r0]
ldr r1, [r1,#0x18]
blx r1
ldr r1, [r4,#4]
movs r3, r0
ldr r0, [r1,#0x20]
movs r2, r5, lsr#9
mov r12, r0
ldr r0, [r4,#8]
str r7, [sp,#4]
adds r0, r0, r2
cmp r1, #0
str r6, [sp,#8]
str r0, [sp]
beq loc_801a668
adds r1, r1, #8
loc_801a668:
movs r2, r4
adds r2, r2, #0xC
mov r0, r12
ldr r5, =(sdmmc_unk2 + 1)
blx r5
stmfd sp!, {r0-r3}
ldr r2, =orig_sector
ldr r1, [r2]
str r1, [r4,#8]
ldr r1, [r2,#4]
str r1, [r4,#4]
ldmfd sp!, {r0-r3}
ldmfd sp!, {r1-r7,lr}
bx lr
str r1, [r0, #4] ; Set object to be SD
ldr r2, [r0, #8] ; Get sector to read
cmp r2, #0 ; For GW compatibility, see if we're trying to read the ncsd header (sector 0)
ldr r3, =nand_offset
ldr r3, [r3]
add r2, r3 ; Add the offset to the NAND in the SD.
ldreq r3, =ncsd_header_offset
ldreq r3, [r3]
addeq r2, r3 ; If we're reading the ncsd header, add the offset of that sector.
str r2, [r0, #8] ; Store sector to read
nand_sd_ret:
; Restore registers.
mov r1, r5
mov r2, r7
mov r3, r6
; Return 4 bytes behind where we got called,
; due to the offset of this function being stored there.
mov r0, lr
add r0, #4
bx r0
.pool .pool
orig_sector: .word 0x00000000
orig_ptr: .word 0x00000000
nand_offset: .ascii "NAND" ; for rednand this should be 1 nand_offset: .ascii "NAND" ; for rednand this should be 1
ncsd_header_offset: .ascii "NCSD" ; depends on nand manufacturer + emunand type (GW/RED) ncsd_header_offset: .ascii "NCSD" ; depends on nand manufacturer + emunand type (GW/RED)
;ncsd_header_offset: .word 0x1D7800
;ncsd_header_offset: .word 0x1DD000
slot0x25keyX:
.word 0xABD8E7CE
.word 0xAE0DC030
.word 0xE3F50E85
.word 0xF35AAC82
.close .close

View File

@ -376,20 +376,26 @@ void nandFirm0(u8 *outbuf, const u32 size){
aes(outbuf, outbuf, size / AES_BLOCK_SIZE, CTR, AES_CTR_MODE, AES_INPUT_BE | AES_INPUT_NORMAL); aes(outbuf, outbuf, size / AES_BLOCK_SIZE, CTR, AES_CTR_MODE, AES_INPUT_BE | AES_INPUT_NORMAL);
} }
//Decrypt the arm9 binary on N3DS firm //Emulates the Arm9loader process
void decryptArm9Bin(void *armHdr, u32 kversion){ //9.5.0 = 0x0F
//9.6.0 = 0x18
void arm9loader(void *armHdr, u32 kversion){
//Set Nand key#2 here (decrypted from 0x12C10)
u8 key2[0x10] = {0x42, 0x3F, 0x81, 0x7A, 0x23, 0x52, 0x58, 0x31, 0x6E, 0x75, 0x8E, 0x3A, 0x39, 0x43, 0x2E, 0xD0};
u8 keyX[0x10]; u8 keyX[0x10];
u8 keyY[0x10]; u8 keyY[0x10];
u8 CTR[0x10]; u8 CTR[0x10];
u32 slot = (kversion == 0x0F ? 0x16 : 0x15); u32 slot = (kversion >= 0x0F ? 0x16 : 0x15);
//Setupkeys needed for arm9bin decryption
memcpy(keyY, armHdr+0x10, 0x10); memcpy(keyY, armHdr+0x10, 0x10);
memcpy(CTR, armHdr+0x20, 0x10); memcpy(CTR, armHdr+0x20, 0x10);
u32 size = atoi(armHdr+0x30); u32 size = atoi(armHdr+0x30);
aes_use_keyslot(0x11); if(kversion >= 0x0F){
if(kversion >= 0x18) aes_setkey(0x11, key2, AES_KEYNORMAL, AES_INPUT_BE | AES_INPUT_NORMAL);
if(kversion == 0x0F){ aes_use_keyslot(0x11);
aes(keyX, armHdr+0x60, 1, NULL, AES_ECB_DECRYPT_MODE, 0); aes(keyX, armHdr+0x60, 1, NULL, AES_ECB_DECRYPT_MODE, 0);
aes_setkey(slot, keyX, AES_KEYX, AES_INPUT_BE | AES_INPUT_NORMAL); aes_setkey(slot, keyX, AES_KEYX, AES_INPUT_BE | AES_INPUT_NORMAL);
} }
@ -399,4 +405,84 @@ void decryptArm9Bin(void *armHdr, u32 kversion){
aes_use_keyslot(slot); aes_use_keyslot(slot);
aes(armHdr+0x800, armHdr+0x800, size/AES_BLOCK_SIZE, CTR, AES_CTR_MODE, AES_INPUT_BE | AES_INPUT_NORMAL); aes(armHdr+0x800, armHdr+0x800, size/AES_BLOCK_SIZE, CTR, AES_CTR_MODE, AES_INPUT_BE | AES_INPUT_NORMAL);
}
void setKeys(kversion){
u8 key2[0x10] = {0x42, 0x3F, 0x81, 0x7A, 0x23, 0x52, 0x58, 0x31, 0x6E, 0x75, 0x8E, 0x3A, 0x39, 0x43, 0x2E, 0xD0};
//Initialze keys
if(kversion >= 0x18){
u8 keyX18[16] = {
0x82, 0xE9, 0xC9, 0xBE, 0xBF, 0xB8, 0xBD, 0xB8, 0x75, 0xEC, 0xC0, 0xA0,
0x7D, 0x47, 0x43, 0x74
};
u8 keyX19[16] = {
0xF5, 0x36, 0x7F, 0xCE, 0x73, 0x14, 0x2E, 0x66, 0xED, 0x13, 0x91, 0x79,
0x14, 0xB7, 0xF2, 0xEF
};
u8 keyX1A[16] = {
0xEA, 0xBA, 0x98, 0x4C, 0x9C, 0xB7, 0x66, 0xD4, 0xA3, 0xA7, 0xE9, 0x74,
0xE2, 0xE7, 0x13, 0xA3
};
u8 keyX1B[16] = {
0x45, 0xAD, 0x04, 0x95, 0x39, 0x92, 0xC7, 0xC8, 0x93, 0x72, 0x4A, 0x9A,
0x7B, 0xCE, 0x61, 0x82
};
u8 keyX1C[16] = {
0xC3, 0x83, 0x0F, 0x81, 0x56, 0xE3, 0x54, 0x3B, 0x72, 0x3F, 0x0B, 0xC0,
0x46, 0x74, 0x1E, 0x8F
};
u8 keyX1D[16] = {
0xD6, 0xB3, 0x8B, 0xC7, 0x59, 0x41, 0x75, 0x96, 0xD6, 0x19, 0xD6, 0x02,
0x9D, 0x13, 0xE0, 0xD8
};
u8 keyX1E[16] = {
0xBB, 0x62, 0x3A, 0x97, 0xDD, 0xD7, 0x93, 0xD7, 0x57, 0xC4, 0x10, 0x4B,
0x8D, 0x9F, 0xB9, 0x69
};
u8 keyX1F[16] = {
0x4C, 0x28, 0xEC, 0x6E, 0xFF, 0xA3, 0xC2, 0x36, 0x46, 0x07, 0x8B, 0xBA,
0x35, 0x0C, 0x79, 0x95
};
aes_setkey(0x18, keyX18, AES_KEYX, AES_INPUT_BE | AES_INPUT_NORMAL);
aes_setkey(0x19, keyX19, AES_KEYX, AES_INPUT_BE | AES_INPUT_NORMAL);
aes_setkey(0x1A, keyX19, AES_KEYX, AES_INPUT_BE | AES_INPUT_NORMAL);
aes_setkey(0x1B, keyX1B, AES_KEYX, AES_INPUT_BE | AES_INPUT_NORMAL);
aes_setkey(0x1C, keyX1C, AES_KEYX, AES_INPUT_BE | AES_INPUT_NORMAL);
aes_setkey(0x1D, keyX1D, AES_KEYX, AES_INPUT_BE | AES_INPUT_NORMAL);
aes_setkey(0x1E, keyX1E, AES_KEYX, AES_INPUT_BE | AES_INPUT_NORMAL);
aes_setkey(0x1F, keyX1F, AES_KEYX, AES_INPUT_BE | AES_INPUT_NORMAL);
/*
//data at armHdr+0x8A804 (its not in FCRAM for whatever reason)
u8 encryptedData1[0x10] = {
0xA4, 0x8D, 0xE4, 0xF1, 0x0B, 0x36, 0x44, 0xAA, 0x90, 0x31, 0x28, 0xFF,
0x4D, 0xCA, 0x76, 0xDF
};
//data at armHdr+0x8A814 (its not in FCRAM for whatever reason)
u8 encryptedData2[0x10] = {
0xDD, 0xDA, 0xA4, 0xC6, 0x2C, 0xC4, 0x50, 0xE9, 0xDA, 0xB6, 0x9B, 0x0D,
0x9D, 0x2A, 0x21, 0x98
};
//Set key 0x18 keyX
u8 keyX18[0x10];
aes(keyX18, encryptedData1, 1, NULL, AES_ECB_DECRYPT_MODE, 0);
aes_setkey(0x18, keyX18, AES_KEYX, AES_INPUT_BE | AES_INPUT_NORMAL);
//Set key 0x11 normalkey
aes_setkey(0x11, key2, AES_KEYNORMAL, AES_INPUT_BE | AES_INPUT_NORMAL);
aes_use_keyslot(0x11);
//Set keys 0x19..0x1F keyXs
u8 keyTemp[0x10];
aes_use_keyslot(0x11);
int i; for(i = 0; i < 7; i++) {
aes(keyTemp, encryptedData2, 1, NULL, AES_ECB_DECRYPT_MODE, 0);
aes_setkey(0x19 + i, keyTemp, AES_KEYX, AES_INPUT_BE | AES_INPUT_NORMAL);
encryptedData2[0x0F]++;
}*/
}
} }

View File

@ -133,6 +133,7 @@ int rsa_verify(const void* data, u32 size, const void* sig, u32 mode);
//NAND/FIRM stuff //NAND/FIRM stuff
void getNandCTR(u8 *buf); void getNandCTR(u8 *buf);
void nandFirm0(u8 *outbuf, const u32 size); void nandFirm0(u8 *outbuf, const u32 size);
void decryptArm9Bin(void *armHdr, u32 kversion); void arm9loader(void *armHdr, u32 kversion);
void setKeys(kversion);
#endif /*__CRYPTO_H*/ #endif /*__CRYPTO_H*/

View File

@ -26,14 +26,15 @@ void loadFirm(int mode){
nandFirm0((u8*)firmLocation, firmSize); nandFirm0((u8*)firmLocation, firmSize);
section = firmLocation->section; section = firmLocation->section;
kversion = 0x04; //TODO: make this not hard coded kversion = 0x04; //TODO: make this not hard coded
decryptArm9Bin((u8*)firmLocation + section[2].offset, kversion); arm9loader((u8*)firmLocation + section[2].offset, kversion);
} }
//Emunand mode //Emunand mode
else{ else{
//Read FIRM from SD card and write to FCRAM //Read FIRM from SD card and write to FCRAM
fileRead((u8*)firmLocation, "/rei/firmware.bin", firmSize); fileRead((u8*)firmLocation, "/rei/firmware.bin", firmSize);
section = firmLocation->section; section = firmLocation->section;
kversion = 0x0F; //TODO: make this not hard coded kversion = 0x18; //TODO: make this not hard coded
arm9loader((u8*)firmLocation + section[2].offset, kversion);
loadEmu(); loadEmu();
} }
} }
@ -42,7 +43,7 @@ void loadFirm(int mode){
void loadEmu(void){ void loadEmu(void){
//Read emunand code from SD //Read emunand code from SD
u32 code = emuCode(); u32 code = emuCode(kversion);
fileRead((u8*)code, "/rei/emunand/emunand.bin", 0); fileRead((u8*)code, "/rei/emunand/emunand.bin", 0);
u32 *pos_offset = memsearch((u8*)code, "NAND", 0x218, 4); u32 *pos_offset = memsearch((u8*)code, "NAND", 0x218, 4);
u32 *pos_header = memsearch((u8*)code, "NCSD", 0x218, 4); u32 *pos_header = memsearch((u8*)code, "NCSD", 0x218, 4);
@ -50,9 +51,8 @@ void loadEmu(void){
memcpy((void *)pos_header, (void *)emuHeader, 4); memcpy((void *)pos_header, (void *)emuHeader, 4);
//Add emunand hooks //Add emunand hooks
memcpy((u8*)emuHook(1), eh1, sizeof(eh1)); memcpy((u8*)emuHook(1, kversion), nandRedir, sizeof(nandRedir));
memcpy((u8*)emuHook(2), eh2, sizeof(eh2)); memcpy((u8*)emuHook(2, kversion), nandRedir, sizeof(nandRedir));
memcpy((u8*)emuHook(3), eh3, sizeof(eh3));
} }
//Patches //Patches
@ -62,12 +62,12 @@ void patchFirm(){
memcpy((u8*)mpuCode(kversion), mpu, sizeof(mpu)); memcpy((u8*)mpuCode(kversion), mpu, sizeof(mpu));
//Part2: Disable signature checks //Part2: Disable signature checks
memcpy((u8*)sigPatch(1, kversion), p1, sizeof(p1)); memcpy((u8*)sigPatch(1, kversion), sigPat1, sizeof(sigPat1));
memcpy((u8*)sigPatch(2, kversion), p2, sizeof(p2)); memcpy((u8*)sigPatch(2, kversion), sigPat2, sizeof(sigPat2));
//Part3: Create arm9 thread //Part3: Create arm9 thread
fileRead((u8*)threadCode(kversion), "/rei/thread/arm9.bin", 0); fileRead((u8*)threadCode(kversion), "/rei/thread/arm9.bin", 0);
if(kversion == 0x0F){ //TODO: 0F only untill i can figure out why the hell this doesnt work on sysnand anymore. if(kversion == 0x18){ //TODO: 0x18 only untill i can figure out why the hell this doesnt work on sysnand anymore.
memcpy((u8*)threadHook(1, kversion), th1, sizeof(th1)); memcpy((u8*)threadHook(1, kversion), th1, sizeof(th1));
memcpy((u8*)threadHook(2, kversion), th2, sizeof(th2)); memcpy((u8*)threadHook(2, kversion), th2, sizeof(th2));
} }
@ -108,7 +108,10 @@ void launchFirm(void){
memcpy(section[1].address, (u8*)firmLocation + section[1].offset, section[1].size); memcpy(section[1].address, (u8*)firmLocation + section[1].offset, section[1].size);
memcpy(section[2].address, (u8*)firmLocation + section[2].offset, section[2].size); memcpy(section[2].address, (u8*)firmLocation + section[2].offset, section[2].size);
*(u32 *)0x1FFFFFF8 = (u32)firmLocation->arm11Entry; *(u32 *)0x1FFFFFF8 = (u32)firmLocation->arm11Entry;
setKeys(kversion);
//Final jump to arm9 binary //Final jump to arm9 binary
((void (*)())0x801B01C)(); ((void (*)())0x801B01C)();
//((void (*)())firmLocation->arm9Entry)();
} }

View File

@ -7,8 +7,10 @@
#include "patches.h" #include "patches.h"
#define FIRM 0x24000000 #define FIRM 0x24000000
#define KERNEL9 (FIRM + 0x66A00) #define KERNEL9 (FIRM + 0x66A00)
#define PROC9 (FIRM + 0x7D700) #define PROC9 (FIRM + 0x7D700)
#define v9_6_Offset 0x1600
#define K9_ADDR 0x08006000 #define K9_ADDR 0x08006000
#define P9_ADDR 0x08028000 #define P9_ADDR 0x08028000
@ -25,24 +27,20 @@ u8 mpu[0x2C] = { //MPU shit
0x00, 0x00, 0x00, 0x20, 0x01, 0x01, 0x01, 0x01, 0x03, 0x06, 0x20, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x20, 0x01, 0x01, 0x01, 0x01, 0x03, 0x06, 0x20, 0x00, 0x00, 0x00, 0x00, 0x08,
0x01, 0x01, 0x01, 0x01, 0x03, 0x06, 0x1C, 0x00, 0x00, 0x00, 0x02, 0x08 0x01, 0x01, 0x01, 0x01, 0x03, 0x06, 0x1C, 0x00, 0x00, 0x00, 0x02, 0x08
}; };
u8 eh1[0x14] = { //Sets Slot0x25KeyX
0x03, 0x4A, 0x05, 0x21, 0x25, 0x20, 0x2F, 0xF0, 0xAB, 0xF8, 0x37, 0xF0, 0x6F, 0xFB, 0x70, 0xBD, u8 nandRedir[0x08] = {0x00, 0x4C, 0xA0, 0x47, 0xC0, 0xA4, 0x01, 0x08}; //Branch to emunand function
0xC8, 0xA6, 0x01, 0x08
};
u8 eh2[0x0A] = {0x01, 0x4C, 0x20, 0x47, 0x00, 0x00, 0xC0, 0xA4, 0x01, 0x08}; //Branch to emunand write function
u8 eh3[0x0A] = {0x01, 0x4C, 0x20, 0x47, 0x00, 0x00, 0xB0, 0xA5, 0x01, 0x08}; //Branch to emunand read function
/* /*
* Sig checks * Sig checks
*/ */
u8 p1[2] = {0x00, 0x20}; u8 sigPat1[2] = {0x00, 0x20};
u8 p2[4] = {0x00, 0x20, 0x70, 0x47}; u8 sigPat2[4] = {0x00, 0x20, 0x70, 0x47};
/* /*
* Arm9 thread * Arm9 thread
*/ */
u8 th1[4] = {0x2C, 0xF0, 0x9F, 0xE5}; //ldr pc, =0x080860E4 u8 th1[4] = {0x2C, 0xF0, 0x9F, 0xE5}; //ldr pc, =0x0801A6E0
u8 th2[4] = {0xE0, 0xA6, 0x01, 0x08}; //0x080860E4 u8 th2[4] = {0xE0, 0xA6, 0x01, 0x08}; //0x0801A6E0
@ -50,10 +48,38 @@ u8 th2[4] = {0xE0, 0xA6, 0x01, 0x08}; //0x080860E4
* Functions * Functions
**************************************************/ **************************************************/
u32 emuCode(void){ //0F only //Where the emunand code is stored in firm
return KERNEL9 + (0x0801A4C0 - K9_ADDR); u32 emuCode(u32 kver){
u32 ret = NULL;
switch(kver){
case 0x04:
case 0x0C:
case 0x0F:
ret = KERNEL9 + (0x0801A4C0 - K9_ADDR);
break;
case 0x18:
ret = KERNEL9 + v9_6_Offset + (0x0801A4C0 - K9_ADDR);
break;
}
return ret;
} }
//Where thread code is stored in firm
u32 threadCode(u32 kver){
u32 ret = NULL;
switch(kver){
case 0x04:
case 0x0C:
case 0x0F:
ret = KERNEL9 + (0x0801A6E0 - K9_ADDR);
case 0x18:
ret = KERNEL9 + v9_6_Offset + (0x0801A6E0 - K9_ADDR);
break;
}
return ret;
}
//Area of MPU setting code
u32 mpuCode(u32 kver){ u32 mpuCode(u32 kver){
u32 ret = NULL; u32 ret = NULL;
switch(kver){ switch(kver){
@ -62,22 +88,14 @@ u32 mpuCode(u32 kver){
case 0x0F: case 0x0F:
ret = KERNEL9 + (0x0801B3D4 - K9_ADDR); ret = KERNEL9 + (0x0801B3D4 - K9_ADDR);
break; break;
} case 0x18:
return ret; ret = KERNEL9 + v9_6_Offset + (0x0801B3D4 - K9_ADDR);
}
u32 threadCode(u32 kver){
u32 ret = NULL;
switch(kver){
case 0x04:
case 0x0C:
case 0x0F:
ret = KERNEL9 + (0x0801A6E0 - K9_ADDR);
break; break;
} }
return ret; return ret;
} }
//Offsets to redirect to thread code
u32 threadHook(u8 val, u32 kver){ u32 threadHook(u8 val, u32 kver){
u32 ret = NULL; u32 ret = NULL;
switch(kver){ switch(kver){
@ -94,24 +112,38 @@ u32 threadHook(u8 val, u32 kver){
PROC9 + (0x080860B0 - P9_ADDR) : PROC9 + (0x080860B0 - P9_ADDR) :
PROC9 + (0x080860E4 - P9_ADDR); PROC9 + (0x080860E4 - P9_ADDR);
break; break;
case 0x18:
ret = val == 1 ?
PROC9 + v9_6_Offset + (0x08086140 - P9_ADDR) :
PROC9 + v9_6_Offset + (0x08086174 - P9_ADDR);
break;
} }
return ret; return ret;
} }
u32 emuHook(u8 val){ //0F only //Offsets to redirect to Emunand code
u32 emuHook(u8 val, u32 kver){ //latest only
u32 ret = NULL; u32 ret = NULL;
if(val == 1){ switch(kver){
ret = PROC9 + (0x080282F8 - P9_ADDR); case 0x04:
} //???
else if(val == 2){ break;
ret = PROC9 + (0x0807877E - P9_ADDR); case 0x0C:
} //???
else if(val == 3){ break;
ret = PROC9 + (0x080787BE - P9_ADDR); case 0x0F:
if(val == 1) ret = PROC9 + (0x0807882C - P9_ADDR);
else if(val == 2) ret = PROC9 + (0x0807886C - P9_ADDR);
break;
case 0x18:
if(val == 1) ret = PROC9 + v9_6_Offset + (0x0807882C - P9_ADDR);
else if(val == 2) ret = PROC9 + v9_6_Offset + (0x0807886C - P9_ADDR);
break;
} }
return ret; return ret;
} }
//Offsets to redirect to thread code
u32 sigPatch(u8 val, u32 kver){ u32 sigPatch(u8 val, u32 kver){
u32 ret = NULL; u32 ret = NULL;
switch(kver){ switch(kver){
@ -130,6 +162,11 @@ u32 sigPatch(u8 val, u32 kver){
PROC9 + (0x08063374 - P9_ADDR) : PROC9 + (0x08063374 - P9_ADDR) :
PROC9 + (0x0805D498 - P9_ADDR); PROC9 + (0x0805D498 - P9_ADDR);
break; break;
case 0x18:
ret = val == 1 ?
PROC9 + v9_6_Offset + (0x080632B8 - P9_ADDR) :
PROC9 + v9_6_Offset + (0x0805D628 - P9_ADDR);
break;
} }
return ret; return ret;
} }

View File

@ -11,23 +11,21 @@
/************************************************** /**************************************************
* Patches * Patches
**************************************************/ **************************************************/
u8 mpu[0x2C]; u8 mpu[0x2C];
u8 eh1[0x14]; u8 nandRedir[0x08];
u8 eh2[0x0A]; u8 sigPat1[2];
u8 eh3[0x0A]; u8 sigPat2[4];
u8 p1[2];
u8 p2[4];
u8 th1[4]; u8 th1[4];
u8 th2[4]; u8 th2[4];
/************************************************** /**************************************************
* Functions * Functions
**************************************************/ **************************************************/
u32 emuCode(void); u32 emuCode(u32 kver);
u32 mpuCode(u32 kver); u32 mpuCode(u32 kver);
u32 threadCode(u32 kver); u32 threadCode(u32 kver);
u32 threadHook(u8 val, u32 kver); u32 threadHook(u8 val, u32 kver);
u32 emuHook(u8 val); u32 emuHook(u8 val, u32 kver);
u32 sigPatch(u8 val, u32 kver); u32 sigPatch(u8 val, u32 kver);
#endif #endif

View File

@ -11,7 +11,7 @@
.type fopen9, %function .type fopen9, %function
fopen9: fopen9:
push {r0-r6, lr} push {r0-r6, lr}
ldr r4, =0x0805B015 ldr r4, =0x0805B181
blx r4 blx r4
pop {r0-r6, pc} pop {r0-r6, pc}
.pool .pool
@ -21,7 +21,7 @@
.type fwrite9, %function .type fwrite9, %function
fwrite9: fwrite9:
push {r4, lr} push {r4, lr}
ldr r4, =0x0805C379 ldr r4, =0x0805C4D1
blx r4 blx r4
pop {r4, pc} pop {r4, pc}
.pool .pool
@ -41,7 +41,7 @@
.type fclose9, %function .type fclose9, %function
fclose9: fclose9:
push {r4, lr} push {r4, lr}
ldr r4, =0x08053C6D ldr r4, =0x08053CF9
blx r4 blx r4
pop {r4, pc} pop {r4, pc}
.pool .pool
@ -51,7 +51,7 @@
.type fsize9, %function .type fsize9, %function
fsize9: fsize9:
push {r4, lr} push {r4, lr}
ldr r4, =0x0805C175 ldr r4, =0x0805C2CD
blx r4 blx r4
pop {r4, pc} pop {r4, pc}
.pool .pool

View File

@ -16,5 +16,5 @@ _start:
ldr r4, =0x1 ldr r4, =0x1
svc 0x8 svc 0x8
pop {r0-r12 , lr} pop {r0-r12 , lr}
ldr r0, =0x80CB0A8 ldr r0, =0x80CB028
ldr pc, =0x080860B4 ldr pc, =0x08086144

View File

@ -79,8 +79,7 @@ void thread(void){
screenShot(BOT_FRAME); screenShot(BOT_FRAME);
} }
if(isPressed(BUTTON_START | BUTTON_X)){ if(isPressed(BUTTON_START | BUTTON_X)){
memdump(L"sdmc:/AXIWRAM.bin", AXIWRAM, 0x00080000); memdump(L"sdmc:/BootRom.bin", 0xFFFF0000, 0x8000);
memdump(L"sdmc:/FCRAM.bin", FCRAM, 0x010000000);
} }
patches(); patches();
} }