9.6+ emunand!

This commit is contained in:
Reisyukaku 2016-01-13 15:16:03 -05:00
parent b914674325
commit 1f0a8f692a
10 changed files with 210 additions and 210 deletions

View File

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

View File

@ -1,155 +1,50 @@
.nds
sdmmc equ 0x80D86F0
sdmmc_unk1 equ 0x080788C0
aes_unk equ 0x0805F9E4
aes_setkey equ 0x08057458
sdmmc_unk2 equ 0x080786A0
sdmmc_unk0 equ 0x08062890
sdmmc equ 0x080D86F0
.create "emunand.bin", 0x0801A4C0
.org 0x0801A4C0
.arm
EMU_WRITE:
stmfd sp!, {r0-r3}
mov r3, r0
ldr r1, =orig_sector
ldr r2, [r3,#4]
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_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
nand_sd:
; Original code that still needs to be executed.
mov r4, r0
mov r5, r1
mov r7, r2
mov r6, r3
; End.
EMU_READ:
stmfd sp!, {r0-r3}
mov r3, r0
ldr r1, =orig_sector
ldr r2, [r3,#4]
str r2, [r1,#4]
ldr r0, =sdmmc
cmp r2, r0
ldr r2, [r3,#8]
str r2, [r1]
beq @@orig_code
; If we're already trying to access the SD, return.
ldr r2, [r0, #4]
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
cmp r2, r1
beq nand_sd_ret
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
orig_sector: .word 0x00000000
orig_ptr: .word 0x00000000
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: .word 0x1D7800
;ncsd_header_offset: .word 0x1DD000
slot0x25keyX:
.word 0xABD8E7CE
.word 0xAE0DC030
.word 0xE3F50E85
.word 0xF35AAC82
.close

View File

@ -60,7 +60,6 @@ __asm__\
void aes_setkey(u8 keyslot, const void* key, u32 keyType, u32 mode)
{
if(keyslot <= 0x03) return; // Ignore TWL keys for now
u32* key32 = (u32*)key;
*REG_AESCNT = (*REG_AESCNT & ~(AES_CNT_INPUT_ENDIAN | AES_CNT_INPUT_ORDER)) | mode;
*REG_AESKEYCNT = (*REG_AESKEYCNT >> 6 << 6) | keyslot | AES_KEYCNT_WRITE;
@ -376,20 +375,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);
}
//Decrypt the arm9 binary on N3DS firm
void decryptArm9Bin(void *armHdr, u32 kversion){
//Emulates the Arm9loader process
//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 keyY[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(CTR, armHdr+0x20, 0x10);
u32 size = atoi(armHdr+0x30);
if(kversion >= 0x0F){
if(kversion >= 0x18) aes_setkey(0x11, key2, AES_KEYNORMAL, AES_INPUT_BE | AES_INPUT_NORMAL);
aes_use_keyslot(0x11);
if(kversion == 0x0F){
aes(keyX, armHdr+0x60, 1, NULL, AES_ECB_DECRYPT_MODE, 0);
aes_setkey(slot, keyX, AES_KEYX, AES_INPUT_BE | AES_INPUT_NORMAL);
}
@ -400,3 +405,65 @@ void decryptArm9Bin(void *armHdr, u32 kversion){
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, keyX19, AES_KEYX, AES_INPUT_BE | AES_INPUT_NORMAL);
aes_setkey(0x1D, keyX19, AES_KEYX, AES_INPUT_BE | AES_INPUT_NORMAL);
aes_setkey(0x1E, keyX19, AES_KEYX, AES_INPUT_BE | AES_INPUT_NORMAL);
aes_setkey(0x1F, keyX19, 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];
u8 keys[7][0x10];
aes_use_keyslot(0x11);
int i; for(i = 0; i < 7; i++) {
aes(keyTemp, encryptedData2, 1, NULL, AES_ECB_DECRYPT_MODE, 0);
encryptedData2[0x0F]++;
memcpy(keys[i], keyTemp, 0x10);
}
aes_setkey(0x19, keys[0], AES_KEYX, AES_INPUT_BE | AES_INPUT_NORMAL);
aes_setkey(0x1A, keys[1], AES_KEYX, AES_INPUT_BE | AES_INPUT_NORMAL);
aes_setkey(0x1B, keys[2], AES_KEYX, AES_INPUT_BE | AES_INPUT_NORMAL);
aes_setkey(0x1C, keys[3], AES_KEYX, AES_INPUT_BE | AES_INPUT_NORMAL);
aes_setkey(0x1D, keys[4], AES_KEYX, AES_INPUT_BE | AES_INPUT_NORMAL);
aes_setkey(0x1E, keys[5], AES_KEYX, AES_INPUT_BE | AES_INPUT_NORMAL);
aes_setkey(0x1F, keys[6], AES_KEYX, AES_INPUT_BE | AES_INPUT_NORMAL);*/
}
}

View File

@ -133,6 +133,7 @@ int rsa_verify(const void* data, u32 size, const void* sig, u32 mode);
//NAND/FIRM stuff
void getNandCTR(u8 *buf);
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*/

View File

@ -26,14 +26,15 @@ void loadFirm(int mode){
nandFirm0((u8*)firmLocation, firmSize);
section = firmLocation->section;
kversion = 0x04; //TODO: make this not hard coded
decryptArm9Bin((u8*)firmLocation + section[2].offset, kversion);
arm9loader((u8*)firmLocation + section[2].offset, kversion);
}
//Emunand mode
else{
//Read FIRM from SD card and write to FCRAM
fileRead((u8*)firmLocation, "/rei/firmware.bin", firmSize);
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();
}
}
@ -42,7 +43,7 @@ void loadFirm(int mode){
void loadEmu(void){
//Read emunand code from SD
u32 code = emuCode();
u32 code = emuCode(kversion);
fileRead((u8*)code, "/rei/emunand/emunand.bin", 0);
u32 *pos_offset = memsearch((u8*)code, "NAND", 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);
//Add emunand hooks
memcpy((u8*)emuHook(1), eh1, sizeof(eh1));
memcpy((u8*)emuHook(2), eh2, sizeof(eh2));
memcpy((u8*)emuHook(3), eh3, sizeof(eh3));
memcpy((u8*)emuHook(1, kversion), nandRedir, sizeof(nandRedir));
memcpy((u8*)emuHook(2, kversion), nandRedir, sizeof(nandRedir));
}
//Patches
@ -62,12 +62,12 @@ void patchFirm(){
memcpy((u8*)mpuCode(kversion), mpu, sizeof(mpu));
//Part2: Disable signature checks
memcpy((u8*)sigPatch(1, kversion), p1, sizeof(p1));
memcpy((u8*)sigPatch(2, kversion), p2, sizeof(p2));
memcpy((u8*)sigPatch(1, kversion), sigPat1, sizeof(sigPat1));
memcpy((u8*)sigPatch(2, kversion), sigPat2, sizeof(sigPat2));
//Part3: Create arm9 thread
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(2, kversion), th2, sizeof(th2));
}
@ -109,6 +109,9 @@ void launchFirm(void){
memcpy(section[2].address, (u8*)firmLocation + section[2].offset, section[2].size);
*(u32 *)0x1FFFFFF8 = (u32)firmLocation->arm11Entry;
setKeys(kversion);
//Final jump to arm9 binary
((void (*)())0x801B01C)();
//((void (*)())firmLocation->arm9Entry)();
}

View File

@ -7,8 +7,10 @@
#include "patches.h"
#define FIRM 0x24000000
#define KERNEL9 (FIRM + 0x66A00)
#define PROC9 (FIRM + 0x7D700)
#define v9_6_Offset 0x1600
#define K9_ADDR 0x08006000
#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,
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,
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
u8 nandRedir[0x08] = {0x00, 0x4C, 0xA0, 0x47, 0xC0, 0xA4, 0x01, 0x08}; //Branch to emunand function
/*
* Sig checks
*/
u8 p1[2] = {0x00, 0x20};
u8 p2[4] = {0x00, 0x20, 0x70, 0x47};
u8 sigPat1[2] = {0x00, 0x20};
u8 sigPat2[4] = {0x00, 0x20, 0x70, 0x47};
/*
* Arm9 thread
*/
u8 th1[4] = {0x2C, 0xF0, 0x9F, 0xE5}; //ldr pc, =0x080860E4
u8 th2[4] = {0xE0, 0xA6, 0x01, 0x08}; //0x080860E4
u8 th1[4] = {0x2C, 0xF0, 0x9F, 0xE5}; //ldr pc, =0x0801A6E0
u8 th2[4] = {0xE0, 0xA6, 0x01, 0x08}; //0x0801A6E0
@ -50,10 +48,38 @@ u8 th2[4] = {0xE0, 0xA6, 0x01, 0x08}; //0x080860E4
* Functions
**************************************************/
u32 emuCode(void){ //0F only
return KERNEL9 + (0x0801A4C0 - K9_ADDR);
//Where the emunand code is stored in firm
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 ret = NULL;
switch(kver){
@ -62,22 +88,14 @@ u32 mpuCode(u32 kver){
case 0x0F:
ret = KERNEL9 + (0x0801B3D4 - K9_ADDR);
break;
}
return ret;
}
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 + (0x0801B3D4 - K9_ADDR);
break;
}
return ret;
}
//Offsets to redirect to thread code
u32 threadHook(u8 val, u32 kver){
u32 ret = NULL;
switch(kver){
@ -94,24 +112,38 @@ u32 threadHook(u8 val, u32 kver){
PROC9 + (0x080860B0 - P9_ADDR) :
PROC9 + (0x080860E4 - P9_ADDR);
break;
case 0x18:
ret = val == 1 ?
PROC9 + v9_6_Offset + (0x08086140 - P9_ADDR) :
PROC9 + v9_6_Offset + (0x08086174 - P9_ADDR);
break;
}
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;
if(val == 1){
ret = PROC9 + (0x080282F8 - P9_ADDR);
}
else if(val == 2){
ret = PROC9 + (0x0807877E - P9_ADDR);
}
else if(val == 3){
ret = PROC9 + (0x080787BE - P9_ADDR);
switch(kver){
case 0x04:
//???
break;
case 0x0C:
//???
break;
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;
}
//Offsets to redirect to thread code
u32 sigPatch(u8 val, u32 kver){
u32 ret = NULL;
switch(kver){
@ -130,6 +162,11 @@ u32 sigPatch(u8 val, u32 kver){
PROC9 + (0x08063374 - P9_ADDR) :
PROC9 + (0x0805D498 - P9_ADDR);
break;
case 0x18:
ret = val == 1 ?
PROC9 + v9_6_Offset + (0x080632B8 - P9_ADDR) :
PROC9 + v9_6_Offset + (0x0805D628 - P9_ADDR);
break;
}
return ret;
}

View File

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

View File

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

View File

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

View File

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