diff --git a/exceptions/arm11/source/handlers.h b/exceptions/arm11/source/handlers.h index 270723b..e82afb4 100644 --- a/exceptions/arm11/source/handlers.h +++ b/exceptions/arm11/source/handlers.h @@ -28,10 +28,10 @@ typedef struct __attribute__((packed)) { u32 magic[2]; u16 versionMinor, versionMajor; - + u16 processor, core; u32 type; - + u32 totalSize; u32 registerDumpSize; u32 codeDumpSize; diff --git a/exceptions/arm11/source/mainHandler.c b/exceptions/arm11/source/mainHandler.c index 69b3850..0029e8d 100644 --- a/exceptions/arm11/source/mainHandler.c +++ b/exceptions/arm11/source/mainHandler.c @@ -46,22 +46,22 @@ static u32 __attribute__((noinline)) copyMemory(void *dst, const void *src, u32 void __attribute__((noreturn)) mainHandler(u32 regs[REG_DUMP_SIZE / 4], u32 type, u32 cpuId) { ExceptionDumpHeader dumpHeader; - + u32 registerDump[REG_DUMP_SIZE / 4]; u8 codeDump[CODE_DUMP_SIZE]; u8 *final = (u8 *)FINAL_BUFFER; while(*(vu32 *)final == 0xDEADC0DE && *((vu32 *)final + 1) == 0xDEADCAFE); - + dumpHeader.magic[0] = 0xDEADC0DE; dumpHeader.magic[1] = 0xDEADCAFE; dumpHeader.versionMajor = 1; dumpHeader.versionMinor = 2; - + dumpHeader.processor = 11; dumpHeader.core = cpuId & 0xF; dumpHeader.type = type; - + dumpHeader.registerDumpSize = REG_DUMP_SIZE; dumpHeader.codeDumpSize = CODE_DUMP_SIZE; dumpHeader.additionalDataSize = 0; @@ -80,24 +80,24 @@ void __attribute__((noreturn)) mainHandler(u32 regs[REG_DUMP_SIZE / 4], u32 type //Dump code u8 *instr = (u8 *)pc + ((cpsr & 0x20) ? 2 : 4) - dumpHeader.codeDumpSize; //Doesn't work well on 32-bit Thumb instructions, but it isn't much of a problem dumpHeader.codeDumpSize = copyMemory(codeDump, instr, dumpHeader.codeDumpSize, ((cpsr & 0x20) != 0) ? 2 : 4); - + //Copy register dump and code dump final = (u8 *)(FINAL_BUFFER + sizeof(ExceptionDumpHeader)); final += copyMemory(final, registerDump, dumpHeader.registerDumpSize, 1); final += copyMemory(final, codeDump, dumpHeader.codeDumpSize, 1); - + //Dump stack in place dumpHeader.stackDumpSize = copyMemory(final, (const void *)registerDump[13], 0x1000 - (registerDump[13] & 0xFFF), 1); final += dumpHeader.stackDumpSize; vu8 *currentKProcess = cannotAccessVA((u8 *)0xFFFF9004) ? NULL : *(vu8 **)0xFFFF9004; vu8 *currentKCodeSet = currentKProcess != NULL ? *(vu8 **)(currentKProcess + CODESET_OFFSET) : NULL; - + if(currentKCodeSet != NULL) { vu64 *additionalData = (vu64 *)final; dumpHeader.additionalDataSize = 16; - + additionalData[0] = *(vu64 *)(currentKCodeSet + 0x50); //Process name additionalData[1] = *(vu64 *)(currentKCodeSet + 0x5C); //Title ID } diff --git a/injector/Makefile b/injector/Makefile index 6fa5844..e733480 100755 --- a/injector/Makefile +++ b/injector/Makefile @@ -43,7 +43,7 @@ clean: $(dir_build)/$(name).elf: $(objects) $(LINK.o) $(OUTPUT_OPTION) $^ $(LIBPATHS) $(LIBS) -$(dir_build)/memory.o : CFLAGS += -O3 +$(dir_build)/memory.o $(dir_build)/strings.o: CFLAGS += -O3 $(dir_build)/%.o: $(dir_source)/%.c @mkdir -p "$(@D)" diff --git a/injector/source/memory.c b/injector/source/memory.c index 4f4c96a..8c36f5f 100644 --- a/injector/source/memory.c +++ b/injector/source/memory.c @@ -7,4 +7,44 @@ void memcpy(void *dest, const void *src, u32 size) for(u32 i = 0; i < size; i++) destc[i] = srcc[i]; +} + +int memcmp(const void *buf1, const void *buf2, u32 size) +{ + const u8 *buf1c = (const u8 *)buf1; + const u8 *buf2c = (const u8 *)buf2; + + for(u32 i = 0; i < size; i++) + { + int cmp = buf1c[i] - buf2c[i]; + if(cmp) return cmp; + } + + return 0; +} + +//Quick Search algorithm, adapted from http://igm.univ-mlv.fr/~lecroq/string/node19.html#SECTION00190 +u8 *memsearch(u8 *startPos, const void *pattern, u32 size, u32 patternSize) +{ + const u8 *patternc = (const u8 *)pattern; + + //Preprocessing + u32 table[256]; + + for(u32 i = 0; i < 256; i++) + table[i] = patternSize + 1; + for(u32 i = 0; i < patternSize; i++) + table[patternc[i]] = patternSize - i; + + //Searching + u32 j = 0; + + while(j <= size - patternSize) + { + if(memcmp(pattern, startPos + j, patternSize) == 0) + return startPos + j; + j += table[startPos[j + patternSize]]; + } + + return NULL; } \ No newline at end of file diff --git a/injector/source/memory.h b/injector/source/memory.h index c1e1609..b7cf593 100644 --- a/injector/source/memory.h +++ b/injector/source/memory.h @@ -2,4 +2,6 @@ #include <3ds/types.h> -void memcpy(void *dest, const void *src, u32 size); \ No newline at end of file +void memcpy(void *dest, const void *src, u32 size); +int memcmp(const void *buf1, const void *buf2, u32 size); +u8 *memsearch(u8 *startPos, const void *pattern, u32 size, u32 patternSize); \ No newline at end of file diff --git a/injector/source/patcher.c b/injector/source/patcher.c index 5ecdce2..fcd6d60 100644 --- a/injector/source/patcher.c +++ b/injector/source/patcher.c @@ -1,56 +1,15 @@ #include <3ds.h> -#include "memory.h" #include "patcher.h" +#include "memory.h" +#include "strings.h" #include "ifile.h" #include "CFWInfo.h" static CFWInfo info; -static int memcmp(const void *buf1, const void *buf2, u32 size) +static void patchMemory(u8 *start, u32 size, const void *pattern, u32 patSize, int offset, const void *replace, u32 repSize, u32 count) { - const u8 *buf1c = (const u8 *)buf1; - const u8 *buf2c = (const u8 *)buf2; - - for(u32 i = 0; i < size; i++) - { - int cmp = buf1c[i] - buf2c[i]; - if(cmp) return cmp; - } - - return 0; -} - -//Quick Search algorithm, adapted from http://igm.univ-mlv.fr/~lecroq/string/node19.html#SECTION00190 -static u8 *memsearch(u8 *startPos, const void *pattern, u32 size, u32 patternSize) -{ - const u8 *patternc = (const u8 *)pattern; - - //Preprocessing - u32 table[256]; - - for(u32 i = 0; i < 256; ++i) - table[i] = patternSize + 1; - for(u32 i = 0; i < patternSize; ++i) - table[patternc[i]] = patternSize - i; - - //Searching - u32 j = 0; - - while(j <= size - patternSize) - { - if(memcmp(patternc, startPos + j, patternSize) == 0) - return startPos + j; - j += table[startPos[j + patternSize]]; - } - - return NULL; -} - -static u32 patchMemory(u8 *start, u32 size, const void *pattern, u32 patSize, int offset, const void *replace, u32 repSize, u32 count) -{ - u32 i; - - for(i = 0; i < count; i++) + for(u32 i = 0; i < count; i++) { u8 *found = memsearch(start, pattern, size, patSize); @@ -65,17 +24,6 @@ static u32 patchMemory(u8 *start, u32 size, const void *pattern, u32 patSize, in size -= at + patSize; start = found + patSize; } - - return i; -} - -static inline size_t strnlen(const char *string, size_t maxlen) -{ - size_t size; - - for(size = 0; *string && size < maxlen; string++, size++); - - return size; } static int fileOpen(IFile *file, FS_ArchiveID archiveId, const char *path, int flags) @@ -119,16 +67,6 @@ static bool secureInfoExists(void) return exists; } -static void progIdToStr(char *strEnd, u64 progId) -{ - while(progId) - { - static const char hexDigits[] = "0123456789ABCDEF"; - *strEnd-- = hexDigits[(u32)(progId & 0xF)]; - progId >>= 4; - } -} - static void loadTitleCodeSection(u64 progId, u8 *code, u32 size) { /* Here we look for "/luma/code_sections/[u64 titleID in hex, uppercase].bin" diff --git a/injector/source/strings.c b/injector/source/strings.c new file mode 100644 index 0000000..4f34404 --- /dev/null +++ b/injector/source/strings.c @@ -0,0 +1,20 @@ +#include "strings.h" + +size_t strnlen(const char *string, size_t maxlen) +{ + size_t size; + + for(size = 0; *string && size < maxlen; string++, size++); + + return size; +} + +void progIdToStr(char *strEnd, u64 progId) +{ + while(progId) + { + static const char hexDigits[] = "0123456789ABCDEF"; + *strEnd-- = hexDigits[(u32)(progId & 0xF)]; + progId >>= 4; + } +} \ No newline at end of file diff --git a/injector/source/strings.h b/injector/source/strings.h new file mode 100644 index 0000000..6599118 --- /dev/null +++ b/injector/source/strings.h @@ -0,0 +1,6 @@ +#pragma once + +#include <3ds/types.h> + +size_t strnlen(const char *string, size_t maxlen); +void progIdToStr(char *strEnd, u64 progId); \ No newline at end of file diff --git a/patches/svcGetCFWInfo.s b/patches/svcGetCFWInfo.s index 945cb58..3950ead 100644 --- a/patches/svcGetCFWInfo.s +++ b/patches/svcGetCFWInfo.s @@ -23,7 +23,6 @@ .arm.little .create "build/svcGetCFWInfo.bin", 0 - .arm adr r1, infoStart diff --git a/source/exceptions.h b/source/exceptions.h index 74bd152..27e8a69 100644 --- a/source/exceptions.h +++ b/source/exceptions.h @@ -31,10 +31,10 @@ typedef struct __attribute__((packed)) { u32 magic[2]; u16 versionMinor, versionMajor; - + u16 processor, core; u32 type; - + u32 totalSize; u32 registerDumpSize; u32 codeDumpSize; diff --git a/source/memory.c b/source/memory.c index 03a36ae..48d4060 100644 --- a/source/memory.c +++ b/source/memory.c @@ -66,9 +66,9 @@ u8 *memsearch(u8 *startPos, const void *pattern, u32 size, u32 patternSize) //Preprocessing u32 table[256]; - for(u32 i = 0; i < 256; ++i) + for(u32 i = 0; i < 256; i++) table[i] = patternSize + 1; - for(u32 i = 0; i < patternSize; ++i) + for(u32 i = 0; i < patternSize; i++) table[patternc[i]] = patternSize - i; //Searching @@ -76,7 +76,7 @@ u8 *memsearch(u8 *startPos, const void *pattern, u32 size, u32 patternSize) while(j <= size - patternSize) { - if(memcmp(patternc, startPos + j, patternSize) == 0) + if(memcmp(pattern, startPos + j, patternSize) == 0) return startPos + j; j += table[startPos[j + patternSize]]; }