From ceaeb935f3270dafa357f4d3099ed0f392df3fd9 Mon Sep 17 00:00:00 2001 From: chaoskagami Date: Tue, 7 Jun 2016 10:04:42 -0400 Subject: [PATCH] Reboot code is working now (but evidently without patches of any sort) --- Makefile | 2 +- host/bytecode_asm.py | 25 +++++++++++++++++++++---- source/firm/firm.c | 9 ++++++--- source/interp.c | 13 +++++++++++++ source/menu.c | 2 +- source/patch/reboot.c | 14 +++++++++++--- source/patch/svc.c | 25 +++++++++++-------------- 7 files changed, 64 insertions(+), 26 deletions(-) diff --git a/Makefile b/Makefile index 6971f18..5bd904c 100644 --- a/Makefile +++ b/Makefile @@ -20,7 +20,7 @@ dir_out := out REVISION := r$(shell git rev-list --count HEAD):$(shell git rev-parse HEAD | head -c8) ASFLAGS := -mlittle-endian -mcpu=arm946e-s -march=armv5te -CFLAGS := -MMD -MP -Wall -Wextra -Werror -fno-omit-frame-pointer -Os $(ASFLAGS) -fno-builtin -std=c11 -DVERSION=\"$(REVISION)\" +CFLAGS := -MMD -MP -Wall -Wextra -Werror -fomit-frame-pointer -Os $(ASFLAGS) -fshort-wchar -fno-builtin -std=c11 -DVERSION=\"$(REVISION)\" FLAGS := dir_out=$(abspath $(dir_out)) --no-print-directory LDFLAGS := -nostdlib -Wl,-z,defs -lgcc -Wl,-Map,$(dir_build)/link.map diff --git a/host/bytecode_asm.py b/host/bytecode_asm.py index 36f0b4b..a32945a 100755 --- a/host/bytecode_asm.py +++ b/host/bytecode_asm.py @@ -100,7 +100,6 @@ def parse_op(token_list, instr_offs): return bytearray() - if token_list[0] == "nop": # Nop. Expects 0 args. return bytearray.fromhex("00") elif token_list[0] == "rel": # Rel. Expects one argument. Possibly requires mapping. @@ -183,6 +182,13 @@ def parse_op(token_list, instr_offs): return bytearray.fromhex("0D") + bytearray.fromhex(token_list[1]) elif token_list[0] == "clf": return bytearray.fromhex("0E") + elif token_list[0] == "seek": + if s != 2: + syn_err("invalid number of arguments") + + v = bytearray.fromhex(token_list[1]) + v.reverse() + return bytearray.fromhex("0F") + v elif token_list[0] == "jmpeq": if s != 2: syn_err("invalid number of arguments") @@ -275,8 +281,8 @@ except: exit(1) size = 0 - offsets = [] +labels = [] with open(in_file, "r") as ins: with open(out_file, "wb") as writ: @@ -286,22 +292,33 @@ with open(in_file, "r") as ins: # One to figure out the opcode offsets, one # to actually parse everything. + # FIXME - We need label support ASAP. The AGB and TWL patches I wrote make my head hurt. + for line in ins: lines += 1 tokens = re.split("\s+", line.strip("\n")) # Split by whitespace. - bytes = parse_op(tokens, None) # Parse. + try: + bytes = parse_op(tokens, None) # Parse. + except: + print("Error on line " + str(lines)) + exit(1) if bytes: offsets += [size] size += len(bytes) offsets += [size+1] # So we can jump past the last instruction for 'exit' type behavior + lines = 0 ins.seek(0) for line in ins: lines += 1 tokens = re.split("\s+", line.strip("\n")) # Split by whitespace. - bytes = parse_op(tokens, offsets) # Parse. + try: + bytes = parse_op(tokens, offsets) # Parse. + except: + print("Error on line " + str(lines)) + exit(1) if bytes: bytecode += bytes diff --git a/source/firm/firm.c b/source/firm/firm.c index a9fcd7c..ec9de2e 100644 --- a/source/firm/firm.c +++ b/source/firm/firm.c @@ -425,8 +425,6 @@ boot_cfw() if (config.options[OPTION_RECONFIGURED]) { fprintf(stderr, "Generating patch cache...\n"); generate_patch_cache(); - config.options[OPTION_RECONFIGURED] = 0; - save_config(); } fprintf(BOTTOM_SCREEN, "Patching firmware...\n"); @@ -434,7 +432,7 @@ boot_cfw() return; if (config.options[OPTION_REBOOT] && config.options[OPTION_RECONFIGURED]) { - fprintf(stderr, "Saving FIRMs for reboot..."); + fprintf(stderr, "Saving FIRM for reboot...\n"); if (!write_file(firm_loc, PATH_NATIVE_P, firm_size)) abort("Failed to save prepatched native\n"); @@ -445,5 +443,10 @@ boot_cfw() abort("Failed to save prepatched agb\n"); } + if (config.options[OPTION_RECONFIGURED]) { + config.options[OPTION_RECONFIGURED] = 0; + save_config(); + } + boot_firm(); } diff --git a/source/interp.c b/source/interp.c index 03958a8..6310d6b 100644 --- a/source/interp.c +++ b/source/interp.c @@ -23,6 +23,7 @@ #define OP_NOT 0x0C #define OP_VER 0x0D #define OP_CLF 0x0E +#define OP_SEEK 0x0F #define OP_JMPEQ 0x17 #define OP_JMPNE 0x27 @@ -327,6 +328,18 @@ exec_bytecode(uint8_t *bytecode, uint16_t ver, uint32_t len, int debug) eq = !eq; code += 2; break; + case OP_SEEK: // Jump to offset if greater than or equal + if (debug) + log("seek\n"); + code++; + offset = code[3] + (code[2] * 0x100) + (code[1] * 0x10000) + (code[0] * 0x1000000); + if (offset > current_mode->size) { + // Went out of bounds. Error. + abort("seeked out of bounds\n"); + } + else + code += 4; + break; case OP_NEXT: if (debug) log("next\n"); diff --git a/source/menu.c b/source/menu.c index b49d98d..676806f 100644 --- a/source/menu.c +++ b/source/menu.c @@ -23,7 +23,7 @@ static struct options_s options[] = { { OPTION_SVCS, "SVC Replacement", "Replaces ARM11 svc calls, including svcBackdoor. With 11.0 NATIVE_FIRM, you probably want this.", boolean_val, 0, 0 }, - { OPTION_REBOOT, "Reboot Hook", "Hooks firmlaunch to keep the CFW resident on o3DS and allow patching TWL/AGB firms as well.", boolean_val, 0, 0 }, + { OPTION_REBOOT, "Reboot Hook", "Hooks firmlaunch to allow largemem games on o3DS (and allow patching TWL/AGB on all consoles)", boolean_val, 0, 0 }, { OPTION_EMUNAND, "Use EmuNAND", "Redirects NAND write/read to the SD.", boolean_val, 0, 0 }, { OPTION_EMUNAND_INDEX, " Index", "Which EmuNAND to use. Currently, 10 maximum (but this is arbitrary)", ranged_val, 0, 0x9 }, diff --git a/source/patch/reboot.c b/source/patch/reboot.c index 47f9db5..4b120f6 100644 --- a/source/patch/reboot.c +++ b/source/patch/reboot.c @@ -73,20 +73,26 @@ void patch_reboot() { *pos_native = (uint32_t)mem; memcpy(mem, L"sdmc:", 10); mem += 10; - for(size_t i=0; i < sizeof(PATH_NATIVE_P); i++, mem += 2) + for(size_t i=0; i < sizeof(PATH_NATIVE_P); i++, mem += 2) { *mem = PATH_NATIVE_P[i]; + *(mem + 1) = 0; + } *pos_twl = (uint32_t)mem; memcpy(mem, L"sdmc:", 10); mem += 10; - for(size_t i=0; i < sizeof(PATH_TWL_P); i++, mem += 2) + for(size_t i=0; i < sizeof(PATH_TWL_P); i++, mem += 2) { *mem = PATH_TWL_P[i]; + *(mem + 1) = 0; + } *pos_agb = (uint32_t)mem; memcpy(mem, L"sdmc:", 10); mem += 10; - for(size_t i=0; i < sizeof(PATH_AGB_P); i++, mem += 2) + for(size_t i=0; i < sizeof(PATH_AGB_P); i++, mem += 2) { *mem = PATH_AGB_P[i]; + *(mem + 1) = 0; + } uint32_t *pos_rebc = (uint32_t*)memfind(off, size, "rebc", 4); *pos_rebc = (uint32_t)mem; @@ -99,4 +105,6 @@ void patch_reboot() { fread(mem, 1, fsize(f), f); fclose(f); + + write_file((void*)0x1FF8000, "/test", 0x8000); } diff --git a/source/patch/svc.c b/source/patch/svc.c index 6cd22a5..05391eb 100644 --- a/source/patch/svc.c +++ b/source/patch/svc.c @@ -41,6 +41,13 @@ PATCH(services) at[0] = ("0123456789abcdef")[i]; for (uint32_t j = 0; j < 0xf; j++) { + uint32_t svc = (i << 4) & j; // Actual svc index. + + // Refuse to replace non-NULL services unless the user has it enabled. + // Also don't bother checking for non-null svc files (it's slow.) + if (svcTable[svc] && !config.options[OPTION_REPLACE_ALLOCATED_SVC]) + continue; + // This is just hexdump. Nothing complicated. at[1] = ("0123456789abcdef")[j]; @@ -48,34 +55,24 @@ PATCH(services) if (!data) continue; // No file for svc. Move on. - uint32_t svc = (i << 4) & j; - - // Refuse to replace non-NULL services unless the user says to. - if (svcTable[svc] && !config.options[OPTION_REPLACE_ALLOCATED_SVC]) { - fclose(data); - fprintf(stderr, "Svc: %x non-null, moving on\n", i); - continue; - } - // TODO - We can just fread directly to freeSpace with a little reordering. uint32_t size = fsize(data); fprintf(stderr, "Svc: %s, %d bytes\n", at, size); - if (!freeSpace) { - for (freeSpace = exceptionsPage; *freeSpace != 0xFFFFFFFF; freeSpace++) - ; - } + if (!freeSpace) + for (freeSpace = exceptionsPage; *freeSpace != 0xFFFFFFFF; freeSpace++); fprintf(stderr, "Svc: Copy code to %x\n", (uint32_t)freeSpace); fread(freeSpace, 1, size, data); + fclose(data); svcTable[svc] = 0xFFFF0000 + ((uint8_t *)freeSpace - (uint8_t *)exceptionsPage); - freeSpace += size; // We keep track of this because there's more than 7B free. + freeSpace += size; fprintf(stderr, "Svc: entry set as %x\n", svcTable[svc]); } -- 2.39.5