From ab14e77b5014e3d880452a6ed76a3b1a217962c5 Mon Sep 17 00:00:00 2001 From: TuxSH Date: Thu, 18 May 2017 01:05:56 +0200 Subject: [PATCH] Remove A9LH & Brahma support altogether, use FIRM format instead --- Makefile | 13 ++-- injector/source/patcher.h | 1 - loader/source/main.c | 17 +++-- loader/source/start.s | 2 +- patches/emunand.s | 2 +- patches/k11modules.s | 2 +- patches/reboot.s | 145 ++++++++++++++++++++++++++++---------- patches/svcGetCFWInfo.s | 2 +- source/3dsheaders.h | 6 +- source/config.c | 12 +--- source/config.h | 3 +- source/crypto.c | 24 +------ source/crypto.h | 4 +- source/firm.c | 2 - source/firm.h | 3 + source/fs.c | 109 ++++++++++++++++++++++++---- source/main.c | 54 +++++++++++++- source/patches.c | 27 +------ source/start.s | 30 ++++---- source/types.h | 3 +- 20 files changed, 307 insertions(+), 154 deletions(-) diff --git a/Makefile b/Makefile index fc5f60c..61e668b 100644 --- a/Makefile +++ b/Makefile @@ -36,13 +36,13 @@ define bin2o endef .PHONY: all -all: a9lh +all: firm .PHONY: release release: $(dir_out)/$(name)$(revision).7z -.PHONY: a9lh -a9lh: $(dir_out)/arm9loaderhax.bin +.PHONY: firm +firm: $(dir_out)/boot.firm .PHONY: clean clean: @@ -63,12 +63,9 @@ $(dir_out)/$(name)$(revision).7z: all @mkdir -p "$(@D)" @7z a -mx $@ ./$(@D)/* ./$(dir_exceptions)/exception_dump_parser.py -$(dir_out)/arm9loaderhax.bin: $(dir_build)/main.bin +$(dir_out)/boot.firm: $(dir_build)/main.elf @mkdir -p "$(@D)" - @cp -a $(dir_build)/main.bin $@ - -$(dir_build)/main.bin: $(dir_build)/main.elf - $(OBJCOPY) -S -O binary $< $@ + @firmtool build $@ -e 0 -D $^ -C NDMA $(dir_build)/main.elf: $(bundled) $(objects) $(LINK.o) -T linker.ld $(OUTPUT_OPTION) $^ diff --git a/injector/source/patcher.h b/injector/source/patcher.h index 745c9c9..7b1d697 100644 --- a/injector/source/patcher.h +++ b/injector/source/patcher.h @@ -28,7 +28,6 @@ enum singleOptions AUTOBOOTEMU = 0, USEEMUFIRM, LOADEXTFIRMSANDMODULES, - USECUSTOMPATH, PATCHGAMES, PATCHVERSTRING, SHOWGBABOOT, diff --git a/loader/source/main.c b/loader/source/main.c index 143c8bf..d51815f 100644 --- a/loader/source/main.c +++ b/loader/source/main.c @@ -22,15 +22,20 @@ #include "memory.h" #include "cache.h" +#include "firm.h" -void main(u32 payloadSize) +void main(int argc __attribute__((unused)), char **argv) { - void *payloadAddress = (void *)0x23F00000; + Firm *firm = (Firm *)0x24000000; + char absPath[92]; - memcpy(payloadAddress, (void *)0x24000000, payloadSize); + u32 i; + for(i = 0; i < 91 && argv[1] != 0; i++) + absPath[i] = argv[1][i]; + for(; i < 91; i++) + absPath[i] = 0; - //Ensure that all memory transfers have completed and that the caches have been flushed - flushCaches(); + char *argvPassed[1] = {absPath}; - ((void (*)())payloadAddress)(); + launchFirm(firm, 1, argvPassed); } diff --git a/loader/source/start.s b/loader/source/start.s index 4dd90e5..07775ed 100644 --- a/loader/source/start.s +++ b/loader/source/start.s @@ -1,5 +1,5 @@ @ This file is part of Luma3DS -@ Copyright (C) 2016 Aurora Wright, TuxSH +@ Copyright (C) 2017 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 diff --git a/patches/emunand.s b/patches/emunand.s index b3433f6..b0d6643 100644 --- a/patches/emunand.s +++ b/patches/emunand.s @@ -45,4 +45,4 @@ sdmmc: .ascii "SDMC" nand_offset: .ascii "NAND" ; For rednand this should be 1 ncsd_header_offset: .ascii "NCSD" ; Depends on nand manufacturer + emunand type (GW/RED) -.close \ No newline at end of file +.close diff --git a/patches/k11modules.s b/patches/k11modules.s index cd803cb..525d0d5 100644 --- a/patches/k11modules.s +++ b/patches/k11modules.s @@ -102,4 +102,4 @@ b die .pool -.close \ No newline at end of file +.close diff --git a/patches/reboot.s b/patches/reboot.s index 3c51847..78d5b9a 100644 --- a/patches/reboot.s +++ b/patches/reboot.s @@ -2,9 +2,15 @@ .arm.little -payload_addr equ 0x23F00000 ; Brahma payload address -payload_maxsize equ 0x100000 ; Maximum size for the payload (maximum that CakeBrah supports) +argv_addr equ 0x27FFDF00 +fname_addr equ 0x27FFDF80 +low_tid_addr equ 0x27FFDFE0 +copy_launch_stub_addr equ 0x27FFE000 +firm_addr equ 0x24000000 +firm_maxsize equ (copy_launch_stub_addr - 0x1000 - firm_addr) + +arm11_entrypoint_addr equ 0x1FFFFFFC .create "build/reboot.bin", 0 .arm ; Interesting registers and locations to keep in mind, set just before this code is ran: @@ -28,42 +34,41 @@ payload_maxsize equ 0x100000 ; Maximum size for the payload (maximum that CakeB cmp r0, r2 bne pxi_wait_recv - mov r4, #2 + ; Open file + add r0, r7, #8 + adr r1, fname + mov r2, #1 + ldr r6, [fopen] + orr r6, 1 + blx r6 + cmp r0, #0 + bne panic - open_payload: - ; Open file - add r0, r7, #8 - adr r1, fname - mov r2, #1 - ldr r6, [fopen] - orr r6, 1 - blx r6 - cmp r0, #0 - beq read_payload - subs r4, r4, #1 - beq panic - adr r0, fname - adr r1, nand_mount - mov r2, #8 - bl memcpy16 - b open_payload - - read_payload: - ; Read file - mov r0, r7 - adr r1, bytes_read - ldr r2, =payload_addr - ldr r3, =payload_maxsize - ldr r6, [r7] - ldr r6, [r6, #0x28] - blx r6 + ; Read file + mov r0, r7 + adr r1, bytes_read + ldr r2, =firm_addr + ldr r3, =firm_maxsize + ldr r6, [r7] + ldr r6, [r6, #0x28] + blx r6 ; Copy the low TID (in UTF-16) of the wanted firm to the 5th byte of the payload - ldr r0, =payload_addr + 4 + ldr r0, =low_tid_addr add r1, r8, #0x1A mov r2, #0x10 bl memcpy16 + ldr r0, =fname_addr + adr r1, fname + mov r2, #42 + bl memcpy16 + + ldr r0, =argv_addr + ldr r1, =fname_addr + ldr r2, =low_tid_addr + stmia r0, {r1, r2} + ; Set kernel state mov r0, #0 mov r1, #0 @@ -81,12 +86,14 @@ payload_maxsize equ 0x100000 ; Maximum size for the payload (maximum that CakeB b die memcpy16: + cmp r2, #0 + bxeq lr add r2, r0, r2 - copy_loop: + copy_loop16: ldrh r3, [r1], #2 strh r3, [r0], #2 cmp r0, r2 - blo copy_loop + blo copy_loop16 bx lr panic: @@ -98,7 +105,7 @@ payload_maxsize equ 0x100000 ; Maximum size for the payload (maximum that CakeB bytes_read: .word 0 fopen: .ascii "OPEN" .pool -fname: .dcw "sdmc:/arm9loaderhax.bin" +fname: .dcw "sdmc:/arm9loaderha.firm" .word 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 .pool nand_mount: .dcw "nand" @@ -106,12 +113,75 @@ nand_mount: .dcw "nand" .align 4 kernelcode_start: - ldr sp, =0x080FF000 + mrs r0, cpsr ; disable interrupts + orr r0, #0xC0 + msr cpsr, r0 + + ldr sp, =0x27FFDF00 + + ldr r0, =copy_launch_stub_addr + adr r1, copy_launch_stub + mov r2, #(copy_launch_stub_end - copy_launch_stub) + bl memcpy32 ; Disable MPU ldr r0, =0x42078 ; alt vector select, enable itcm mcr p15, 0, r0, c1, c0, 0 + bl flushCaches + + ldr r0, =copy_launch_stub_addr + bx r0 + + copy_launch_stub: + + ldr r4, =firm_addr + + mov r5, #0 + load_section_loop: + ; Such checks. Very ghetto. Wow. + add r3, r4, #0x40 + add r3, r5,lsl #5 + add r3, r5,lsl #4 + ldmia r3, {r6-r8} + mov r0, r7 + add r1, r4, r6 + mov r2, r8 + bl memcpy32 + add r5, #1 + cmp r5, #3 + blo load_section_loop + + ldr r0, =arm11_entrypoint_addr + ldr r1, [r4, #0x08] + str r1, [r0] + + mov r0, #2 ; argc + ldr r1, =argv_addr ; argv + ldr r2, =0xBEEF ; magic word + + ldr r5, =arm11_entrypoint_addr + ldr r6, [r4, #0x08] + str r6, [r5] + + ldr lr, [r4, #0x0c] + bx lr + + memcpy32: + cmp r2, #0 + bxeq lr + add r2, r0, r2 + copy_loop32: + ldr r3, [r1], #4 + str r3, [r0], #4 + cmp r0, r2 + blo copy_loop32 + bx lr + + copy_launch_stub_end: + + flushCaches: + ; Clean and flush data cache mov r1, #0 ; segment counter outer_loop: @@ -134,10 +204,7 @@ nand_mount: .dcw "nand" ; Flush instruction cache mcr p15, 0, r1, c7, c5, 0 - ; Jump to payload - ldr r0, =payload_addr - bx r0 + bx lr .pool .close - diff --git a/patches/svcGetCFWInfo.s b/patches/svcGetCFWInfo.s index cfb11ee..66b54e8 100644 --- a/patches/svcGetCFWInfo.s +++ b/patches/svcGetCFWInfo.s @@ -45,4 +45,4 @@ infoStart: .word 0 ; truncated commit hash .word 0 ; config infoEnd: -.close \ No newline at end of file +.close diff --git a/source/3dsheaders.h b/source/3dsheaders.h index 7e7bfd0..bdbbefe 100644 --- a/source/3dsheaders.h +++ b/source/3dsheaders.h @@ -24,6 +24,8 @@ * Adapted from 3DBrew and https://github.com/mid-kid/CakesForeveryWan/blob/master/source/headers.h */ +#pragma once + typedef struct __attribute__((packed)) { u32 address; @@ -139,7 +141,7 @@ typedef struct __attribute__((packed)) typedef struct __attribute__((packed)) { - u32 magic; + char magic[4]; u32 reserved1; u8 *arm11Entry; u8 *arm9Entry; @@ -158,4 +160,4 @@ typedef struct __attribute__((packed)) char magic[4]; u8 reserved2[0xC]; u8 slot0x16keyX[0x10]; -} Arm9Bin; \ No newline at end of file +} Arm9Bin; diff --git a/source/config.c b/source/config.c index d355648..e01f9c4 100644 --- a/source/config.c +++ b/source/config.c @@ -84,7 +84,6 @@ void configMenu(bool isSdMode, bool oldPinStatus, u32 oldPinMode) const char *singleOptionsText[] = { "( ) Autoboot EmuNAND", "( ) Use EmuNAND FIRM if booting with R", "( ) Enable loading external FIRMs and modules", - "( ) Use custom path", "( ) Enable game patching", "( ) Show NAND or user string in System Settings", "( ) Show GBA boot screen in patched AGB_FIRM", @@ -147,10 +146,6 @@ void configMenu(bool isSdMode, bool oldPinStatus, u32 oldPinMode) "This isn't needed in most cases.\n\n" "Refer to the wiki for instructions.", - "Use a custom path for the\n" - "Luma3DS payload.\n\n" - "Refer to the wiki for instructions.", - "Enable overriding the region and\n" "language configuration and the usage\n" "of patched code binaries,\n" @@ -195,8 +190,8 @@ void configMenu(bool isSdMode, bool oldPinStatus, u32 oldPinMode) "Enable Luma3DS's ARM9/ARM11 exception\n" "handlers.\n" - "A9LH is required, and Luma3DS should\n" - "be ran as arm9loaderhax.bin.\n" + "Luma3DS should be ran as:\n" + "arm9loaderhax.bin\n\n" "Useful for debugging." }; @@ -226,8 +221,7 @@ void configMenu(bool isSdMode, bool oldPinStatus, u32 oldPinMode) { .visible = true }, { .visible = true }, { .visible = true }, - { .visible = true }, - { .visible = true} + { .visible = true } }; //Calculate the amount of the various kinds of options and pre-select the first single one diff --git a/source/config.h b/source/config.h index 480a014..e7bc916 100644 --- a/source/config.h +++ b/source/config.h @@ -30,7 +30,7 @@ #define CONFIG_FILE "config.bin" #define CONFIG_VERSIONMAJOR 1 -#define CONFIG_VERSIONMINOR 10 +#define CONFIG_VERSIONMINOR 11 #define BOOTCFG_NAND BOOTCONFIG(0, 7) #define BOOTCFG_FIRM BOOTCONFIG(3, 7) @@ -50,7 +50,6 @@ enum singleOptions AUTOBOOTEMU = 0, USEEMUFIRM, LOADEXTFIRMSANDMODULES, - USECUSTOMPATH, PATCHGAMES, PATCHVERSTRING, SHOWGBABOOT, diff --git a/source/crypto.c b/source/crypto.c index 647d6b3..8a1e10a 100755 --- a/source/crypto.c +++ b/source/crypto.c @@ -230,7 +230,7 @@ static void aes_batch(void *dst, const void *src, u32 blockCount) } } -static void aes(void *dst, const void *src, u32 blockCount, void *iv, u32 mode, u32 ivMode) +void aes(void *dst, const void *src, u32 blockCount, void *iv, u32 mode, u32 ivMode) { *REG_AESCNT = mode | AES_CNT_INPUT_ORDER | AES_CNT_OUTPUT_ORDER | @@ -278,10 +278,8 @@ static void sha_wait_idle() while(*REG_SHA_CNT & 1); } -static void sha(void *res, const void *src, u32 size, u32 mode) +void sha(void *res, const void *src, u32 size, u32 mode) { - backupAndRestoreShaHash(false); - sha_wait_idle(); *REG_SHA_CNT = mode | SHA_CNT_OUTPUT_ENDIAN | SHA_NORMAL_ROUND; @@ -571,21 +569,3 @@ void computePinHash(u8 *outbuf, const u8 *inbuf) aes(cipherText, inbuf, 1, cid, AES_CBC_ENCRYPT_MODE, AES_INPUT_BE | AES_INPUT_NORMAL); sha(outbuf, cipherText, sizeof(cipherText), SHA_256_MODE); } - -void backupAndRestoreShaHash(bool isRestore) -{ - if(ISSIGHAX) return; - - static bool didShaHashBackup = false; - __attribute__((aligned(4))) static u8 shaHashBackup[SHA_256_HASH_SIZE]; - - if(isRestore) - { - if(didShaHashBackup) memcpy((void *)REG_SHA_HASH, shaHashBackup, sizeof(shaHashBackup)); - } - else if(!didShaHashBackup) - { - memcpy(shaHashBackup, (void *)REG_SHA_HASH, sizeof(shaHashBackup)); - didShaHashBackup = true; - } -} diff --git a/source/crypto.h b/source/crypto.h index f914beb..a41bd2f 100755 --- a/source/crypto.h +++ b/source/crypto.h @@ -107,6 +107,9 @@ extern u32 emuOffset; extern FirmwareSource firmSource; +void aes(void *dst, const void *src, u32 blockCount, void *iv, u32 mode, u32 ivMode); +void sha(void *res, const void *src, u32 size, u32 mode); + void ctrNandInit(void); int ctrNandRead(u32 sector, u32 sectorCount, u8 *outbuf); int ctrNandWrite(u32 sector, u32 sectorCount, const u8 *inbuf); @@ -114,4 +117,3 @@ bool decryptExeFs(Cxi *cxi); bool decryptNusFirm(const Ticket *ticket, Cxi *cxi, u32 ncchSize); void kernel9Loader(Arm9Bin *arm9Section); void computePinHash(u8 *outbuf, const u8 *inbuf); -void backupAndRestoreShaHash(bool isRestore); diff --git a/source/firm.c b/source/firm.c index 59c415d..d127ce5 100755 --- a/source/firm.c +++ b/source/firm.c @@ -35,8 +35,6 @@ #include "fmt.h" #include "../build/bundled.h" -static Firm *firm = (Firm *)0x24000000; - static inline bool loadFirmFromStorage(FirmwareType firmType) { const char *firmwareFiles[] = { diff --git a/source/firm.h b/source/firm.h index cb6f4a5..2afcfa6 100644 --- a/source/firm.h +++ b/source/firm.h @@ -23,6 +23,9 @@ #pragma once #include "types.h" +#include "3dsheaders.h" + +static Firm *const firm = (Firm *const)0x24000000; u32 loadFirm(FirmwareType *firmType, FirmwareSource nandType, bool loadFromStorage, bool isSafeMode); u32 patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32 emuHeader, bool isSafeMode, bool doUnitinfoPatch, bool enableExceptionHandlers); diff --git a/source/fs.c b/source/fs.c index 8fc5652..37c9846 100644 --- a/source/fs.c +++ b/source/fs.c @@ -32,6 +32,8 @@ #include "config.h" #include "fatfs/ff.h" #include "buttons.h" +#include "firm.h" +#include "crypto.h" #include "../build/bundled.h" static FATFS sdFs, @@ -116,12 +118,80 @@ void fileDelete(const char *path) f_unlink(path); } +static __attribute__((noinline)) bool overlaps(u32 as, u32 ae, u32 bs, u32 be) +{ + if (as <= bs && bs <= ae) + return true; + else if (bs <= as && as <= be) + return true; + return false; +} + +static bool checkFirmPayload(void) +{ + if(memcmp(firm->magic, "FIRM", 4) != 0) + return false; + + if(firm->arm9Entry == NULL) //allow for the arm11 entrypoint to be zero in which case nothing is done on the arm11 side + return false; + + u32 size = 0x200; + for(u32 i = 0; i < 4; i++) + size += firm->section[i].size; + + bool arm9EpFound = false, arm11EpFound = false; + for(u32 i = 0; i < 4; i++) + { + __attribute__((aligned(4))) u8 hash[0x20]; + + FirmSection *section = &firm->section[i]; + + // allow empty sections + if (section->size == 0) + continue; + + if(section->offset < 0x200) + return false; + + if(section->address + section->size < section->address) //overflow check + return false; + + if(((u32)section->address & 3) || (section->offset & 0x1FF) || (section->size & 0x1FF)) //alignment check + return false; + + if(overlaps((u32)section->address, (u32)section->address + section->size, 0x27FFE000, 0x28000000)) + return false; + else if(overlaps((u32)section->address, (u32)section->address + section->size, 0x27FFE000 - 0x1000, 0x27FFE000)) + return false; + else if(overlaps((u32)section->address, (u32)section->address + section->size, (u32)firm, (u32)firm + size)) + return false; + + sha(hash, (u8 *)firm + section->offset, section->size, SHA_256_MODE); + if(memcmp(hash, section->hash, 0x20) != 0) + return false; + + if(firm->arm9Entry >= section->address && firm->arm9Entry < (section->address + section->size)) + arm9EpFound = true; + + if(firm->arm11Entry >= section->address && firm->arm11Entry < (section->address + section->size)) + arm11EpFound = true; + } + + return arm9EpFound && (firm->arm11Entry == NULL || arm11EpFound); +} + void loadPayload(u32 pressed, const char *payloadPath) { u32 *loaderAddress = (u32 *)0x27FFE000; - u8 *payloadAddress = (u8 *)0x24000000; u32 payloadSize = 0, - maxPayloadSize = 0xFFE00; + maxPayloadSize = (u32)((u8 *)loaderAddress - (u8 *)firm); + + char path[62] = {0}, + absPath[92] = {0}; + + char mountPoint[5] = {0}; + for(u32 i = 0; i < 4 && launchedPath[i] != ':'; i++) + mountPoint[i] = launchedPath[i]; if(payloadPath == NULL) { @@ -142,7 +212,6 @@ void loadPayload(u32 pressed, const char *payloadPath) DIR dir; FILINFO info; FRESULT result; - char path[22]; result = f_findfirst(&dir, &info, "payloads", pattern); @@ -153,24 +222,36 @@ void loadPayload(u32 pressed, const char *payloadPath) if(!info.fname[0]) return; sprintf(path, "payloads/%s", info.altname); - payloadSize = fileRead(payloadAddress, path, maxPayloadSize); - } - else payloadSize = fileRead(payloadAddress, payloadPath, maxPayloadSize); + if(memcmp(mountPoint, "nand", 4)) + sprintf(absPath, "nand:/rw/luma/payloads/%s", info.altname); + else + sprintf(absPath, "%s:/luma/payloads/%s", mountPoint, info.altname); - if(!payloadSize) return; + payloadSize = fileRead(firm, path, maxPayloadSize); + } + else + { + if(memcmp(mountPoint, "nand", 4)) + sprintf(absPath, "nand:/rw/luma/payloads/%s", payloadPath); + else + sprintf(absPath, "%s:/luma/payloads/%s", mountPoint, payloadPath); + + payloadSize = fileRead(firm, payloadPath, maxPayloadSize); + } + + if(!payloadSize || !checkFirmPayload()) return; writeConfig(true); + char *argv[1] = {absPath}; memcpy(loaderAddress, loader_bin, loader_bin_size); - if(ISN3DS) kernel9Loader(NULL); - backupAndRestoreShaHash(true); initScreens(); flushDCacheRange(loaderAddress, loader_bin_size); flushICacheRange(loaderAddress, loader_bin_size); - ((void (*)(u32))loaderAddress)(payloadSize); + ((void (*)(int, char **, u32))loaderAddress)(1, argv, 0x0000BEEF); } void payloadMenu(void) @@ -190,11 +271,11 @@ void payloadMenu(void) u32 nameLength = strlen(info.fname); - if(nameLength < 5 || nameLength > 52) continue; + if(nameLength < 6 || nameLength > 52) continue; - nameLength -= 4; + nameLength -= 5; - if(memcmp(info.fname + nameLength, ".bin", 4) != 0) continue; + if(memcmp(info.fname + nameLength, ".firm", 5) != 0) continue; memcpy(payloadList[payloadNum], info.fname, nameLength); payloadList[payloadNum][nameLength] = 0; @@ -258,7 +339,7 @@ void payloadMenu(void) if(pressed != BUTTON_START) { - sprintf(path, "payloads/%s.bin", payloadList[selectedPayload]); + sprintf(path, "payloads/%s.firm", payloadList[selectedPayload]); loadPayload(0, path); error("The payload is too large or corrupted."); } diff --git a/source/main.c b/source/main.c index acb84d8..6c5ab62 100644 --- a/source/main.c +++ b/source/main.c @@ -32,12 +32,16 @@ #include "pin.h" #include "crypto.h" #include "fmt.h" +#include "memory.h" extern CfgData configData; extern ConfigurationStatus needConfig; extern FirmwareSource firmSource; -void main(void) +u16 launchedFirmTidLow[8]; +u16 launchedPath[42]; + +void main(int argc, char **argv) { bool isSafeMode = false, isNoForceFlagSet = false; @@ -45,15 +49,59 @@ void main(void) FirmwareType firmType; FirmwareSource nandType; + switch(argc) + { + case 0: + error("Unsupported launcher."); + break; + + case 1: //Normal boot + { + u32 i; + for(i = 0; i < 41 && launchedPath[i] != 0; i++) //Copy and convert the path to utf16 + launchedPath[2 * i] = argv[0][i]; + for(; i < 41; i++) + launchedPath[i] = 0; + + for(u32 i = 0; i < 8; i++) + launchedFirmTidLow[i] = 0; + break; + } + + case 2: //Firmlaunch + { + u32 i; + u16 *p = (u16 *)argv[0]; + for(i = 0; i < 41 && launchedPath[i] != 0; i++) + launchedPath[i] = p[i]; + for(; i < 41; i++) + launchedPath[i] = 0; + + memcpy(launchedFirmTidLow, (u16 *)argv[1], 16); + break; + } + } + + char mountPoint[5] = {0}; + for(u32 i = 0; i < 4 && argv[0][i] != ':'; i++) + mountPoint[i] = argv[0][i]; + //Mount SD or CTRNAND bool isSdMode; - if(mountFs(true, false)) isSdMode = true; - else + + if(memcmp(mountPoint, "sdmc", 4) == 0) + { + if(!mountFs(true, false)) error("Failed to mount SD."); + isSdMode = true; + } + else if(memcmp(mountPoint, "nand", 4) == 0) { firmSource = FIRMWARE_SYSNAND; if(!mountFs(false, true)) error("Failed to mount SD and CTRNAND."); isSdMode = false; } + else + error("Launched from an unsupported location"); //Attempt to read the configuration file needConfig = readConfig() ? MODIFY_CONFIGURATION : CREATE_CONFIGURATION; diff --git a/source/patches.c b/source/patches.c index 9d939a2..89850fd 100644 --- a/source/patches.c +++ b/source/patches.c @@ -37,30 +37,6 @@ #include "utils.h" #include "../build/bundled.h" -static inline void pathChanger(u8 *pos) -{ - const char *pathFile = "path.txt"; - u8 path[57]; - - u32 pathSize = fileRead(path, pathFile, sizeof(path)); - - if(pathSize < 6) return; - - if(path[pathSize - 1] == 0xA) pathSize--; - if(path[pathSize - 1] == 0xD) pathSize--; - - if(pathSize < 6 || pathSize > 55 || path[0] != '/' || memcmp(path + pathSize - 4, ".bin", 4) != 0) return; - - u16 finalPath[56]; - for(u32 i = 0; i < pathSize; i++) - finalPath[i] = (u16)path[i]; - - finalPath[pathSize] = 0; - - u8 *posPath = memsearch(pos, u"sd", reboot_bin_size, 4) + 0xA; - memcpy(posPath, finalPath, (pathSize + 1) * 2); -} - u8 *getProcess9Info(u8 *pos, u32 size, u32 *process9Size, u32 *process9MemAddr) { u8 *temp = memsearch(pos, "NCCH", size, 4); @@ -159,7 +135,8 @@ u32 patchFirmlaunches(u8 *pos, u32 size, u32 process9MemAddr) u32 *pos_fopen = (u32 *)memsearch(off, "OPEN", reboot_bin_size, 4); *pos_fopen = fOpenOffset; - if(CONFIG(USECUSTOMPATH)) pathChanger(off); + //u16 *fname = (u16 *)memsearch(off, u"sd", reboot_bin_size, 4); + //memcpy(fname, u"sdmc:/test.firm", 32); return 0; } diff --git a/source/start.s b/source/start.s index 675fc89..2a05828 100644 --- a/source/start.s +++ b/source/start.s @@ -24,32 +24,31 @@ .align 4 .global _start _start: - b start - -.global launchedFirmTidLow -launchedFirmTidLow: - .hword 0, 0, 0, 0, 0, 0, 0, 0 - -start: @ Disable interrupts - mrs r0, cpsr - orr r0, #0x1C0 - msr cpsr_cx, r0 + mrs r4, cpsr + orr r4, #0x1C0 + msr cpsr_cx, r4 + + ldr r4, =0xBEEF + cmp r2, r4 + movne r0, #0 @ check magic word @ Change the stack pointer mov sp, #0x27000000 @ Disable caches / MPU - mrc p15, 0, r0, c1, c0, 0 @ read control register - bic r0, #(1<<12) @ - instruction cache disable - bic r0, #(1<<2) @ - data cache disable - bic r0, #(1<<0) @ - mpu disable - mcr p15, 0, r0, c1, c0, 0 @ write control register + mrc p15, 0, r4, c1, c0, 0 @ read control register + bic r4, #(1<<12) @ - instruction cache disable + bic r4, #(1<<2) @ - data cache disable + bic r4, #(1<<0) @ - mpu disable + mcr p15, 0, r4, c1, c0, 0 @ write control register @ Flush caches bl flushEntireDCache bl flushEntireICache + push {r0-r3} + @ Give read/write access to all the memory regions ldr r0, =0x3333333 mcr p15, 0, r0, c5, c0, 2 @ write data access @@ -98,4 +97,5 @@ start: sub r2, r0 bl memset32 + pop {r0-r3} b main diff --git a/source/types.h b/source/types.h index ec01e22..419068b 100644 --- a/source/types.h +++ b/source/types.h @@ -115,4 +115,5 @@ typedef enum FirmwareType NATIVE_FIRM1X2X } FirmwareType; -extern u16 launchedFirmTidLow[8]; //Defined in start.s +extern u16 launchedFirmTidLow[8]; +extern u16 launchedPath[42];