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:
Reisyukaku
2016-01-23 03:53:45 -05:00
parent 2465cb0fa9
commit 62d8d582c1
14 changed files with 127 additions and 91 deletions

View File

@@ -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.
}

View File

@@ -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

View File

@@ -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));

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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 ?