diff --git a/Makefile b/Makefile index 3ba7bd9..3ef32cd 100644 --- a/Makefile +++ b/Makefile @@ -64,9 +64,9 @@ $(dir_out)/3ds/$(name): @mv $(dir_out)/$(name).3dsx $@ @mv $(dir_out)/$(name).smdh $@ -$(dir_out)/rei/: $(dir_data)/firmware.bin $(dir_data)/splash.bin +$(dir_out)/rei/: $(dir_data)/firmware.bin $(dir_data)/splash.bin $(dir_data)/RAM.txt @mkdir -p "$(dir_out)/rei" - @cp -av $(dir_data)/*bin $@ + @cp -av $(dir_data)/* $@ $(dir_out)/rei/thread/arm9.bin: $(dir_thread) @$(MAKE) $(FLAGS) -C $(dir_thread) diff --git a/data/RAM.txt b/data/RAM.txt new file mode 100644 index 0000000..5a62826 --- /dev/null +++ b/data/RAM.txt @@ -0,0 +1 @@ +536870912 \ No newline at end of file diff --git a/emunand/emuCode.s b/emunand/emuCode.s index 868a600..d0e86d0 100644 --- a/emunand/emuCode.s +++ b/emunand/emuCode.s @@ -1,6 +1,6 @@ .nds -sdmmc equ 0x080F0AB0 +sdmmc equ 0x434D4453 ;dummy .create "emunand.bin", 0x0801A5C0 .org 0x0801A5C0 diff --git a/source/emunand.c b/source/emunand.c index 2da99cb..9b62b13 100644 --- a/source/emunand.c +++ b/source/emunand.c @@ -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. } \ No newline at end of file diff --git a/source/emunand.h b/source/emunand.h index 1f8ded9..098fee1 100644 --- a/source/emunand.h +++ b/source/emunand.h @@ -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 \ No newline at end of file diff --git a/source/firm.c b/source/firm.c index 4b9a811..278697f 100644 --- a/source/firm.c +++ b/source/firm.c @@ -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)); diff --git a/source/fs.c b/source/fs.c index 9e59e98..c9fa177 100644 --- a/source/fs.c +++ b/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; } \ No newline at end of file diff --git a/source/fs.h b/source/fs.h index 0bee0e0..3b25189 100644 --- a/source/fs.h +++ b/source/fs.h @@ -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 diff --git a/source/patches.c b/source/patches.c index f66c074..d8e367d 100644 --- a/source/patches.c +++ b/source/patches.c @@ -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 ? diff --git a/thread/3ds.ld b/thread/3ds.ld index ddd375e..a04c2c9 100644 --- a/thread/3ds.ld +++ b/thread/3ds.ld @@ -6,7 +6,7 @@ ENTRY(_start) SECTIONS { - . = 0x0801A7E0; + . = 0x08006070; start_addr = .; .text.start : { *(.text.start) } .text : { *(.text) *(.text*) } diff --git a/thread/source/_start.s b/thread/source/_start.s index 0359814..368b25d 100644 --- a/thread/source/_start.s +++ b/thread/source/_start.s @@ -13,8 +13,8 @@ _start: ldr r1, =thread @ thread_addr mov r2, #0x0 @ arg ldr r3, =0x08000c00 @ StackTop - ldr r4, =0x1 + ldr r4, =0xFFFFFFFE svc 0x8 pop {r0-r12 , lr} - ldr r0, =0x80E3408 + ldr r0, =0x080E3408 ldr pc, =0x0808519C \ No newline at end of file diff --git a/thread/source/lib.c b/thread/source/lib.c index 34193b4..c086335 100644 --- a/thread/source/lib.c +++ b/thread/source/lib.c @@ -31,6 +31,24 @@ int memcmp(void* buf1, void* buf2, int size){ return equal; } +int atoi(const char* nptr){ + int result = 0, + position = 1; + const char* p = nptr; + + while(*p) ++p; + + for(--p; p >= nptr; p--){ + if(*p < 0x30 || *p > 0x39) break; + else{ + result += (position) * (*p - 0x30); + position *= 10; + } + } + result = ((nptr[0] == '-')? -result : result); + return result; +} + unsigned isPressed(unsigned bitfield){ return ((~*(unsigned *)0x10146000) & 0xFFF) == (bitfield & 0xFFF) ? 1 : 0; } \ No newline at end of file diff --git a/thread/source/lib.h b/thread/source/lib.h index ed2204d..d0a3ba5 100644 --- a/thread/source/lib.h +++ b/thread/source/lib.h @@ -20,6 +20,7 @@ void* memset(void * ptr, int value, unsigned int num); int strcomp(char* s1, char*s2, unsigned int size); void strcopy(char* dest, char* source, unsigned int size); int memcmp(void* buf1, void* buf2, int size); +int atoi(const char* nptr); unsigned isPressed(unsigned bitfield); #endif \ No newline at end of file diff --git a/thread/source/thread.c b/thread/source/thread.c index 5c0e5fd..4e790ec 100644 --- a/thread/source/thread.c +++ b/thread/source/thread.c @@ -10,78 +10,48 @@ #include "lib.h" #include "FS.h" +//ram stuff #define VRAM (unsigned char*)0x18000000 #define FCRAM (unsigned char*)0x20000000 #define FCRAM_EXT (unsigned char*)0x28000000 -#define ARM9_MEM (unsigned char*)0x8000000 -#define AXIWRAM (unsigned char*)0x1FF80000 -#define TOP_FRAME 0 -#define BOT_FRAME 1 + +//file stuff +#define READ 0 +#define WRITE 1 unsigned char handle[32]; -unsigned char bmpHead[] = { - 0x42, 0x4D, 0x36, 0x65, 0x04, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x28, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xF0, 0x00, - 0x00, 0x00, 0x01, 0x00, 0x18, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x65, 0x04, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; + +void fileReadWrite(void *buf, void *path, int size, char rw){ + unsigned int br = 0; + memset(&handle, 0, 32); + fopen9(&handle, path, 6); + if(rw == 0) fread9(&handle, &br, buf, size); + else fwrite9(&handle, &br, buf, size); + fclose9(&handle); +} void memdump(void* filename, void* buf, unsigned int size){ - unsigned int br = 0; - memset(&handle, 0, 32); - fopen9(&handle, filename, 6); - fwrite9(&handle, &br, buf, size); - fclose9(&handle); + fileReadWrite(buf, filename, size, WRITE); memset(VRAM+0x1E6000, 0xFF, 0x46500); } -void transpose (void * dst, const void * src, unsigned dim1, unsigned dim2, unsigned item_length) { - char * ptr_write; - const char * ptr_read; - unsigned x, y, z; - for (x = 0; x < dim1; x ++) for (y = 0; y < dim2; y ++) { - ptr_write = ((char *) dst) + item_length * (y * dim1 + x); - ptr_read = ((const char *) src) + item_length * (x * dim2 + y); - for (z = 0; z < item_length; z ++) *(ptr_write ++) = *(ptr_read ++); - } -} - -void screenShot(int frame){ - unsigned int br; - short width = frame == 0 ? 400 : 320; - short height = 240; - int frameOff = frame == 0 ? 0x1E6000 : 0x48F000; //<- Defaults - int length = frame == 0 ? 0x46500 : 0x38400; - memset(&handle, 0, 32); - fopen9(&handle, frame == 0 ? L"sdmc:/screen_top.bmp" : L"sdmc:/screen_bot.bmp", 6); - transpose(FCRAM+0xF80000, VRAM+frameOff, width, height, 3); - bmpHead[18] = frame == 0 ? 0x90 : 0x40; - fwrite9(&handle, &br, bmpHead, 0x36); - fwrite9(&handle, &br, FCRAM+0xF80000, length); - fclose9(&handle); - memset(VRAM+frameOff, 0xFF, 0x46500); -} - void patches(void){ //Change version string for(int i = 0; i < 0x600000; i+=4){ if(strcomp((void*)0x27B00000 - i, (void*)L"Ver.", 4)){ - if(strcomp((void*)0x27B00000 - i + 0x28, (void*)"T_ver_00", 4)) strcopy((void*)0x27B00000 - i, (void*)L"\uE024Rei", 4); + if(strcomp((void*)0x27B00000 - i + 0x0A, (void*)L"%d.%d.%d-%d", 11)) strcopy((void*)0x27B00000 - i, (void*)L"\uE024Rei", 4); } } } void thread(void){ while(1){ - if(isPressed(BUTTON_SELECT | BUTTON_X)){ - screenShot(TOP_FRAME); - screenShot(BOT_FRAME); - } - if(isPressed(BUTTON_START | BUTTON_X)){ - memdump(L"sdmc:/FCRAM.bin", (void*)0x27500000, 0x600000); + if(isPressed(BUTTON_START | BUTTON_X)){ + unsigned char buf[0x10] = {0}; + int loc = 0; + fileReadWrite(buf, L"sdmc:/rei/RAM.txt", 0x20, READ); + loc = atoi(buf); + memdump(L"sdmc:/RAMdmp.bin", (void*)loc, 0x500000); } patches(); }