Emunand self patching; found solution for some hard coded stuff/FS more flexible; got rid of screenShot; implemented PoC RAM dumper using txt file; changed location of arm9 thread; fixed ver string; tons of organization and cleaning up for easier to read and modify code.
This commit is contained in:
@@ -5,12 +5,13 @@
|
||||
*/
|
||||
|
||||
#include "emunand.h"
|
||||
#include "memory.h"
|
||||
#include "fatfs/ff.h"
|
||||
#include "fatfs/sdmmc/sdmmc.h"
|
||||
|
||||
static u8 *temp = (u8*)0x24300000;
|
||||
|
||||
void getEmunand(u32 *off, u32 *head){
|
||||
void getEmunandSect(u32 *off, u32 *head){
|
||||
u32 nandSize = getMMCDevice(0)->total_size;
|
||||
if (sdmmc_sdcard_readsectors(nandSize, 1, temp) == 0) {
|
||||
if (*(u32*)(temp + 0x100) == NCSD_MAGIC) {
|
||||
@@ -18,4 +19,30 @@ void getEmunand(u32 *off, u32 *head){
|
||||
*head = nandSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void getSDMMC(void *offset, u32 *off, u32 size){
|
||||
//Look for struct code
|
||||
unsigned char pattern[] = {0x01, 0x21, 0x20, 0x18, 0x20, 0x30};
|
||||
*off = memsearch(offset, pattern, size, 6);
|
||||
|
||||
//Get DCD values
|
||||
unsigned char buf[4];
|
||||
int p;
|
||||
u32 addr = 0;
|
||||
u32 additive = 0;
|
||||
memcpy((void*)buf, (void*)(*off+0x0A), 4);
|
||||
for (p = 0; p < 4; p++) addr |= ((u32) buf[p]) << (8 * p);
|
||||
memcpy((void*)buf, (void*)(*off+0x0E), 4);
|
||||
for (p = 0; p < 4; p++) additive |= ((u32) buf[p]) << (8 * p);
|
||||
|
||||
//Return result
|
||||
*off = addr + additive;
|
||||
}
|
||||
|
||||
void getEmuRW(void *pos, u32 size, u32 *readOff, u32 *writeOff){
|
||||
//Look for read/write code
|
||||
unsigned char pattern[] = {0x04, 0x00, 0x0D, 0x00, 0x17, 0x00, 0x1E, 0x00, 0xC8, 0x05};
|
||||
*writeOff = memsearch(pos, pattern, size, 10);
|
||||
*readOff = *writeOff - 0x40; //TODO: Maybe make memsearch work properly for this.
|
||||
}
|
||||
@@ -11,6 +11,8 @@
|
||||
|
||||
#define NCSD_MAGIC (0x4453434E)
|
||||
|
||||
void getEmunand(u32 *off, u32 *head);
|
||||
void getEmunandSect(u32 *off, u32 *head);
|
||||
void getSDMMC(void *offset, u32 *off, u32 size);
|
||||
void getEmuRW(void *pos, u32 size, u32 *readOff, u32 *writeOff);
|
||||
|
||||
#endif
|
||||
@@ -13,13 +13,19 @@
|
||||
|
||||
const firmHeader *firmLocation = (firmHeader *)0x24000000;
|
||||
firmSectionHeader *section;
|
||||
u32 emuOffset = 0;
|
||||
u32 emuHeader = 0;
|
||||
u32 emuOffset = 0,
|
||||
emuHeader = 0,
|
||||
emuRead = 0,
|
||||
emuWrite = 0,
|
||||
sdmmcOffset = 0,
|
||||
firmSize = 0;
|
||||
|
||||
//Load firm into FCRAM
|
||||
void loadFirm(void){
|
||||
//Read FIRM from SD card and write to FCRAM
|
||||
fileRead((u8*)firmLocation, "/rei/firmware.bin", 0);
|
||||
const char firmPath[] = "/rei/firmware.bin";
|
||||
firmSize = fileSize(firmPath);
|
||||
fileRead((u8*)firmLocation, firmPath, firmSize);
|
||||
section = firmLocation->section;
|
||||
arm9loader((u8*)firmLocation + section[2].offset);
|
||||
}
|
||||
@@ -29,31 +35,35 @@ void loadEmu(void){
|
||||
|
||||
//Read emunand code from SD
|
||||
u32 code = emuCode();
|
||||
fileRead(code, "/rei/emunand/emunand.bin", 0);
|
||||
u32 *pos_offset = memsearch(code, "NAND", 0x218, 4);
|
||||
u32 *pos_header = memsearch(code, "NCSD", 0x218, 4);
|
||||
getEmunand(&emuOffset, &emuHeader);
|
||||
if (pos_offset && pos_header) {
|
||||
*pos_offset = emuOffset;
|
||||
*pos_header = emuHeader;
|
||||
}
|
||||
|
||||
const char path[] = "/rei/emunand/emunand.bin";
|
||||
u32 size = fileSize(path);
|
||||
fileRead(code, path, size);
|
||||
|
||||
//Find and patch emunand related offsets
|
||||
u32 *pos_sdmmc = memsearch(code, "SDMC", size, 4);
|
||||
u32 *pos_offset = memsearch(code, "NAND", size, 4);
|
||||
u32 *pos_header = memsearch(code, "NCSD", size, 4);
|
||||
getSDMMC(firmLocation, &sdmmcOffset, firmSize);
|
||||
getEmunandSect(&emuOffset, &emuHeader);
|
||||
getEmuRW(firmLocation, firmSize, &emuRead, &emuWrite);
|
||||
*pos_sdmmc = sdmmcOffset;
|
||||
*pos_offset = emuOffset;
|
||||
*pos_header = emuHeader;
|
||||
|
||||
//Add emunand hooks
|
||||
memcpy((u8*)emuHook(1), nandRedir, sizeof(nandRedir));
|
||||
memcpy((u8*)emuHook(2), nandRedir, sizeof(nandRedir));
|
||||
memcpy((u8*)emuRead, nandRedir, sizeof(nandRedir));
|
||||
memcpy((u8*)emuWrite, nandRedir, sizeof(nandRedir));
|
||||
memcpy((u8*)mpuCode(), mpu, sizeof(mpu));
|
||||
}
|
||||
|
||||
//Patches
|
||||
void patchFirm(){
|
||||
|
||||
//Part1: Set MPU for payload area
|
||||
memcpy((u8*)mpuCode(), mpu, sizeof(mpu));
|
||||
|
||||
//Part2: Disable signature checks
|
||||
//Disable signature checks
|
||||
memcpy((u8*)sigPatch(1), sigPat1, sizeof(sigPat1));
|
||||
memcpy((u8*)sigPatch(2), sigPat2, sizeof(sigPat2));
|
||||
|
||||
//Part3: Create arm9 thread
|
||||
//Create arm9 thread
|
||||
fileRead((u8*)threadCode(), "/rei/thread/arm9.bin", 0);
|
||||
memcpy((u8*)threadHook(1), th1, sizeof(th1));
|
||||
memcpy((u8*)threadHook(2), th2, sizeof(th2));
|
||||
|
||||
14
source/fs.c
14
source/fs.c
@@ -69,4 +69,18 @@ int fileWrite(const u8 *buffer, const char *path, u32 size){
|
||||
if (fr == FR_OK && br == size) return 0;
|
||||
}
|
||||
return fr;
|
||||
}
|
||||
|
||||
int fileSize(const char* path){
|
||||
FRESULT fr;
|
||||
FIL fp;
|
||||
int size = 0;
|
||||
|
||||
fr = f_open(&fp, path, FA_READ);
|
||||
if (fr != FR_OK)goto error;
|
||||
|
||||
size = f_size(&fp);
|
||||
error:
|
||||
f_close(&fp);
|
||||
return size;
|
||||
}
|
||||
@@ -12,5 +12,6 @@ int unmountSD();
|
||||
int fileReadOffset(u8 *dest, const char *path, u32 size, u32 offset);
|
||||
int fileRead(u8 *dest, const char *path, u32 size);
|
||||
int fileWrite(const u8 *buffer, const char *path, u32 size);
|
||||
int fileSize(const char* path);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -19,14 +19,13 @@
|
||||
**************************************************/
|
||||
|
||||
/*
|
||||
* Emunand
|
||||
* MPU
|
||||
*/
|
||||
u8 mpu[0x2C] = { //MPU shit
|
||||
0x03, 0x00, 0x36, 0x00, 0x00, 0x00, 0x10, 0x10, 0x01, 0x00, 0x00, 0x01, 0x03, 0x00, 0x36, 0x00,
|
||||
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 nandRedir[0x08] = {0x00, 0x4C, 0xA0, 0x47, 0xC0, 0xA5, 0x01, 0x08}; //Branch to emunand function
|
||||
|
||||
/*
|
||||
@@ -38,8 +37,8 @@ u8 sigPat2[4] = {0x00, 0x20, 0x70, 0x47};
|
||||
/*
|
||||
* Arm9 thread
|
||||
*/
|
||||
u8 th1[4] = {0x2C, 0xF0, 0x9F, 0xE5}; //ldr pc, =0x0801A7E0
|
||||
u8 th2[4] = {0xE0, 0xA7, 0x01, 0x08}; //0x0801A7E0
|
||||
u8 th1[4] = {0x2C, 0xF0, 0x9F, 0xE5}; //ldr pc, =0x08006070
|
||||
u8 th2[4] = {0x70, 0x60, 0x00, 0x08}; //0x08006070
|
||||
|
||||
|
||||
|
||||
@@ -54,7 +53,7 @@ u32 emuCode(void){
|
||||
|
||||
//Where thread code is stored in firm
|
||||
u32 threadCode(void){
|
||||
return KERNEL9 + (0x0801A7E0 - K9_ADDR);
|
||||
return KERNEL9 + (0x08006070 - K9_ADDR);
|
||||
}
|
||||
|
||||
//Area of MPU setting code
|
||||
@@ -69,13 +68,6 @@ u32 threadHook(u8 val){
|
||||
PROC9 + (0x080851CC - P9_ADDR);
|
||||
}
|
||||
|
||||
//Offsets to redirect to Emunand code
|
||||
u32 emuHook(u8 val){ //latest only
|
||||
return val == 1 ?
|
||||
PROC9 + (0x08077B40 - P9_ADDR):
|
||||
PROC9 + (0x08077B80 - P9_ADDR);
|
||||
}
|
||||
|
||||
//Offsets to redirect to thread code
|
||||
u32 sigPatch(u8 val){
|
||||
return val == 1 ?
|
||||
|
||||
Reference in New Issue
Block a user