diff --git a/Makefile b/Makefile index 5959325..5d2e982 100644 --- a/Makefile +++ b/Makefile @@ -36,7 +36,8 @@ objects = $(patsubst $(dir_source)/%.s, $(dir_build)/%.o, \ $(call rwildcard, $(dir_source), *.s *.c))) bundled = $(dir_build)/rebootpatch.h $(dir_build)/emunandpatch.h $(dir_build)/k11modulespatch.h $(dir_build)/svcGetCFWInfopatch.h $(dir_build)/twl_k11modulespatch.h \ - $(dir_build)/arm9_exceptions.h $(dir_build)/arm11_exceptions.h $(dir_build)/injector.h $(dir_build)/loader.h + $(dir_build)/arm9_exceptions.h $(dir_build)/arm11_exceptions.h $(dir_build)/injector.h $(dir_build)/loader.h + .PHONY: all all: launcher a9lh ninjhax @@ -127,8 +128,8 @@ $(dir_build)/arm9_exceptions.h: $(dir_arm9_exceptions)/Makefile $(dir_build)/arm11_exceptions.h: $(dir_arm11_exceptions)/Makefile @$(MAKE) -C $(dir_arm11_exceptions) @bin2c -o $@ -n arm11_exceptions $(@D)/arm11_exceptions.bin - -$(dir_build)/memory.o: CFLAGS += -O3 + +$(dir_build)/memory.o $(dir_build)/strings.o: CFLAGS += -O3 $(dir_build)/config.o: CFLAGS += -DCONFIG_TITLE="\"$(name) $(revision) (dev) configuration\"" $(dir_build)/patches.o: CFLAGS += -DREVISION=\"$(revision)\" -DCOMMIT_HASH="0x$(commit)" diff --git a/injector/Makefile b/injector/Makefile index f7194b2..6fa5844 100755 --- a/injector/Makefile +++ b/injector/Makefile @@ -25,7 +25,7 @@ INCLUDE := $(foreach dir,$(LIBDIRS),-I$(dir)/include) ASFLAGS := -mcpu=mpcore -mfloat-abi=hard -mtp=soft CFLAGS := -Wall -Wextra -MMD -MP -marm $(ASFLAGS) -fno-builtin -std=c11 -O2 -flto -ffast-math -mword-relocations \ -ffunction-sections -fdata-sections $(INCLUDE) -DARM11 -D_3DS -LDFLAGS := -Xlinker --defsym="__start__=0x14000000" -specs=3dsx.specs $(ASFLAGS) -L$(DEVKITPRO)/libctru/lib +LDFLAGS := -Xlinker --defsym="__start__=0x14000000" -specs=3dsx.specs $(ASFLAGS) objects = $(patsubst $(dir_source)/%.c, $(dir_build)/%.o, \ $(call rwildcard, $(dir_source), *.s *.c)) diff --git a/source/config.c b/source/config.c index cbea164..50d290a 100644 --- a/source/config.c +++ b/source/config.c @@ -57,11 +57,7 @@ void writeConfig(const char *configPath, u32 configTemp) configData.formatVersionMinor = CONFIG_VERSIONMINOR; if(!fileWrite(&configData, configPath, sizeof(cfgData))) - { - createDirectory("luma"); - if(!fileWrite(&configData, configPath, sizeof(cfgData))) - error("Error writing the configuration file"); - } + error("Error writing the configuration file"); } } diff --git a/source/draw.c b/source/draw.c index a6a99f5..14b8b0e 100644 --- a/source/draw.c +++ b/source/draw.c @@ -26,20 +26,12 @@ */ #include "draw.h" +#include "strings.h" #include "screen.h" #include "utils.h" #include "fs.h" #include "font.h" -static inline int strlen(const char *string) -{ - char *stringEnd = (char *)string; - - while(*stringEnd) stringEnd++; - - return stringEnd - string; -} - bool loadSplash(void) { //Don't delay boot nor init the screens if no splash image is on the SD diff --git a/source/exceptions.c b/source/exceptions.c index b850139..11fd75a 100644 --- a/source/exceptions.c +++ b/source/exceptions.c @@ -22,6 +22,7 @@ #include "exceptions.h" #include "fs.h" +#include "strings.h" #include "memory.h" #include "screen.h" #include "draw.h" @@ -46,7 +47,7 @@ void installArm9Handlers(void) } } -void installArm11Handlers(u32 *exceptionsPage, u32 stackAddr, u32 codeSetOffset) +void installArm11Handlers(u32 *exceptionsPage, u32 stackAddress, u32 codeSetOffset) { u32 *initFPU; for(initFPU = exceptionsPage; initFPU < (exceptionsPage + 0x400) && (initFPU[0] != 0xE59F0008 || initFPU[1] != 0xE5900000); initFPU++); @@ -69,7 +70,7 @@ void installArm11Handlers(u32 *exceptionsPage, u32 stackAddr, u32 codeSetOffset) { switch(*pos) //Perform relocations { - case 0xFFFF3000: *pos = stackAddr; break; + case 0xFFFF3000: *pos = stackAddress; break; case 0xEBFFFFFE: *pos = MAKE_BRANCH_LINK(pos, initFPU); break; case 0xEAFFFFFE: *pos = MAKE_BRANCH(pos, mcuReboot); break; case 0xE12FFF1C: pos[1] = 0xFFFF0000 + 4 * (u32)(freeSpace - exceptionsPage) + pos[1] - 32; break; //bx r12 (mainHandler) @@ -79,20 +80,6 @@ void installArm11Handlers(u32 *exceptionsPage, u32 stackAddr, u32 codeSetOffset) } } -static void hexItoa(u32 n, char *out) -{ - const char hexDigits[] = "0123456789ABCDEF"; - u32 i = 0; - - while(n > 0) - { - out[7 - i++] = hexDigits[n & 0xF]; - n >>= 4; - } - - for(; i < 8; i++) out[7 - i] = '0'; -} - void detectAndProcessExceptionDumps(void) { volatile ExceptionDumpHeader *dumpHeader = (volatile ExceptionDumpHeader *)0x25000000; @@ -103,31 +90,14 @@ void detectAndProcessExceptionDumps(void) char fileName[] = "crash_dump_00000000.dmp"; u32 size = dumpHeader->totalSize; - char *pathFolder; - u32 fileNameSpot; - if(dumpHeader->processor == 9) - { - pathFolder = "/luma/dumps/arm9"; - fileNameSpot = 16; - } - else - { - pathFolder = "/luma/dumps/arm11"; - fileNameSpot = 17; - } + char *pathFolder = dumpHeader->processor == 9 ? "/luma/dumps/arm9" : "/luma/dumps/arm11"; findDumpFile(pathFolder, fileName); - memcpy(path, pathFolder, 17); - path[fileNameSpot] = '/'; - memcpy(&path[fileNameSpot + 1], fileName, sizeof(fileName)); + memcpy(path, pathFolder, strlen(pathFolder) + 1); + concatenateStrings(path, "/"); + concatenateStrings(path, fileName); - if(!fileWrite((void *)dumpHeader, path, size)) - { - createDirectory("/luma"); - createDirectory("/luma/dumps"); - createDirectory(pathFolder); - fileWrite((void *)dumpHeader, path, size); - } + fileWrite((void *)dumpHeader, path, size); vu32 *regs = (vu32 *)((vu8 *)dumpHeader + sizeof(ExceptionDumpHeader)); vu8 *additionalData = (vu8 *)dumpHeader + dumpHeader->totalSize - dumpHeader->additionalDataSize; diff --git a/source/exceptions.h b/source/exceptions.h index 0d6d8ba..f21d91a 100644 --- a/source/exceptions.h +++ b/source/exceptions.h @@ -43,5 +43,5 @@ typedef struct __attribute__((packed)) } ExceptionDumpHeader; void installArm9Handlers(void); -void installArm11Handlers(u32 *exceptionsPage, u32 stackAddr, u32 codeSetOffset); +void installArm11Handlers(u32 *exceptionsPage, u32 stackAddress, u32 codeSetOffset); void detectAndProcessExceptionDumps(void); \ No newline at end of file diff --git a/source/firm.c b/source/firm.c index 62ff308..18f6365 100755 --- a/source/firm.c +++ b/source/firm.c @@ -26,6 +26,7 @@ #include "fs.h" #include "patches.h" #include "memory.h" +#include "strings.h" #include "cache.h" #include "emunand.h" #include "crypto.h" @@ -347,9 +348,8 @@ static inline void patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32 if(DEV_OPTIONS != 2) { //Install arm11 exception handlers - u32 stackAddress, - codeSetOffset; - getInfoForArm11ExceptionHandlers(arm11Section1, section[1].size, &stackAddress, &codeSetOffset); + u32 codeSetOffset; + u32 stackAddress = getInfoForArm11ExceptionHandlers(arm11Section1, section[1].size, &codeSetOffset); installArm11Handlers(arm11ExceptionsPage, stackAddress, codeSetOffset); //Kernel9/Process9 debugging @@ -436,10 +436,8 @@ static inline void copySection0AndInjectSystemModules(FirmwareType firmType) const char *ext = ".cxi"; //Read modules from files if they exist - u32 nameOff; - for(nameOff = 0; nameOff < 8 && moduleName[nameOff] != 0; nameOff++); - memcpy(fileName + 17, moduleName, nameOff); - memcpy(fileName + 17 + nameOff, ext, 5); + concatenateStrings(fileName, moduleName); + concatenateStrings(fileName, ext); u32 fileSize = fileRead(dst, fileName); if(fileSize) dstModuleSize = fileSize; diff --git a/source/fs.c b/source/fs.c index ea9d406..dd20a5a 100644 --- a/source/fs.c +++ b/source/fs.c @@ -22,6 +22,7 @@ #include "fs.h" #include "memory.h" +#include "strings.h" #include "cache.h" #include "screen.h" #include "fatfs/ff.h" @@ -64,7 +65,9 @@ bool fileWrite(const void *buffer, const char *path, u32 size) { FIL file; - if(f_open(&file, path, FA_WRITE | FA_OPEN_ALWAYS) == FR_OK) + FRESULT result = f_open(&file, path, FA_WRITE | FA_OPEN_ALWAYS); + + if(result == FR_OK) { unsigned int written; f_write(&file, buffer, size, &written); @@ -72,8 +75,21 @@ bool fileWrite(const void *buffer, const char *path, u32 size) return true; } + else if(result == FR_NO_PATH) + { + char folder[256]; - return false; + for(u32 i = 1; path[i] != 0; i++) + if(path[i] == '/') + { + memcpy(folder, path, i); + folder[i] = 0; + f_mkdir(folder); + } + + return fileWrite(buffer, path, size); + } + else return false; } void fileDelete(const char *path) @@ -81,11 +97,6 @@ void fileDelete(const char *path) f_unlink(path); } -void createDirectory(const char *path) -{ - f_mkdir(path); -} - void loadPayload(u32 pressed) { const char *pattern; @@ -99,8 +110,7 @@ void loadPayload(u32 pressed) else if(pressed & BUTTON_R1) pattern = PATTERN("r"); else if(pressed & BUTTON_A) pattern = PATTERN("a"); else if(pressed & BUTTON_START) pattern = PATTERN("start"); - else if(pressed & BUTTON_SELECT) pattern = PATTERN("select"); - else pattern = "nlc.bin"; + else pattern = PATTERN("select"); DIR dir; FILINFO info; @@ -118,12 +128,10 @@ void loadPayload(u32 pressed) memcpy(loaderAddress, loader, loader_size); - path[14] = '/'; - memcpy(&path[15], info.altname, 13); + concatenateStrings(path, "/"); + concatenateStrings(path, info.altname); loaderAddress[1] = fileRead((void *)0x24F00000, path); - - if(pattern[0] == 'n') f_unlink(path); flushDCacheRange(loaderAddress, loader_size); flushICacheRange(loaderAddress, loader_size); @@ -132,27 +140,6 @@ void loadPayload(u32 pressed) } } -void findDumpFile(const char *path, char *fileName) -{ - DIR dir; - FILINFO info; - u32 n = 0; - - while(f_findfirst(&dir, &info, path, fileName) == FR_OK && info.fname[0]) - { - u32 i = 18, - tmp = ++n; - - while(tmp) - { - fileName[i--] = '0' + (tmp % 10); - tmp /= 10; - } - } - - f_closedir(&dir); -} - u32 firmRead(void *dest, u32 firmType) { const char *firmFolders[4][2] = {{ "00000002", "20000002" }, @@ -160,8 +147,9 @@ u32 firmRead(void *dest, u32 firmType) { "00000202", "20000202" }, { "00000003", "20000003" }}; - char path[48] = "1:/title/00040138/00000000/content"; - memcpy(&path[18], firmFolders[firmType][isN3DS ? 1 : 0], 8); + char path[48] = "1:/title/00040138/"; + concatenateStrings(path, firmFolders[firmType][isN3DS ? 1 : 0]); + concatenateStrings(path, "/content"); DIR dir; FILINFO info; @@ -191,21 +179,33 @@ u32 firmRead(void *dest, u32 firmType) f_closedir(&dir); //Complete the string with the .app name - memcpy(&path[34], "/00000000.app", 14); - - //Last digit of the .app - u32 i = 42; + concatenateStrings(path, "/00000000.app"); //Convert back the .app name from integer to array - u32 tempVersion = firmVersion; - while(tempVersion) - { - static const char hexDigits[] = "0123456789ABCDEF"; - path[i--] = hexDigits[tempVersion & 0xF]; - tempVersion >>= 4; - } + hexItoa(firmVersion, &path[35]); fileRead(dest, path); return firmVersion; +} + +void findDumpFile(const char *path, char *fileName) +{ + DIR dir; + FILINFO info; + u32 n = 0; + + while(f_findfirst(&dir, &info, path, fileName) == FR_OK && info.fname[0]) + { + u32 i = 18, + tmp = ++n; + + while(tmp) + { + fileName[i--] = '0' + (tmp % 10); + tmp /= 10; + } + } + + f_closedir(&dir); } \ No newline at end of file diff --git a/source/fs.h b/source/fs.h index 23244fe..feba3ab 100644 --- a/source/fs.h +++ b/source/fs.h @@ -33,6 +33,7 @@ u32 fileRead(void *dest, const char *path); u32 getFileSize(const char *path); bool fileWrite(const void *buffer, const char *path, u32 size); void fileDelete(const char *path); -void createDirectory(const char *path); +void loadPayload(u32 pressed); +u32 firmRead(void *dest, u32 firmType); + void findDumpFile(const char *path, char *fileName); -void loadPayload(u32 pressed);u32 firmRead(void *dest, u32 firmType); diff --git a/source/memory.c b/source/memory.c index e7a05c9..03a36ae 100644 --- a/source/memory.c +++ b/source/memory.c @@ -41,7 +41,7 @@ void memset32(void *dest, u32 filler, u32 size) { u32 *dest32 = (u32 *)dest; - for (u32 i = 0; i < size / 4; i++) + for(u32 i = 0; i < size / 4; i++) dest32[i] = filler; } diff --git a/source/patches.h b/source/patches.h index fe80a94..a80a393 100644 --- a/source/patches.h +++ b/source/patches.h @@ -61,9 +61,9 @@ void implementSvcGetCFWInfo(u8 *pos, u32 *arm11SvcTable, u8 **freeK11Space); void applyLegacyFirmPatches(u8 *pos, FirmwareType firmType); void patchTwlBg(u8 *pos); -void getInfoForArm11ExceptionHandlers(u8 *pos, u32 size, u32 *stackAddr, u32 *codeSetOffset); +u32 getInfoForArm11ExceptionHandlers(u8 *pos, u32 size, u32 *codeSetOffset); void patchArm9ExceptionHandlersInstall(u8 *pos, u32 size); -void patchSvcBreak9(u8 *pos, u32 size, u32 k9Address); +void patchSvcBreak9(u8 *pos, u32 size, u32 kernel9Address); void patchSvcBreak11(u8 *pos, u32 *arm11SvcTable); void patchKernel9Panic(u8 *pos, u32 size, FirmwareType firmType); void patchKernel11Panic(u8 *pos, u32 size); diff --git a/source/pin.c b/source/pin.c index 0f52200..e46a1d3 100644 --- a/source/pin.c +++ b/source/pin.c @@ -96,11 +96,7 @@ void newPin(bool allowSkipping) memcpy(pin.hash, tmp, 32); if(!fileWrite(&pin, "/luma/pin.bin", sizeof(PINData))) - { - createDirectory("luma"); - if(!fileWrite(&pin, "/luma/pin.bin", sizeof(PINData))) - error("Error writing the PIN file"); - } + error("Error writing the PIN file"); } bool verifyPin(void) diff --git a/source/strings.c b/source/strings.c new file mode 100644 index 0000000..9d0bb2d --- /dev/null +++ b/source/strings.c @@ -0,0 +1,55 @@ +/* +* This file is part of Luma3DS +* Copyright (C) 2016 Aurora Wright, TuxSH +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +* +* Additional Terms 7.b of GPLv3 applies to this file: Requiring preservation of specified +* reasonable legal notices or author attributions in that material or in the Appropriate Legal +* Notices displayed by works containing it. +*/ + +#include "strings.h" +#include "memory.h" + +int strlen(const char *string) +{ + char *stringEnd = (char *)string; + + while(*stringEnd) stringEnd++; + + return stringEnd - string; +} + +void concatenateStrings(char *destination, const char *source) +{ + int i = strlen(source), + j = strlen(destination); + + memcpy(&destination[j], source, i + 1); +} + +void hexItoa(u32 number, char *out) +{ + const char hexDigits[] = "0123456789ABCDEF"; + u32 i = 0; + + while(number > 0) + { + out[7 - i++] = hexDigits[number & 0xF]; + number >>= 4; + } + + for(; i < 8; i++) out[7 - i] = '0'; +} \ No newline at end of file diff --git a/source/strings.h b/source/strings.h new file mode 100644 index 0000000..f6ac599 --- /dev/null +++ b/source/strings.h @@ -0,0 +1,29 @@ +/* +* This file is part of Luma3DS +* Copyright (C) 2016 Aurora Wright, TuxSH +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +* +* Additional Terms 7.b of GPLv3 applies to this file: Requiring preservation of specified +* reasonable legal notices or author attributions in that material or in the Appropriate Legal +* Notices displayed by works containing it. +*/ + +#pragma once + +#include "types.h" + +int strlen(const char *string); +void concatenateStrings(char *destination, const char *source); +void hexItoa(u32 number, char *out); \ No newline at end of file