From 31458e9938b0d1463f3baee0ca3d88a57d3e148f Mon Sep 17 00:00:00 2001 From: Aurora Date: Sat, 27 Aug 2016 16:00:15 +0200 Subject: [PATCH 1/4] Implement a new config file format which allows invalidating the config with new releases, fix config-related bugs, cleanup --- source/config.c | 50 ++++++++++++++++++++++++++++++++++++++++++------ source/config.h | 23 +++++++++++++++++----- source/firm.c | 48 ++++++++++++++++------------------------------ source/firm.h | 5 +++++ source/patches.c | 8 ++++---- source/patches.h | 1 - source/pin.c | 30 ++++++++++++++++++----------- source/pin.h | 2 ++ source/screen.c | 2 +- source/screen.h | 2 ++ source/types.h | 9 +-------- 11 files changed, 113 insertions(+), 67 deletions(-) diff --git a/source/config.c b/source/config.c index 8c9c962..faf55dd 100644 --- a/source/config.c +++ b/source/config.c @@ -21,12 +21,50 @@ */ #include "config.h" +#include "memory.h" +#include "fs.h" #include "utils.h" #include "screen.h" #include "draw.h" #include "buttons.h" -void configureCFW(void) +bool readConfig(const char *configPath) +{ + if(fileRead(&configData, configPath) != sizeof(cfgData) || + memcmp(configData.magic, "CONF", 4) != 0 || + configData.formatVersionMajor != CONFIG_VERSIONMAJOR || + configData.formatVersionMinor != CONFIG_VERSIONMINOR) + { + configData.config = 0; + return false; + } + + return true; +} + +void writeConfig(const char *configPath, u32 configTemp) +{ + /* If the configuration is different from previously, overwrite it. + Just the no-forcing flag being set is not enough */ + if((configTemp & 0xFFFFFFEF) != configData.config) + { + //Merge the new options and new boot configuration + configData.config = (configData.config & 0xFFFFFFC0) | (configTemp & 0x3F); + + memcpy(configData.magic, "CONF", 4); + configData.formatVersionMajor = CONFIG_VERSIONMAJOR; + configData.formatVersionMinor = CONFIG_VERSIONMINOR; + + if(!fileWrite(&configData, configPath, sizeof(configData))) + { + createDirectory("luma"); + if(!fileWrite(&configData, configPath, sizeof(configData))) + error("Error writing the configuration file"); + } + } +} + +void configure(void) { initScreens(); @@ -41,10 +79,10 @@ void configureCFW(void) "( ) Use second EmuNAND as default", "( ) Enable region/language emu. and ext. .code", "( ) Show current NAND in System Settings", + "( ) Enable experimental TwlBg patches", "( ) Show GBA boot screen in patched AGB_FIRM", "( ) Display splash screen before payloads", - "( ) Use a PIN", - "( ) Enable experimental TwlBg patches" }; + "( ) Use a PIN" }; struct multiOption { int posXs[4]; @@ -185,13 +223,13 @@ void configureCFW(void) } //Preserve the last-used boot options (last 12 bits) - config &= 0x3F; + configData.config &= 0x3F; //Parse and write the new configuration for(u32 i = 0; i < multiOptionsAmount; i++) - config |= multiOptions[i].enabled << (i * 2 + 6); + configData.config |= multiOptions[i].enabled << (i * 2 + 6); for(u32 i = 0; i < singleOptionsAmount; i++) - config |= (singleOptions[i].enabled ? 1 : 0) << (i + 16); + configData.config |= (singleOptions[i].enabled ? 1 : 0) << (i + 16); //Wait for the pressed buttons to change while(HID_PAD == BUTTON_START); diff --git a/source/config.h b/source/config.h index 95fa0c6..ecdf4b4 100644 --- a/source/config.h +++ b/source/config.h @@ -24,10 +24,23 @@ #include "types.h" -#define CONFIG(a) (((config >> (a + 16)) & 1) != 0) -#define MULTICONFIG(a) ((config >> (a * 2 + 6)) & 3) -#define BOOTCONFIG(a, b) ((config >> a) & b) +#define CONFIG(a) (((configData.config >> (a + 16)) & 1) != 0) +#define MULTICONFIG(a) ((configData.config >> (a * 2 + 6)) & 3) +#define BOOTCONFIG(a, b) ((configData.config >> a) & b) -extern u32 config; +#define CONFIG_VERSIONMAJOR 1 +#define CONFIG_VERSIONMINOR 0 -void configureCFW(void); \ No newline at end of file +typedef struct __attribute__((packed)) +{ + char magic[4]; + u16 formatVersionMajor, formatVersionMinor; + + u32 config; +} cfgData; + +extern cfgData configData; + +bool readConfig(const char *configPath); +void writeConfig(const char *configPath, u32 configTemp); +void configure(void); \ No newline at end of file diff --git a/source/firm.c b/source/firm.c index 14fa54c..7c9c0c4 100755 --- a/source/firm.c +++ b/source/firm.c @@ -35,18 +35,18 @@ #include "pin.h" #include "../build/injector.h" -extern u16 launchedFirmTIDLow[8]; //defined in start.s +extern u16 launchedFirmTIDLow[8]; //Defined in start.s static firmHeader *const firm = (firmHeader *)0x24000000; static const firmSectionHeader *section; -u32 config, - emuOffset; +u32 emuOffset; bool isN3DS, isDevUnit, isFirmlaunch; +cfgData configData; FirmwareSource firmSource; void main(void) @@ -72,7 +72,7 @@ void main(void) const char configPath[] = "/luma/config.bin"; //Attempt to read the configuration file - needConfig = fileRead(&config, configPath) ? MODIFY_CONFIGURATION : CREATE_CONFIGURATION; + needConfig = readConfig(configPath) ? MODIFY_CONFIGURATION : CREATE_CONFIGURATION; //Determine if this is a firmlaunch boot if(launchedFirmTIDLow[5] != 0) @@ -99,11 +99,8 @@ void main(void) //Determine if booting with A9LH isA9lh = !PDN_SPI_CNT; - //Determine if the user chose to use the SysNAND FIRM as default for a R boot - bool useSysAsDefault = isA9lh ? CONFIG(1) : false; - //Save old options and begin saving the new boot configuration - configTemp = (config & 0xFFFFFFC0) | ((u32)isA9lh << 3); + configTemp = (configData.config & 0xFFFFFFC0) | ((u32)isA9lh << 3); //If it's a MCU reboot, try to force boot options if(isA9lh && CFG_BOOTENV) @@ -112,7 +109,7 @@ void main(void) if(CFG_BOOTENV == 7) { nandType = FIRMWARE_SYSNAND; - firmSource = useSysAsDefault ? FIRMWARE_SYSNAND : (FirmwareSource)BOOTCONFIG(2, 1); + firmSource = CONFIG(1) ? FIRMWARE_SYSNAND : (FirmwareSource)BOOTCONFIG(2, 1); needConfig = DONT_CONFIGURE; //Flag to prevent multiple boot options-forcing @@ -121,7 +118,7 @@ void main(void) /* Else, force the last used boot options unless a button is pressed or the no-forcing flag is set */ - else if(!pressed && !BOOTCONFIG(4, 1)) + else if(needConfig != CREATE_CONFIGURATION && !pressed && !BOOTCONFIG(4, 1)) { nandType = (FirmwareSource)BOOTCONFIG(0, 3); firmSource = (FirmwareSource)BOOTCONFIG(2, 1); @@ -134,7 +131,7 @@ void main(void) { PINData pin; - bool pinExists = CONFIG(7) && readPin(&pin); + bool pinExists = CONFIG(8) && readPin(&pin); //If we get here we should check the PIN (if it exists) in all cases if(pinExists) verifyPin(&pin); @@ -144,9 +141,9 @@ void main(void) if(shouldLoadConfigurationMenu) { - configureCFW(); + configure(); - if(!pinExists && CONFIG(7)) newPin(); + if(!pinExists && CONFIG(8)) newPin(); chrono(2); @@ -164,7 +161,7 @@ void main(void) } else { - if(CONFIG(6) && loadSplash()) pressed = HID_PAD; + if(CONFIG(7) && loadSplash()) pressed = HID_PAD; /* If L and R/A/Select or one of the single payload buttons are pressed, chainload an external payload (the PIN, if any, has been verified)*/ @@ -172,7 +169,10 @@ void main(void) if(shouldLoadPayload) loadPayload(pressed); - if(!CONFIG(6)) loadSplash(); + if(!CONFIG(7)) loadSplash(); + + //Determine if the user chose to use the SysNAND FIRM as default for a R boot + bool useSysAsDefault = isA9lh ? CONFIG(1) : false; //If R is pressed, boot the non-updated NAND with the FIRM of the opposite one if(pressed & BUTTON_R1) @@ -210,21 +210,7 @@ void main(void) if(!isFirmlaunch) { configTemp |= (u32)nandType | ((u32)firmSource << 2); - - /* If the configuration is different from previously, overwrite it. - Just the no-forcing flag being set is not enough */ - if((configTemp & 0xFFFFFFEF) != config) - { - //Merge the new options and new boot configuration - config = (config & 0xFFFFFFC0) | (configTemp & 0x3F); - - if(!fileWrite(&config, configPath, 4)) - { - createDirectory("luma"); - if(!fileWrite(&config, configPath, 4)) - error("Error writing the configuration file"); - } - } + writeConfig(configPath, configTemp); } u32 firmVersion = loadFirm(firmType); @@ -331,7 +317,7 @@ static inline void patchLegacyFirm(FirmwareType firmType) applyLegacyFirmPatches((u8 *)firm, firmType); - if(firmType == TWL_FIRM && CONFIG(8)) + if(firmType == TWL_FIRM && CONFIG(5)) patchTwlBg((u8 *)firm + section[1].offset); } diff --git a/source/firm.h b/source/firm.h index 2898a35..7b5d84d 100644 --- a/source/firm.h +++ b/source/firm.h @@ -24,6 +24,11 @@ #include "types.h" +#define CFG_BOOTENV (*(vu32 *)0x10010000) +#define CFG_UNITINFO (*(vu8 *)0x10010010) +#define PDN_MPCORE_CFG (*(vu32 *)0x10140FFC) +#define PDN_SPI_CNT (*(vu32 *)0x101401C0) + //FIRM Header layout typedef struct firmSectionHeader { u32 offset; diff --git a/source/patches.c b/source/patches.c index cb8bad5..c7c2def 100644 --- a/source/patches.c +++ b/source/patches.c @@ -98,9 +98,9 @@ void patchSignatureChecks(u8 *pos, u32 size) void patchFirmlaunches(u8 *pos, u32 size, u32 process9MemAddr) { //Look for firmlaunch code - const u8 pattern[] = {0xDE, 0x1F, 0x8D, 0xE2}; + const u8 pattern[] = {0xE2, 0x20, 0x20, 0x90}; - u8 *off = memsearch(pos, pattern, size, 4) - 0x10; + u8 *off = memsearch(pos, pattern, size, 4) - 0x13; //Firmlaunch function offset - offset in BLX opcode (A4-16 - ARM DDI 0100E) + 1 u32 fOpenOffset = (u32)(off + 9 - (-((*(u32 *)off & 0x00FFFFFF) << 2) & (0xFFFFFF << 2)) - pos + process9MemAddr); @@ -180,7 +180,7 @@ void implementSvcGetCFWInfo(u8 *pos, u32 size) CFWInfo *info = (CFWInfo *)memsearch(freeK11Space, "LUMA", svcGetCFWInfo_size, 4); info->commitHash = COMMIT_HASH; - info->config = config; + info->config = configData.config; info->versionMajor = (u8)(rev[1] - '0'); info->versionMinor = (u8)(rev[3] - '0'); if(rev[4] == '.') @@ -227,7 +227,7 @@ void applyLegacyFirmPatches(u8 *pos, FirmwareType firmType) /* Calculate the amount of patches to apply. Only count the boot screen patch for AGB_FIRM if the matching option was enabled (keep it as last) */ u32 numPatches = firmType == TWL_FIRM ? (sizeof(twlPatches) / sizeof(patchData)) : - (sizeof(agbPatches) / sizeof(patchData) - !CONFIG(5)); + (sizeof(agbPatches) / sizeof(patchData) - !CONFIG(6)); const patchData *patches = firmType == TWL_FIRM ? twlPatches : agbPatches; //Patch diff --git a/source/patches.h b/source/patches.h index 5b162c4..24e82bb 100644 --- a/source/patches.h +++ b/source/patches.h @@ -48,7 +48,6 @@ typedef struct __attribute__((packed)) } CFWInfo; extern bool isN3DS; -extern u32 config; u8 *getProcess9(u8 *pos, u32 size, u32 *process9Size, u32 *process9MemAddr); void patchSignatureChecks(u8 *pos, u32 size); diff --git a/source/pin.c b/source/pin.c index 599fee0..aac0d41 100644 --- a/source/pin.c +++ b/source/pin.c @@ -36,11 +36,14 @@ bool readPin(PINData *out) { - u8 __attribute__((aligned(4))) zeroes[16] = {0}; - u8 __attribute__((aligned(4))) tmp[32] = {0}; + if(fileRead(out, "/luma/pin.bin") != sizeof(PINData) || + memcmp(out->magic, "PINF", 4) != 0 || + out->formatVersionMajor != PIN_VERSIONMAJOR || + out->formatVersionMinor != PIN_VERSIONMINOR) + return false; - if(fileRead(out, "/luma/pin.bin") != sizeof(PINData)) return false; - if(memcmp(out->magic, "PINF", 4) != 0) return false; + u8 __attribute__((aligned(4))) zeroes[16] = {0}; + u8 __attribute__((aligned(4))) tmp[32]; computePINHash(tmp, zeroes, 1); @@ -89,13 +92,13 @@ void newPin(void) charDrawPos += 2 * SPACING_X; } - PINData pin = {0}; - u8 __attribute__((aligned(4))) tmp[32] = {0}; + PINData pin; + u8 __attribute__((aligned(4))) tmp[32]; u8 __attribute__((aligned(4))) zeroes[16] = {0}; memcpy(pin.magic, "PINF", 4); - pin.formatVersionMajor = 1; - pin.formatVersionMinor = 0; + pin.formatVersionMajor = PIN_VERSIONMAJOR; + pin.formatVersionMinor = PIN_VERSIONMINOR; computePINHash(tmp, zeroes, 1); memcpy(pin.testHash, tmp, 32); @@ -103,8 +106,13 @@ void newPin(void) computePINHash(tmp, enteredPassword, (PIN_LENGTH + 15) / 16); memcpy(pin.hash, tmp, 32); - fileWrite(&pin, "/luma/pin.bin", sizeof(PINData)); - + if(!fileWrite(&pin, "/luma/pin.bin", sizeof(PINData))) + { + createDirectory("luma"); + if(!fileWrite(&pin, "/luma/pin.bin", sizeof(PINData))) + error("Error writing the PIN file"); + } + while(HID_PAD & PIN_BUTTONS); } @@ -145,7 +153,7 @@ void verifyPin(PINData *in) if(cnt >= PIN_LENGTH) { - u8 __attribute__((aligned(4))) tmp[32] = {0}; + u8 __attribute__((aligned(4))) tmp[32]; computePINHash(tmp, enteredPassword, (PIN_LENGTH + 15) / 16); unlock = memcmp(in->hash, tmp, 32) == 0; diff --git a/source/pin.h b/source/pin.h index c75ba00..ce6f370 100644 --- a/source/pin.h +++ b/source/pin.h @@ -31,6 +31,8 @@ #include "types.h" #define PIN_LENGTH 4 +#define PIN_VERSIONMAJOR 1 +#define PIN_VERSIONMINOR 0 typedef struct __attribute__((packed)) { diff --git a/source/screen.c b/source/screen.c index 6b121a6..ffcf863 100644 --- a/source/screen.c +++ b/source/screen.c @@ -242,7 +242,7 @@ void initScreens(void) if(PDN_GPU_CNT == 1) { - flushDCacheRange(&config, 4); + flushDCacheRange(&configData, sizeof(cfgData)); flushDCacheRange((void *)fb, sizeof(struct fb)); invokeArm11Function(ARM11); diff --git a/source/screen.h b/source/screen.h index 1e86289..720d01e 100644 --- a/source/screen.h +++ b/source/screen.h @@ -29,6 +29,8 @@ #include "types.h" +#define PDN_GPU_CNT (*(vu8 *)0x10141200) + #define ARM11_STUB_ADDRESS (0x25000000 - 0x30) //It's currently only 0x28 bytes large. We're putting 0x30 just to be sure here #define WAIT_FOR_ARM9() *arm11Entry = 0; while(!*arm11Entry); ((void (*)())*arm11Entry)(); diff --git a/source/types.h b/source/types.h index 0aa6fc5..a6946d5 100644 --- a/source/types.h +++ b/source/types.h @@ -26,13 +26,6 @@ #include #include -#define CFG_BOOTENV (*(vu32 *)0x10010000) -#define CFG_UNITINFO (*(vu8 *)0x10010010) - -#define PDN_MPCORE_CFG (*(vu32 *)0x10140FFC) -#define PDN_SPI_CNT (*(vu32 *)0x101401C0) -#define PDN_GPU_CNT (*(vu8 *)0x10141200) - //Common data types typedef uint8_t u8; typedef uint16_t u16; @@ -43,7 +36,7 @@ typedef volatile u16 vu16; typedef volatile u32 vu32; typedef volatile u64 vu64; -//Used by multiple files: +//Used by multiple files typedef enum FirmwareSource { FIRMWARE_SYSNAND = 0, From d6f66d24facee699ffd7de23c1e24d78c194faf7 Mon Sep 17 00:00:00 2001 From: Aurora Date: Sat, 27 Aug 2016 16:09:45 +0200 Subject: [PATCH 2/4] Consistency --- source/config.c | 4 ++-- source/utils.c | 2 -- source/utils.h | 2 ++ 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/source/config.c b/source/config.c index faf55dd..6b684fa 100644 --- a/source/config.c +++ b/source/config.c @@ -55,10 +55,10 @@ void writeConfig(const char *configPath, u32 configTemp) configData.formatVersionMajor = CONFIG_VERSIONMAJOR; configData.formatVersionMinor = CONFIG_VERSIONMINOR; - if(!fileWrite(&configData, configPath, sizeof(configData))) + if(!fileWrite(&configData, configPath, sizeof(cfgData))) { createDirectory("luma"); - if(!fileWrite(&configData, configPath, sizeof(configData))) + if(!fileWrite(&configData, configPath, sizeof(cfgData))) error("Error writing the configuration file"); } } diff --git a/source/utils.c b/source/utils.c index 3a931f9..c5706a7 100644 --- a/source/utils.c +++ b/source/utils.c @@ -27,8 +27,6 @@ #include "draw.h" #include "cache.h" -extern bool isFirmlaunch; - u32 waitInput(void) { u32 pressedKey = 0, diff --git a/source/utils.h b/source/utils.h index bf74e1c..34b51eb 100644 --- a/source/utils.h +++ b/source/utils.h @@ -28,6 +28,8 @@ #define REG_TIMER_CNT(i) *(vu16 *)(0x10003002 + 4 * i) #define REG_TIMER_VAL(i) *(vu16 *)(0x10003000 + 4 * i) +extern bool isFirmlaunch; + u32 waitInput(void); void mcuReboot(void); void mcuPowerOff(void); From 94f0d873df3fccf45e914843345adab1d52a63e2 Mon Sep 17 00:00:00 2001 From: Aurora Date: Sat, 27 Aug 2016 17:34:37 +0200 Subject: [PATCH 3/4] Cleanup --- patches/twl_k11modules.s | 8 +++-- source/patches.c | 70 +++++++++++++++++----------------------- 2 files changed, 34 insertions(+), 44 deletions(-) diff --git a/patches/twl_k11modules.s b/patches/twl_k11modules.s index 117888d..88fcc30 100644 --- a/patches/twl_k11modules.s +++ b/patches/twl_k11modules.s @@ -44,7 +44,7 @@ patch: cmp r7, r6 bne end - ldr r7, =#0xabcdabcd ; offset of the dev launcher (will be replaced later) + ldr r7, [launcher] ; offset of the dev launcher (will be replaced later) add r7, r9 adr r5, patchesStart @@ -81,7 +81,9 @@ patch: end: - pop {r0-r11, pc} + pop {r0-r11, pc} + +launcher: .ascii "LAUN" .align 2 .thumb @@ -141,4 +143,4 @@ patchesEnd: .pool -.close \ No newline at end of file +.close diff --git a/source/patches.c b/source/patches.c index c7c2def..957a9b0 100644 --- a/source/patches.c +++ b/source/patches.c @@ -27,21 +27,19 @@ #include "../build/svcGetCFWInfopatch.h" #include "../build/twl_k11modulespatch.h" -static u32 *arm11ExceptionsPage = NULL; static u32 *arm11SvcTable = NULL; -static u32 *arm11SvcHandler = NULL; -static u8 *freeK11Space = NULL; //other than the one used for svcBackdoor +static u8 *freeK11Space = NULL; -static void findArm11ExceptionsPageAndSvcHandlerAndTable(u8 *pos, u32 size) -{ - const u8 arm11ExceptionsPagePattern[] = {0x00, 0xB0, 0x9C, 0xE5}; - - if(arm11ExceptionsPage == NULL) arm11ExceptionsPage = (u32 *)memsearch(pos, arm11ExceptionsPagePattern, size, 4) - 0xB; - if((arm11SvcTable == NULL || arm11SvcHandler == NULL) && arm11ExceptionsPage != NULL) +static void findArm11SvcTable(u8 *pos, u32 size) +{ + if(arm11SvcTable == NULL) { + const u8 pattern[] = {0x00, 0xB0, 0x9C, 0xE5}; + + u32 *arm11ExceptionsPage = (u32 *)memsearch(pos, pattern, size, 4) - 0xB; u32 svcOffset = (-((arm11ExceptionsPage[2] & 0xFFFFFF) << 2) & (0xFFFFFF << 2)) - 8; //Branch offset + 8 for prefetch - arm11SvcHandler = arm11SvcTable = (u32 *)(pos + *(u32 *)(pos + 0xFFFF0008 - svcOffset - 0xFFF00000 + 8) - 0xFFF00000); //SVC handler address + arm11SvcTable = (u32 *)(pos + *(u32 *)(pos + 0xFFFF0008 - svcOffset - 0xFFF00000 + 8) - 0xFFF00000); //SVC handler address while(*arm11SvcTable) arm11SvcTable++; //Look for SVC0 (NULL) } } @@ -50,21 +48,9 @@ static void findFreeK11Space(u8 *pos, u32 size) { if(freeK11Space == NULL) { - const u8 bogus_pattern[] = { 0x1E, 0xFF, 0x2F, 0xE1, 0x1E, 0xFF, 0x2F, 0xE1, 0x1E, 0xFF, - 0x2F, 0xE1, 0x00, 0x10, 0xA0, 0xE3, 0x00, 0x10, 0xC0, 0xE5, - 0x1E, 0xFF, 0x2F, 0xE1 }; + const u8 pattern[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; - u32 *someSpace = (u32 *)memsearch(pos, bogus_pattern, size, 24); - - // We couldn't find the place where to begin our search of an empty block - if (someSpace == NULL) - return; - - // Advance until we reach the padding area (filled with 0xFF) - u32 *freeSpace; - for(freeSpace = someSpace; *freeSpace != 0xFFFFFFFF; freeSpace++); - - freeK11Space = (u8 *)freeSpace; + freeK11Space = memsearch(pos, pattern, size, 5) + 1; } } @@ -154,31 +140,30 @@ void reimplementSvcBackdoor(u8 *pos, u32 size) 0x00, 0xD0, 0xA0, 0xE1, //mov sp, r0 0x11, 0xFF, 0x2F, 0xE1}; //bx r1 - findArm11ExceptionsPageAndSvcHandlerAndTable(pos, size); + findArm11SvcTable(pos, size); if(!arm11SvcTable[0x7B]) { - u32 *freeSpace; - for(freeSpace = arm11ExceptionsPage; *freeSpace != 0xFFFFFFFF; freeSpace++); + findFreeK11Space(pos, size); - memcpy(freeSpace, svcBackdoor, 40); + memcpy(freeK11Space, svcBackdoor, 40); - arm11SvcTable[0x7B] = 0xFFFF0000 + ((u8 *)freeSpace - (u8 *)arm11ExceptionsPage); + arm11SvcTable[0x7B] = 0xFFF00000 + freeK11Space - pos; + freeK11Space += 40; } } void implementSvcGetCFWInfo(u8 *pos, u32 size) { - const char *rev = REVISION; - bool isRelease; - - findArm11ExceptionsPageAndSvcHandlerAndTable(pos, size); findFreeK11Space(pos, size); memcpy(freeK11Space, svcGetCFWInfo, svcGetCFWInfo_size); CFWInfo *info = (CFWInfo *)memsearch(freeK11Space, "LUMA", svcGetCFWInfo_size, 4); + const char *rev = REVISION; + bool isRelease; + info->commitHash = COMMIT_HASH; info->config = configData.config; info->versionMajor = (u8)(rev[1] - '0'); @@ -188,12 +173,13 @@ void implementSvcGetCFWInfo(u8 *pos, u32 size) info->versionBuild = (u8)(rev[5] - '0'); isRelease = rev[6] == 0; } - else - isRelease = rev[4] == 0; + else isRelease = rev[4] == 0; info->flags = 0 /* master branch */ | (((isRelease) ? 1 : 0) << 1) /* is release */; - arm11SvcTable[0x2E] = 0xFFF00000 + freeK11Space - pos; //stubbed svc + findArm11SvcTable(pos, size); + + arm11SvcTable[0x2E] = 0xFFF00000 + freeK11Space - pos; //Stubbed svc freeK11Space += svcGetCFWInfo_size; } @@ -250,12 +236,14 @@ void applyLegacyFirmPatches(u8 *pos, FirmwareType firmType) void patchTwlBg(u8 *pos) { u8 *dst = pos + ((isN3DS) ? 0xFEA4 : 0xFCA0); - u16 *src1 = (u16 *)(pos + ((isN3DS) ? 0xE38 : 0xE3C)), *src2 = (u16 *)(pos + ((isN3DS) ? 0xE54 : 0xE58)); - memcpy(dst, twl_k11modules, twl_k11modules_size); //install k11 hook + + memcpy(dst, twl_k11modules, twl_k11modules_size); //Install K11 hook - u32 *off; - for(off = (u32 *)dst; *off != 0xABCDABCD; off++); - *off = (isN3DS) ? 0xCDE88 : 0xCD5F8; //dev SRL launcher offset + u32 *off = (u32 *)memsearch(dst, "LAUN", twl_k11modules_size, 4); + *off = (isN3DS) ? 0xCDE88 : 0xCD5F8; //Dev SRL launcher offset + + u16 *src1 = (u16 *)(pos + ((isN3DS) ? 0xE38 : 0xE3C)), + *src2 = (u16 *)(pos + ((isN3DS) ? 0xE54 : 0xE58)); //Construct BLX instructions: src1[0] = 0xF000 | ((((u32)dst - (u32)src1 - 4) & (0xFFF << 11)) >> 12); From a5c6b908b6d42cc2371710a73805041963766b4a Mon Sep 17 00:00:00 2001 From: TuxSH Date: Sat, 27 Aug 2016 18:10:51 +0200 Subject: [PATCH 4/4] Fix reboot patch for 5.x/6.x --- patches/reboot.s | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/patches/reboot.s b/patches/reboot.s index 799d156..9cb779f 100644 --- a/patches/reboot.s +++ b/patches/reboot.s @@ -5,10 +5,14 @@ payload_maxsize equ 0x10000 ; Maximum size for the payload (maximum that CakeB .create "build/reboot.bin", 0 .arm - ; Interesting registers and locations to keep in mind, set before this code is ran: - ; - sp + 0x3A8 - 0x70: FIRM path in exefs. - ; - r7 (which is sp + 0x3A8 - 0x198): Reserved space for file handle - ; - *(sp + 0x3A8 - 0x198) + 0x28: fread function. + ; Interesting registers and locations to keep in mind, set just before this code is ran: + ; - r1: FIRM path in exefs. + ; - r7: pointer to file object + ; - *r7: vtable + ; - *(vtable + 0x28): fread function + ; - *(r7 + 8): file handle + + mov r8, r1 pxi_wait_recv: ldr r2, =0x44846 @@ -47,7 +51,7 @@ payload_maxsize equ 0x10000 ; Maximum size for the payload (maximum that CakeB cmp r4, #0 movne r3, #0x12000 ; Skip the first 0x12000 bytes. moveq r3, payload_maxsize - ldr r6, [sp, #0x3A8-0x198] + ldr r6, [r7] ldr r6, [r6, #0x28] blx r6 cmp r4, #0 @@ -55,8 +59,7 @@ payload_maxsize equ 0x10000 ; Maximum size for the payload (maximum that CakeB bne read_payload ; Go read the real payload. ; Copy the low TID (in UTF-16) of the wanted firm to the 5th byte of the payload - add r0, sp, #0x3A8 - 0x70 - add r0, 0x1A + add r0, r8, 0x1A add r1, r0, #0x10 ldr r2, =payload_addr + 4 copy_TID_low: @@ -75,7 +78,7 @@ payload_maxsize equ 0x10000 ; Maximum size for the payload (maximum that CakeB goto_reboot: ; Jump to reboot code ldr r0, =(kernelcode_start - goto_reboot - 12) - add r0, pc + add r0, pc ; pc is two instructions ahead of the instruction being executed (12 = 2*4 + 4) swi 0x7B die: