]> Chaos Git - corbenik/corbenik.git/commitdiff
Relocation is sort-of-working, but sigpatch is broken due to (maybe) compiler black...
authorroot <chaos.kagami@gmail.com>
Tue, 17 May 2016 02:27:28 +0000 (22:27 -0400)
committerroot <chaos.kagami@gmail.com>
Tue, 17 May 2016 02:27:28 +0000 (22:27 -0400)
66 files changed:
Makefile
asm/backdoor.s
copy.sh
patchbins/README.txt [deleted file]
patchbins/firmprot/src/exported.h [deleted file]
patchbins/firmprot/src/link_table.s [deleted file]
patchbins/firmprot/src/main.c [deleted file]
patchbins/firmprot/src/patcher.c [deleted file]
patchbins/firmprot/src/start.s [deleted file]
patchbins/firmprot/tool/compile_header.c [deleted file]
patchbins/signatures/Makefile [deleted file]
patchbins/signatures/linker.ld [deleted file]
patchbins/signatures/src/link_table.s [deleted file]
patchbins/signatures/src/main.c [deleted file]
patchbins/signatures/src/start.s [deleted file]
patchbins/template/Makefile [deleted file]
patchbins/template/linker.ld [deleted file]
patchbins/template/meta/cfw_version [deleted file]
patchbins/template/meta/deps [deleted file]
patchbins/template/meta/desc [deleted file]
patchbins/template/meta/name [deleted file]
patchbins/template/meta/patch_version [deleted file]
patchbins/template/meta/title [deleted file]
patchbins/template/meta/uuid [deleted file]
patchbins/template/src/exported.h [deleted file]
patchbins/template/src/link_table.s [deleted file]
patchbins/template/src/start.s [deleted file]
patchbins/template/tool/compile_header.c [deleted file]
source/firm/firm.c
source/linker.c
source/patch_format.h
source/patcher.c
source/start.s
source/std/draw.c
vco/Makefile [new file with mode: 0644]
vco/README.txt [new file with mode: 0644]
vco/signatures/Makefile [new symlink]
vco/signatures/linker.ld [new symlink]
vco/signatures/meta/cfw_version [moved from patchbins/firmprot/meta/cfw_version with 100% similarity]
vco/signatures/meta/deps [moved from patchbins/firmprot/meta/deps with 100% similarity]
vco/signatures/meta/desc [moved from patchbins/signatures/meta/desc with 100% similarity]
vco/signatures/meta/name [moved from patchbins/signatures/meta/name with 100% similarity]
vco/signatures/meta/patch_version [moved from patchbins/firmprot/meta/patch_version with 100% similarity]
vco/signatures/meta/title [moved from patchbins/firmprot/meta/title with 100% similarity]
vco/signatures/meta/uuid [moved from patchbins/firmprot/meta/uuid with 100% similarity]
vco/signatures/src/exported.h [new symlink]
vco/signatures/src/headers.h [new symlink]
vco/signatures/src/link_table.s [new symlink]
vco/signatures/src/main.c [new file with mode: 0644]
vco/signatures/src/start.s [new symlink]
vco/signatures/tool [new symlink]
vco/template/Makefile [moved from patchbins/firmprot/Makefile with 97% similarity]
vco/template/linker.ld [moved from patchbins/firmprot/linker.ld with 100% similarity]
vco/template/meta/cfw_version [moved from patchbins/signatures/meta/cfw_version with 100% similarity]
vco/template/meta/deps [moved from patchbins/signatures/meta/deps with 100% similarity]
vco/template/meta/desc [moved from patchbins/firmprot/meta/desc with 100% similarity]
vco/template/meta/name [moved from patchbins/firmprot/meta/name with 100% similarity]
vco/template/meta/patch_version [moved from patchbins/signatures/meta/patch_version with 100% similarity]
vco/template/meta/title [moved from patchbins/signatures/meta/title with 100% similarity]
vco/template/meta/uuid [moved from patchbins/signatures/meta/uuid with 100% similarity]
vco/template/src/exported.h [moved from patchbins/signatures/src/exported.h with 74% similarity]
vco/template/src/headers.h [new symlink]
vco/template/src/link_table.s [new file with mode: 0644]
vco/template/src/main.c [moved from patchbins/template/src/main.c with 100% similarity]
vco/template/src/start.s [new file with mode: 0644]
vco/template/tool/compile_header.c [moved from patchbins/signatures/tool/compile_header.c with 95% similarity]

index 4b3c691070170ebeda3ecc4a7f6c30fdf7516f2c..5344ae6757d576932ffade7bd420025872927273 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -28,13 +28,18 @@ objects_cfw = $(patsubst $(dir_source)/%.s, $(dir_build)/%.o, \
                          $(call rwildcard, $(dir_source), *.s *.c)))
 
 .PHONY: all
-all: a9lh
+all: a9lh vco
+
+.PHONY: vco
+vco:
+       make -C vco
 
 .PHONY: a9lh
 a9lh: $(dir_out)/arm9loaderhax.bin
 
 .PHONY: clean
 clean:
+       make -C vco clean
        rm -rf $(dir_out) $(dir_build)
 
 .PHONY: $(dir_out)/arm9loaderhax.bin
index bcd09e11d76d8063c8fd1cc6d761c9460a338032..34503227a7ae8c9c96d0e67663c0b881a7a16e12 100644 (file)
@@ -1,6 +1,8 @@
 // This is svcBackdoor's code from earlier FIRMs
 .arm.little
 .create "backdoor.bin", 0
+       // Luckily, no ARM9/ARM11 specific instructions are used here.
+       // It can just be assembled via ARM9 gas.
        bic r1, sp, #0xff
        orr r1, r1, #0xf00
        add r1, r1, #0x28
diff --git a/copy.sh b/copy.sh
index 2ae94e88b3a0331a6d110a6b23753a782d760810..4cb3f7f71603b287ad4969faac26bd45479358be 100644 (file)
--- a/copy.sh
+++ b/copy.sh
@@ -1,4 +1,6 @@
 #!/bin/bash
-mount /dev/sdb1 /media/sd
-cp out/arm9loaderhax.bin /media/sd/anim/boot/a.bin
-umount /media/sd
+mount /dev/sdb1 /media/cd || exit 0
+cp out/arm9loaderhax.bin /media/cd/anim/boot/a.bin || exit 0
+cp -r out/corbenik /media/cd/ || exit 0
+umount /media/cd || exit 0
+eject /dev/sdb || exit 0
diff --git a/patchbins/README.txt b/patchbins/README.txt
deleted file mode 100644 (file)
index 21b6567..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-You're probably wondering what the heck corbenik does differently from cakes,
-considering it seems similar.
-
-Patches are actually code for whatever processor they're intended to run on.
-They're loaded to a static offset in memory, and executed.
-
-Patches should have a declaration of this sort somewhere in them:
-  { 0xc0, 0x9b, 0xe5, 0x1c }
-Followed by a table large enough to fill with all usable functions.
-
-See template/ for how this works.
-
-When the loader finds that magic value, it fills the table with
-the offsets of important variables and functions for use by the patcher, much
-like how an ELF loader sets up references. In other words; patches are binaries
-that are relocated relative to a 'standard library'.
-
-There's some key differences, obviously, from running just arm9loader code.
-Namely:
-  1) Patches must not clobber the previous state.
-  2) Patches must properly return.
-  3) Patches must have a symbol table with the appropriate magic.
-  4) Patches shouldn't do anything aside from change data.
-  5) _start must be at offset 0x24400000.
-
-Basically, don't get fancy in _start. Just do a bl main; bx lr. You can implement
-shit yourself, but it's an utter waste of memory. Try not to.
diff --git a/patchbins/firmprot/src/exported.h b/patchbins/firmprot/src/exported.h
deleted file mode 100644 (file)
index 9c102ae..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-#ifndef EXPORTED_H
-#define EXPORTED_H
-
-#define stdout (void*)0
-#define stderr (void*)1
-
-extern uint8_t* memory_offset;
-extern uint32_t* memory_len;
-
-extern int strlen(const char *string);
-extern int isprint(char c);
-extern void memcpy(void *dest, const void *src, size_t size);
-extern void memmove(void *dest, const void *src, size_t size);
-extern void memset(void *dest, const int filler, size_t size);
-extern int memcmp(const void *buf1, const void *buf2, const size_t size);
-extern void strncpy(void *dest, const void *src, const size_t size);
-extern int strncmp(const void *buf1, const void *buf2, const size_t size);
-extern int atoi(const char *str);
-extern uint8_t* memfind (uint8_t *string, uint32_t stringlen, uint8_t *pat, uint32_t patlen);
-
-extern void putc(void* buf, const int c);
-extern void puts(void* buf, const char *string);
-extern void fprintf(void* channel, const char* format, ...);
-
-#endif
diff --git a/patchbins/firmprot/src/link_table.s b/patchbins/firmprot/src/link_table.s
deleted file mode 100644 (file)
index 6774354..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-.section .text.table
-.align 4
-
-.macro stub name
-       .global \name
-       \name :
-               .byte 0
-               .byte 0
-               .byte 0
-               .byte 0
-.endm
-
-.global MAGIC_START
-MAGIC_START:
-       .byte 0xc0
-       .byte 0x9b
-       .byte 0xe5
-       .byte 0x1c
-
-// Memory to patch as specified by the header. (uint8_t*)
-stub memory_offset
-
-// Size of memory offset. (uint32_t*)
-stub memory_len
-
-// Exported functions.
-
-// memory.c
-stub strlen
-stub isprint
-stub memcpy
-stub memmove
-stub memset
-stub memcmp
-stub strncpy
-stub strncmp
-stub atoi
-stub memfind
-
-// draw.c
-stub putc
-stub puts
-stub fprintf
diff --git a/patchbins/firmprot/src/main.c b/patchbins/firmprot/src/main.c
deleted file mode 100644 (file)
index 93c2b77..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-#include <stdint.h>
-#include <stddef.h>
-#include "exported.h"
-
-int main() {
-    //Look for signature checks
-       uint8_t pat1[] = {0xC0, 0x1C, 0x76, 0xE7};
-       uint8_t pat2[] = {0xB5, 0x22, 0x4D, 0x0C};
-
-       uint8_t *firm_mem = (uint8_t*)memory_offset;
-       uint32_t size = *(uint32_t*)memory_len;
-
-    uint8_t *off  = memfind(firm_mem, size, pat1, 4);
-    uint8_t *off2 = memfind(firm_mem, size, pat2, 4) - 1;
-
-       if (off == NULL) {
-               fprintf(stderr, "Signature patch failed on P0.\n");
-               return 1; // Failed to find sigpatch. Ugh.
-       }
-
-       if (off2 == NULL) {
-               fprintf(stderr, "Signature patch failed on P1.\n");
-               return 2; // Failed to find sigpatch. Ugh.
-       }
-
-       fprintf(stderr, "Signatures[0]: 0x%x\n", (uint32_t)off);
-       fprintf(stderr, "Signatures[1]: 0x%x\n", (uint32_t)off2);
-
-       uint8_t sigpatch[] = {0x00, 0x20, 0x70, 0x47};
-
-       memcpy(off,  sigpatch, 2);
-       memcpy(off2, sigpatch, 4);
-       fprintf(stderr, "Signature patch succeded.\n");
-
-       return 0;
-}
diff --git a/patchbins/firmprot/src/patcher.c b/patchbins/firmprot/src/patcher.c
deleted file mode 100644 (file)
index e5cf3c7..0000000
+++ /dev/null
@@ -1,171 +0,0 @@
-#include <stdint.h>
-#include "std/unused.h"
-#include "std/memory.h"
-#include "firm/firm.h"
-#include "config.h"
-#include "common.h"
-
-uint32_t wait_key();
-
-// A portion of this file is inherited from Luma3DS.
-/*
-u16 *getFirmWrite(u8 *pos, u32 size) {
-    //Look for FIRM writing code
-    u8 *const off = memsearch(pos, "exe:", size, 4);
-    const u8 pattern[] = {0x00, 0x28, 0x01, 0xDA};
-
-    return (u16 *)memsearch(off - 0x100, pattern, 0x100, 4);
-}
-
-u16 *getFirmWriteSafe(u8 *pos, u32 size) {
-    //Look for FIRM writing code
-    const u8 pattern[] = {0x04, 0x1E, 0x1D, 0xDB};
-
-    return (u16 *)memsearch(pos, pattern, size, 4);
-}
-
-u32 getLoader(u8 *pos, u32 *loaderSize) {
-    u8 *off = pos;
-    u32 size;
-
-    while(1)
-    {
-        size = *(u32 *)(off + 0x104) * 0x200;
-        if(*(u32 *)(off + 0x200) == 0x64616F6C) break;
-        off += size;
-    }
-
-    *loaderSize = size;
-
-    return (u32)(off - pos);
-}
-
-
-// patch_location = (void *)((uintptr_t)firm + section->offset + (version->offset - section->address));
-
-u8 *getProcess9(u8 *pos, u32 size, u32 *process9Size, u32 *process9MemAddr)
-{
-    u8 *off = memsearch(pos, "ess9", size, 4);
-
-    *process9Size = *(u32 *)(off - 0x60) * 0x200;
-    *process9MemAddr = *(u32 *)(off + 0xC);
-
-    //Process9 code offset (start of NCCH + ExeFS offset + ExeFS header size)
-    return off - 0x204 + (*(u32 *)(off - 0x64) * 0x200) + 0x200;
-}
-*/
-
-int patch_signatures() {
-    //Look for signature checks
-
-       uint8_t pat1[] = {0xC0, 0x1C, 0x76, 0xE7};
-       uint8_t pat2[] = {0xB5, 0x22, 0x4D, 0x0C};
-
-       uint8_t *firm_mem = (uint8_t*)firm_p9_exefs + sizeof(exefs_h) + firm_p9_exefs->fileHeaders[0].offset;
-       uint32_t size = firm_p9_exefs->fileHeaders[0].size;
-
-    uint8_t *off  = memfind(firm_mem, size, pat1, 4);
-    uint8_t *off2 = memfind(firm_mem, size, pat2, 4) - 1;
-
-       if (off == NULL) {
-               fprintf(stderr, "Signature patch failed on P0.\n");
-               return 1; // Failed to find sigpatch. Ugh.
-       }
-
-       if (off2 == NULL) {
-               fprintf(stderr, "Signature patch failed on P1.\n");
-               return 2; // Failed to find sigpatch. Ugh.
-       }
-
-       fprintf(stderr, "Signatures[0]: 0x%x\n", (uint32_t)off);
-       fprintf(stderr, "Signatures[1]: 0x%x\n", (uint32_t)off2);
-
-       uint8_t sigpatch[] = {0x00, 0x20, 0x70, 0x47};
-
-       memcpy(off,  sigpatch, 2);
-       memcpy(off2, sigpatch, 4);
-       fprintf(stderr, "Signature patch succeded.\n");
-
-       return 0;
-}
-
-int patch_firmprot() {
-       uint8_t *firm_mem = (uint8_t*)firm_p9_exefs + sizeof(exefs_h) + firm_p9_exefs->fileHeaders[0].offset;
-       uint32_t size = firm_p9_exefs->fileHeaders[0].size;
-
-    //Look for FIRM writing code
-    uint8_t* off = memfind(firm_mem, size, (uint8_t*)"exe:", 4);
-
-       if(off == NULL) {
-               fprintf(stderr, "Couldn't find 'exe:' string.\n");
-               return 1;
-       }
-
-       fprintf(stderr, "Firmprot: 'exe:' string @ %x\n", (uint32_t)off);
-
-    uint8_t pattern[] = {0x00, 0x28, 0x01, 0xDA};
-
-    uint8_t* firmprot = memfind(off - 0x100, 0x100, pattern, 4);
-
-       if(firmprot == NULL) {
-               fprintf(stderr, "Couldn't find firmprot code.\n");
-               return 2;
-       }
-
-       fprintf(stderr, "Firmprot: %x\n", (uint32_t)firmprot);
-
-       uint8_t patch[] = {0x00, 0x20, 0xC0, 0x46};
-       memcpy(firmprot, patch, 4);
-
-       fprintf(stderr, "Applied firmprot patch.\n");
-
-       return 0;
-}
-
-void wait() {
-       if (config.options[OPTION_TRACE]) {
-               fprintf(stderr, "Pausing because trace is on.\n");
-               wait_key();
-       }
-}
-
-int patch_firm_all() {
-       // Use builtin signature patcher?
-
-       fprintf(stderr, "Sigpatch: %s\n", ((config.options[OPTION_SIGPATCH]) ? "yes" : "no" ));
-       fprintf(stderr, "Protect: %s\n", ((config.options[OPTION_FIRMPROT]) ? "yes" : "no" ));
-
-       wait();
-
-       if (config.options[OPTION_SIGPATCH]) {
-               if(patch_signatures()) {
-                       abort("Fatal. Sigpatch has failed.");
-               }
-       }
-
-       wait();
-
-       if (config.options[OPTION_FIRMPROT]) {
-               if(patch_firmprot()) {
-                       abort("Fatal. Firmprot has failed.");
-               }
-       }
-
-       wait();
-
-       // Replace loader?
-       if (config.options[OPTION_LOADER]) {
-               // Yes.
-
-               // This requires OPTION_SIGPATCH.
-       }
-
-       // Use ARM9 hook thread?
-       if (config.options[OPTION_ARM9THREAD]) {
-               // Yes.
-
-               // FIXME - NYI
-       }
-
-       return 0;
-}
diff --git a/patchbins/firmprot/src/start.s b/patchbins/firmprot/src/start.s
deleted file mode 100644 (file)
index 33e1695..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-.section .text.start
-.align 4
-.global _start
-_start:
-    bl main
-    bx lr @ return from patch.
diff --git a/patchbins/firmprot/tool/compile_header.c b/patchbins/firmprot/tool/compile_header.c
deleted file mode 100644 (file)
index bf8b2ad..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-#include <stdint.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "../../../source/patch_format.h"
-
-void read_file_u64(char* name, uint64_t* to) {
-       FILE* hdl = fopen(name, "rb");
-       fscanf(hdl, "%llu", to);
-       fclose(hdl);
-}
-
-
-void read_file_u32(char* name, uint32_t* to) {
-       FILE* hdl = fopen(name, "rb");
-       fscanf(hdl, "%u", to);
-       fclose(hdl);
-}
-
-void read_str(char* name, char* to, size_t len) {
-       FILE* hdl = fopen(name, "rb");
-       int r = fread(to, 1, len-1, hdl);
-       fclose(hdl);
-}
-
-uint32_t size = 0;
-
-uint8_t* read_file_mem(char* name) {
-       FILE* hdl = fopen(name, "rb");
-
-       fseek(hdl, 0, SEEK_END);
-       size = ftell(hdl);
-       rewind(hdl);
-
-       uint8_t* mem = malloc(size);
-       memset(mem, 0, size);
-
-       int r = fread(mem, 1, size, hdl);
-       fclose(hdl);
-
-       printf("%d\n", size);
-
-       return mem;
-}
-
-int main(int c, char** v) {
-       struct system_patch patch;
-       int at = 0;
-
-       memset(&patch, 0, sizeof(patch));
-
-       // Set magic.
-       patch.magic[0] = 'A';
-       patch.magic[1] = 'I';
-       patch.magic[2] = 'D';
-       patch.magic[3] = 'A';
-
-       read_file_u32("meta/patch_version", & patch.patch_ver);
-       read_file_u32("meta/cfw_version", & patch.load_ver);
-
-       read_file_u64("meta/uuid", & patch.patch_id);
-       read_file_u64("meta/title", & patch.tid);
-
-       read_str("meta/name", patch.name, sizeof(patch.name));
-       read_str("meta/desc", patch.desc, sizeof(patch.desc));
-
-       uint8_t* code = read_file_mem("out/patch.bin");
-
-       patch.patch_size = size;
-
-       FILE* out = fopen("out/patch.vco", "wb");
-       fwrite(&patch, 1, sizeof(patch),    out);
-       fwrite(code,   1, patch.patch_size, out);
-       fclose(out);
-
-       free(code);
-
-       printf("Ver:  %u\n"
-                       "CFW:  %u\n"
-                       "UUID: %llu\n"
-                       "TID:  %llu\n"
-                       "Name: %s\n"
-                       "Desc: %s\n"
-                       "Size: %u\n",
-                       patch.patch_ver, patch.load_ver, patch.patch_id,
-                       patch.tid, patch.name, patch.desc, patch.patch_size);
-
-       return 0;
-}
diff --git a/patchbins/signatures/Makefile b/patchbins/signatures/Makefile
deleted file mode 100644 (file)
index 7205e8a..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-rwildcard = $(foreach d, $(wildcard $1*), $(filter $(subst *, %, $2), $d) $(call rwildcard, $d/, $2))
-
-PATH := $(PATH):$(DEVKITARM)/bin
-
-HOST_CC := gcc
-
-CC := arm-none-eabi-gcc
-AS := arm-none-eabi-as
-LD := arm-none-eabi-ld
-OC := arm-none-eabi-objcopy
-
-dir_source := src
-dir_build  := build
-dir_out    := out
-
-ASFLAGS := -mlittle-endian -mcpu=arm946e-s -march=armv5te
-CFLAGS  := -MMD -MP -Wall -Wextra -Werror -Os $(ASFLAGS) -fno-builtin -std=c11 -DVERSION=\"$(REVISION)\"
-FLAGS   := dir_out=$(abspath $(dir_out)) --no-print-directory
-LDFLAGS := -nostdlib -Wl,-z,defs -lgcc
-
-objects_cfw = $(patsubst $(dir_source)/%.s, $(dir_build)/%.o, \
-                         $(patsubst $(dir_source)/%.c, $(dir_build)/%.o, \
-                         $(call rwildcard, $(dir_source), *.s *.c)))
-
-.PHONY: all
-all: patchbin
-
-.PHONY: patchbin
-patchbin: tool $(dir_out)/patch.bin
-       ./compile_header
-
-.PHONY: tool
-tool:
-       $(HOST_CC) -o compile_header tool/compile_header.c
-
-
-.PHONY: clean
-clean:
-       rm -rf $(dir_out) $(dir_build) compile_header
-
-.PHONY: $(dir_out)/patch.bin
-$(dir_out)/patch.bin: $(dir_build)/main.bin
-       @mkdir -p "$(dir_out)"
-       @cp -av $< $@
-
-$(dir_build)/main.bin: $(dir_build)/main.elf
-       $(OC) -S -O binary $< $@
-
-$(dir_build)/main.elf: $(objects_cfw)
-       $(CC) -T linker.ld $(OUTPUT_OPTION) $^ $(LDFLAGS)
-
-$(dir_build)/%.o: $(dir_source)/%.c
-       @mkdir -p "$(@D)"
-       $(COMPILE.c) $(OUTPUT_OPTION) $<
-
-$(dir_build)/%.o: $(dir_source)/%.s
-       @mkdir -p "$(@D)"
-       $(COMPILE.s) $(OUTPUT_OPTION) $<
-
-include $(call rwildcard, $(dir_build), *.d)
diff --git a/patchbins/signatures/linker.ld b/patchbins/signatures/linker.ld
deleted file mode 100644 (file)
index 7d6129b..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/* This memory map is mainly to assist in doing stuff in code.
-MEMORY
-{
-    INSTRUCTION_TCM  (rw)   : ORIGIN = 0x00000000, LENGTH = 0x08000000
-    ARM_INTERNAL     (rw)  : ORIGIN = 0x08000000, LENGTH = 0x00100000
-    NEW_INTERNAL     (rw)  : ORIGIN = 0x08100000, LENGTH = 0x00080000
-    IO_MEMORY        (rw)  : ORIGIN = 0x10000000, LENGTH = 0x08000000
-    VRAM             (rw)  : ORIGIN = 0x18000000, LENGTH = 0x00600000
-    DSP_MEMORY       (rw)  : ORIGIN = 0x1FF00000, LENGTH = 0x00080000
-    AXI_WRAM         (rw)  : ORIGIN = 0x1FF80000, LENGTH = 0x00080000
-    FCRAM            (rwx) : ORIGIN = 0x20000000, LENGTH = 0x08000000
-    NEW_FCRAM        (rwx) : ORIGIN = 0x28000000, LENGTH = 0x08000000
-    DATA_TCM         (rw)  : ORIGIN = 0xFFF00000, LENGTH = 0x00004000
-    BOOTROM          (rw)   : ORIGIN = 0xFFFF0000, LENGTH = 0x00010000
-} */
-
-ENTRY(_start)
-SECTIONS
-{
-    . = 0x24400000;
-
-    START_SECTION = .;
-      .text.start : {
-          *(.text.start)
-      }
-    START_SECTION_END = .;
-
-    TABLE_SECTION = .;
-      .text.table : {
-          *(.text.table)
-      }
-    TABLE_SECTION_END = .;
-
-    TEXT_SECTION = .;
-      .text : {
-          *(.text)
-      }
-    TEXT_SECTION_END = .;
-
-    DATA_SECTION = .;
-      .data : {
-          *(.data)
-      }
-    DATA_SECTION_END = .;
-
-    BSS_SECTION = .;
-      .bss : {
-          *(.bss COMMON)
-      }
-    BSS_SECTION_END = .;
-
-    RODATA_SECTION = .;
-      .rodata : {
-          *(.rodata)
-      }
-    RODATA_SECTION_END = .;
-
-    . = ALIGN(4);
-}
diff --git a/patchbins/signatures/src/link_table.s b/patchbins/signatures/src/link_table.s
deleted file mode 100644 (file)
index 6774354..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-.section .text.table
-.align 4
-
-.macro stub name
-       .global \name
-       \name :
-               .byte 0
-               .byte 0
-               .byte 0
-               .byte 0
-.endm
-
-.global MAGIC_START
-MAGIC_START:
-       .byte 0xc0
-       .byte 0x9b
-       .byte 0xe5
-       .byte 0x1c
-
-// Memory to patch as specified by the header. (uint8_t*)
-stub memory_offset
-
-// Size of memory offset. (uint32_t*)
-stub memory_len
-
-// Exported functions.
-
-// memory.c
-stub strlen
-stub isprint
-stub memcpy
-stub memmove
-stub memset
-stub memcmp
-stub strncpy
-stub strncmp
-stub atoi
-stub memfind
-
-// draw.c
-stub putc
-stub puts
-stub fprintf
diff --git a/patchbins/signatures/src/main.c b/patchbins/signatures/src/main.c
deleted file mode 100644 (file)
index 93c2b77..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-#include <stdint.h>
-#include <stddef.h>
-#include "exported.h"
-
-int main() {
-    //Look for signature checks
-       uint8_t pat1[] = {0xC0, 0x1C, 0x76, 0xE7};
-       uint8_t pat2[] = {0xB5, 0x22, 0x4D, 0x0C};
-
-       uint8_t *firm_mem = (uint8_t*)memory_offset;
-       uint32_t size = *(uint32_t*)memory_len;
-
-    uint8_t *off  = memfind(firm_mem, size, pat1, 4);
-    uint8_t *off2 = memfind(firm_mem, size, pat2, 4) - 1;
-
-       if (off == NULL) {
-               fprintf(stderr, "Signature patch failed on P0.\n");
-               return 1; // Failed to find sigpatch. Ugh.
-       }
-
-       if (off2 == NULL) {
-               fprintf(stderr, "Signature patch failed on P1.\n");
-               return 2; // Failed to find sigpatch. Ugh.
-       }
-
-       fprintf(stderr, "Signatures[0]: 0x%x\n", (uint32_t)off);
-       fprintf(stderr, "Signatures[1]: 0x%x\n", (uint32_t)off2);
-
-       uint8_t sigpatch[] = {0x00, 0x20, 0x70, 0x47};
-
-       memcpy(off,  sigpatch, 2);
-       memcpy(off2, sigpatch, 4);
-       fprintf(stderr, "Signature patch succeded.\n");
-
-       return 0;
-}
diff --git a/patchbins/signatures/src/start.s b/patchbins/signatures/src/start.s
deleted file mode 100644 (file)
index 33e1695..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-.section .text.start
-.align 4
-.global _start
-_start:
-    bl main
-    bx lr @ return from patch.
diff --git a/patchbins/template/Makefile b/patchbins/template/Makefile
deleted file mode 100644 (file)
index 758faed..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-rwildcard = $(foreach d, $(wildcard $1*), $(filter $(subst *, %, $2), $d) $(call rwildcard, $d/, $2))
-
-PATH := $(PATH):$(DEVKITARM)/bin
-
-HOST_CC := gcc
-
-CC := arm-none-eabi-gcc
-AS := arm-none-eabi-as
-LD := arm-none-eabi-ld
-OC := arm-none-eabi-objcopy
-
-dir_source := src
-dir_build  := build
-dir_out    := out
-
-ASFLAGS := -mlittle-endian -mcpu=arm946e-s -march=armv5te
-CFLAGS  := -MMD -MP -Wall -Wextra -Werror -Os $(ASFLAGS) -fno-builtin -std=c11 -DVERSION=\"$(REVISION)\"
-FLAGS   := dir_out=$(abspath $(dir_out)) --no-print-directory
-LDFLAGS := -nostdlib -Wl,-z,defs
-
-objects_cfw = $(patsubst $(dir_source)/%.s, $(dir_build)/%.o, \
-                         $(patsubst $(dir_source)/%.c, $(dir_build)/%.o, \
-                         $(call rwildcard, $(dir_source), *.s *.c)))
-
-.PHONY: all
-all: patchbin
-
-.PHONY: patchbin
-patchbin: tool $(dir_out)/patch.bin
-       ./compile_header
-
-.PHONY: tool
-tool:
-       $(HOST_CC) -o compile_header tool/compile_header.c
-
-
-.PHONY: clean
-clean:
-       rm -rf $(dir_out) $(dir_build) compile_header
-
-.PHONY: $(dir_out)/patch.bin
-$(dir_out)/patch.bin: $(dir_build)/main.bin
-       @mkdir -p "$(dir_out)"
-       @cp -av $< $@
-
-$(dir_build)/main.bin: $(dir_build)/main.elf
-       $(OC) -S -O binary $< $@
-
-$(dir_build)/main.elf: $(objects_cfw)
-       $(CC) -T linker.ld $(OUTPUT_OPTION) $^ $(LDFLAGS)
-
-$(dir_build)/%.o: $(dir_source)/%.c
-       @mkdir -p "$(@D)"
-       $(COMPILE.c) $(OUTPUT_OPTION) $<
-
-$(dir_build)/%.o: $(dir_source)/%.s
-       @mkdir -p "$(@D)"
-       $(COMPILE.s) $(OUTPUT_OPTION) $<
-
-include $(call rwildcard, $(dir_build), *.d)
diff --git a/patchbins/template/linker.ld b/patchbins/template/linker.ld
deleted file mode 100644 (file)
index 7d6129b..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/* This memory map is mainly to assist in doing stuff in code.
-MEMORY
-{
-    INSTRUCTION_TCM  (rw)   : ORIGIN = 0x00000000, LENGTH = 0x08000000
-    ARM_INTERNAL     (rw)  : ORIGIN = 0x08000000, LENGTH = 0x00100000
-    NEW_INTERNAL     (rw)  : ORIGIN = 0x08100000, LENGTH = 0x00080000
-    IO_MEMORY        (rw)  : ORIGIN = 0x10000000, LENGTH = 0x08000000
-    VRAM             (rw)  : ORIGIN = 0x18000000, LENGTH = 0x00600000
-    DSP_MEMORY       (rw)  : ORIGIN = 0x1FF00000, LENGTH = 0x00080000
-    AXI_WRAM         (rw)  : ORIGIN = 0x1FF80000, LENGTH = 0x00080000
-    FCRAM            (rwx) : ORIGIN = 0x20000000, LENGTH = 0x08000000
-    NEW_FCRAM        (rwx) : ORIGIN = 0x28000000, LENGTH = 0x08000000
-    DATA_TCM         (rw)  : ORIGIN = 0xFFF00000, LENGTH = 0x00004000
-    BOOTROM          (rw)   : ORIGIN = 0xFFFF0000, LENGTH = 0x00010000
-} */
-
-ENTRY(_start)
-SECTIONS
-{
-    . = 0x24400000;
-
-    START_SECTION = .;
-      .text.start : {
-          *(.text.start)
-      }
-    START_SECTION_END = .;
-
-    TABLE_SECTION = .;
-      .text.table : {
-          *(.text.table)
-      }
-    TABLE_SECTION_END = .;
-
-    TEXT_SECTION = .;
-      .text : {
-          *(.text)
-      }
-    TEXT_SECTION_END = .;
-
-    DATA_SECTION = .;
-      .data : {
-          *(.data)
-      }
-    DATA_SECTION_END = .;
-
-    BSS_SECTION = .;
-      .bss : {
-          *(.bss COMMON)
-      }
-    BSS_SECTION_END = .;
-
-    RODATA_SECTION = .;
-      .rodata : {
-          *(.rodata)
-      }
-    RODATA_SECTION_END = .;
-
-    . = ALIGN(4);
-}
diff --git a/patchbins/template/meta/cfw_version b/patchbins/template/meta/cfw_version
deleted file mode 100644 (file)
index 573541a..0000000
+++ /dev/null
@@ -1 +0,0 @@
-0
diff --git a/patchbins/template/meta/deps b/patchbins/template/meta/deps
deleted file mode 100644 (file)
index b0047fa..0000000
+++ /dev/null
@@ -1 +0,0 @@
-None
diff --git a/patchbins/template/meta/desc b/patchbins/template/meta/desc
deleted file mode 100644 (file)
index adf29f1..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Prints "Hello World!"
diff --git a/patchbins/template/meta/name b/patchbins/template/meta/name
deleted file mode 100644 (file)
index e3dac2c..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Example Patch
diff --git a/patchbins/template/meta/patch_version b/patchbins/template/meta/patch_version
deleted file mode 100644 (file)
index d00491f..0000000
+++ /dev/null
@@ -1 +0,0 @@
-1
diff --git a/patchbins/template/meta/title b/patchbins/template/meta/title
deleted file mode 100644 (file)
index 8380236..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Native
diff --git a/patchbins/template/meta/uuid b/patchbins/template/meta/uuid
deleted file mode 100644 (file)
index d00491f..0000000
+++ /dev/null
@@ -1 +0,0 @@
-1
diff --git a/patchbins/template/src/exported.h b/patchbins/template/src/exported.h
deleted file mode 100644 (file)
index 9c102ae..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-#ifndef EXPORTED_H
-#define EXPORTED_H
-
-#define stdout (void*)0
-#define stderr (void*)1
-
-extern uint8_t* memory_offset;
-extern uint32_t* memory_len;
-
-extern int strlen(const char *string);
-extern int isprint(char c);
-extern void memcpy(void *dest, const void *src, size_t size);
-extern void memmove(void *dest, const void *src, size_t size);
-extern void memset(void *dest, const int filler, size_t size);
-extern int memcmp(const void *buf1, const void *buf2, const size_t size);
-extern void strncpy(void *dest, const void *src, const size_t size);
-extern int strncmp(const void *buf1, const void *buf2, const size_t size);
-extern int atoi(const char *str);
-extern uint8_t* memfind (uint8_t *string, uint32_t stringlen, uint8_t *pat, uint32_t patlen);
-
-extern void putc(void* buf, const int c);
-extern void puts(void* buf, const char *string);
-extern void fprintf(void* channel, const char* format, ...);
-
-#endif
diff --git a/patchbins/template/src/link_table.s b/patchbins/template/src/link_table.s
deleted file mode 100644 (file)
index 9bdd5be..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-.section .text.table
-.align 4
-
-.macro stub name
-       .global \name
-       \name :
-               ldr pc, [pc, #-4] // Load the data after this to the PC. return will be before this call.
-               .byte 0 // Read; pc relative in arm mode is pc+8, so pc-4 is the correct offset
-               .byte 0
-               .byte 0
-               .byte 0
-.endm
-
-.macro ref name
-       .global \name
-       \name :
-               .byte 0
-               .byte 0
-               .byte 0
-               .byte 0
-.endm
-
-.global MAGIC_START
-MAGIC_START:
-       .byte 0xc0
-       .byte 0x9b
-       .byte 0xe5
-       .byte 0x1c
-
-// Memory to patch as specified by the header. (uint8_t*)
-ref memory_offset
-
-// Size of memory offset. (uint32_t*)
-ref memory_len
-
-// Exported functions.
-
-// memory.c
-stub strlen
-stub isprint
-stub memcpy
-stub memmove
-stub memset
-stub memcmp
-stub strncpy
-stub strncmp
-stub atoi
-stub memfind
-
-// draw.c
-stub putc
-stub puts
-stub fprintf
diff --git a/patchbins/template/src/start.s b/patchbins/template/src/start.s
deleted file mode 100644 (file)
index 713b650..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-.section .text.start
-.align 4
-.global _start
-_start:
-       stmdb sp!, {lr}
-       bl main
-       ldmia sp!, {lr}
-    bx lr // return from patch.
diff --git a/patchbins/template/tool/compile_header.c b/patchbins/template/tool/compile_header.c
deleted file mode 100644 (file)
index bf8b2ad..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-#include <stdint.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "../../../source/patch_format.h"
-
-void read_file_u64(char* name, uint64_t* to) {
-       FILE* hdl = fopen(name, "rb");
-       fscanf(hdl, "%llu", to);
-       fclose(hdl);
-}
-
-
-void read_file_u32(char* name, uint32_t* to) {
-       FILE* hdl = fopen(name, "rb");
-       fscanf(hdl, "%u", to);
-       fclose(hdl);
-}
-
-void read_str(char* name, char* to, size_t len) {
-       FILE* hdl = fopen(name, "rb");
-       int r = fread(to, 1, len-1, hdl);
-       fclose(hdl);
-}
-
-uint32_t size = 0;
-
-uint8_t* read_file_mem(char* name) {
-       FILE* hdl = fopen(name, "rb");
-
-       fseek(hdl, 0, SEEK_END);
-       size = ftell(hdl);
-       rewind(hdl);
-
-       uint8_t* mem = malloc(size);
-       memset(mem, 0, size);
-
-       int r = fread(mem, 1, size, hdl);
-       fclose(hdl);
-
-       printf("%d\n", size);
-
-       return mem;
-}
-
-int main(int c, char** v) {
-       struct system_patch patch;
-       int at = 0;
-
-       memset(&patch, 0, sizeof(patch));
-
-       // Set magic.
-       patch.magic[0] = 'A';
-       patch.magic[1] = 'I';
-       patch.magic[2] = 'D';
-       patch.magic[3] = 'A';
-
-       read_file_u32("meta/patch_version", & patch.patch_ver);
-       read_file_u32("meta/cfw_version", & patch.load_ver);
-
-       read_file_u64("meta/uuid", & patch.patch_id);
-       read_file_u64("meta/title", & patch.tid);
-
-       read_str("meta/name", patch.name, sizeof(patch.name));
-       read_str("meta/desc", patch.desc, sizeof(patch.desc));
-
-       uint8_t* code = read_file_mem("out/patch.bin");
-
-       patch.patch_size = size;
-
-       FILE* out = fopen("out/patch.vco", "wb");
-       fwrite(&patch, 1, sizeof(patch),    out);
-       fwrite(code,   1, patch.patch_size, out);
-       fclose(out);
-
-       free(code);
-
-       printf("Ver:  %u\n"
-                       "CFW:  %u\n"
-                       "UUID: %llu\n"
-                       "TID:  %llu\n"
-                       "Name: %s\n"
-                       "Desc: %s\n"
-                       "Size: %u\n",
-                       patch.patch_ver, patch.load_ver, patch.patch_id,
-                       patch.tid, patch.name, patch.desc, patch.patch_size);
-
-       return 0;
-}
index 29187ec3366c2b1a10914f55c0107e2c0743f56f..1e66922f25331fe8167a79b35ee25efccb0554db 100644 (file)
@@ -135,7 +135,7 @@ int load_firm(firm_h *dest, char *path, char *path_firmkey, uint32_t *size, uint
     int firmware_changed = 0;
 
     if (read_file(dest, path, *size)) {
-        fprintf(BOTTOM_SCREEN, "Failed to read FIRM from SD\n");
+        fprintf(BOTTOM_SCREEN, "  Failed to read FIRM.\n");
 
         // Only whine about this if it's NATIVE_FIRM, which is important.
         if (firm_title == NATIVE_FIRM_TITLEID) {
@@ -155,17 +155,18 @@ int load_firm(firm_h *dest, char *path, char *path_firmkey, uint32_t *size, uint
             if (firm_title == NATIVE_FIRM_TITLEID) {
                 fprintf(BOTTOM_SCREEN, "Failed to decrypt firmware.\n"
                                        "This is fatal. Aborting.\n");
+                       status = 1;
+                       goto exit_error;
             }
-            goto exit_error;
         }
         firmware_changed = 1; // Decryption performed.
     } else {
-        fprintf(BOTTOM_SCREEN, "FIRM not encrypted\n");
+        fprintf(BOTTOM_SCREEN, "  FIRM not encrypted\n");
     }
 
        struct firm_signature* fsig = get_firm_info(dest);
 
-       fprintf(BOTTOM_SCREEN, "FIRM version: %s\n", fsig->version_string);
+       fprintf(BOTTOM_SCREEN, "  FIRM version: %s\n", fsig->version_string);
 
     // The N3DS firm has an additional encryption layer for ARM9
        if (fsig->console == console_n3ds) {
@@ -192,7 +193,7 @@ int load_firm(firm_h *dest, char *path, char *path_firmkey, uint32_t *size, uint
                     }
                     firmware_changed = 1; // Decryption of arm9bin performed.
                 } else {
-                    fprintf(BOTTOM_SCREEN, "ARM9 FIRM binary not encrypted\n");
+                    fprintf(BOTTOM_SCREEN, "  ARM9 FIRM binary not encrypted\n");
                     if (firm_title == NATIVE_FIRM_TITLEID && fsig->version > 0x0F) {
                         slot0x11key96_init(); // This has to be loaded regardless, otherwise boot will fail.
                     }
@@ -206,13 +207,12 @@ int load_firm(firm_h *dest, char *path, char *path_firmkey, uint32_t *size, uint
 
     // Save firmware.bin if decryption was done.
     if (firmware_changed) {
-        fprintf(BOTTOM_SCREEN, "Saving decrypted FIRM\n");
+        fprintf(BOTTOM_SCREEN, "  Saving decrypted FIRM\n");
         write_file(dest, path, *size);
     }
 
-    if (fsig->console == console_n3ds)
-    {
-        fprintf(BOTTOM_SCREEN, "Fixing arm9 entrypoint\n");
+    if (fsig->console == console_n3ds) {
+        fprintf(BOTTOM_SCREEN, "  Fixing arm9 entrypoint\n");
 
         // Patch the entrypoint to skip arm9loader
         if (firm_title == NATIVE_FIRM_TITLEID) {
@@ -261,6 +261,9 @@ void boot_firm() {
         fprintf(BOTTOM_SCREEN, "Updated keyX keyslots\n");
     }
 
+       fumount(); // Unmount SD. No longer needed.
+       fprintf(BOTTOM_SCREEN, "SD Unmounted.\n");
+
     for (firm_section_h *section = firm_loc->section;
             section < firm_loc->section + 4 && section->address != 0; section++) {
         memcpy((void *)section->address, (void *)firm_loc + section->offset, section->size);
@@ -293,7 +296,7 @@ int find_proc9(firm_h* firm, firm_section_h* process9, exefs_h** p9exefs) {
                                                process9->address = p9exheader->sci.textCodeSet.address;
                                                process9->size = (*p9exefs)->fileHeaders[0].size;
                                                process9->offset = (void*)((*p9exefs) + 1) - (void*)firm;
-                                               fprintf(BOTTOM_SCREEN, "Found Process9 for FIRM.\n");
+                                               fprintf(BOTTOM_SCREEN, "  Found Process9 for FIRM.\n");
                                                return 0;
                                        }
                                }
@@ -301,12 +304,12 @@ int find_proc9(firm_h* firm, firm_section_h* process9, exefs_h** p9exefs) {
                        }
                }
        }
-       fprintf(BOTTOM_SCREEN, "Couldn't find Process9 for FIRM?\n");
+       fprintf(BOTTOM_SCREEN, "  Couldn't find Process9?\n");
        return 1;
 }
 
 int load_firms() {
-    fprintf(TOP_SCREEN, "[Loading FIRM]");
+    fprintf(TOP_SCREEN, "[Loading FIRM]\n");
 
     fprintf(BOTTOM_SCREEN, "Loading NATIVE_FIRM\n");
     if (load_firm(firm_loc, PATH_NATIVE_F, PATH_NATIVE_FIRMKEY, &firm_size, NATIVE_FIRM_TITLEID) != 0)
@@ -315,13 +318,13 @@ int load_firms() {
 
     fprintf(BOTTOM_SCREEN, "Loading TWL_FIRM\n");
     if(load_firm(twl_firm_loc, PATH_TWL_F, PATH_TWL_FIRMKEY, &twl_firm_size, TWL_FIRM_TITLEID))
-        fprintf(BOTTOM_SCREEN, "TWL_FIRM failed to load.\n");
+        fprintf(BOTTOM_SCREEN, "  TWL_FIRM failed to load.\n");
        else
        find_proc9(twl_firm_loc, &twl_firm_proc9, &twl_firm_p9_exefs);
 
     fprintf(BOTTOM_SCREEN, "Loading AGB_FIRM\n");
     if(load_firm(agb_firm_loc, PATH_AGB_F, PATH_AGB_FIRMKEY, &agb_firm_size, AGB_FIRM_TITLEID))
-        fprintf(BOTTOM_SCREEN, "AGB_FIRM failed to load.\n");
+        fprintf(BOTTOM_SCREEN, "  AGB_FIRM failed to load.\n");
        else
        find_proc9(agb_firm_loc, &agb_firm_proc9, &agb_firm_p9_exefs);
 
@@ -329,7 +332,7 @@ int load_firms() {
 }
 
 void boot_cfw() {
-    fprintf(TOP_SCREEN, "[Patching]");
+    fprintf(TOP_SCREEN, "Applying patches...\n");
     if (patch_firm_all() != 0)
         return;
 
index b727142df47ec0c78522f3ee6640d7704af9780f..4ec769e5d43b9f80ac617df8028a912e57e38e5d 100644 (file)
 #include "common.h"
 #include "firm/fcram.h"
+#include "firm/firm.h"
 
-int link_and_load_patchbin(char* path) {
-       fprintf(stderr, "Prep to relocate and execute patch.\n");
+extern void flush_cache();
 
-       struct system_patch patch;
+extern firm_h *firm_loc;
+extern exefs_h *firm_p9_exefs;
+
+extern firm_h *twl_firm_loc;
+extern exefs_h *twl_firm_p9_exefs;
+
+extern firm_h *agb_firm_loc;
+extern exefs_h *agb_firm_p9_exefs;
+
+firm_h* __attribute__((optimize("O0"))) get_firm() {
+       return firm_loc;
+}
+
+exefs_h* __attribute__((optimize("O0"))) get_firm_proc9_exefs() {
+       return firm_p9_exefs;
+}
 
-       fprintf(stderr, "Loading patch vco.\n");
+firm_h* __attribute__((optimize("O0"))) get_agb() {
+       return agb_firm_loc;
+}
+
+exefs_h* __attribute__((optimize("O0"))) get_agb_proc9_exefs() {
+       return agb_firm_p9_exefs;
+}
+
+firm_h* __attribute__((optimize("O0"))) get_twl() {
+       return twl_firm_loc;
+}
+
+exefs_h* __attribute__((optimize("O0"))) get_twl_proc9_exefs() {
+       return twl_firm_p9_exefs;
+}
+
+// Yes, this is EXACTLY what it looks like. We dynamically link and
+// load patches as binaries; they use functions from corbenik to do
+// the work, and therefore must have a function table in them.
+
+// See vco/template for how this magic works.
+
+// This ensures relatively small patches while also having incredible
+// flexibility unlike a 'patch format'.
+
+int execp(char* path) {
+       int basename = 0;
+       for(basename=strlen(path); basename > 0; basename--)
+               if (path[basename] == '/')
+                       break;
+       basename++;
+
+       fprintf(stderr, "Executing patchbin: %s\n", &path[basename]);
+
+       struct system_patch patch;
 
        // Load patch from path.
        FILE* f = fopen(path, "r");
        fread(&patch, 1, sizeof(patch), f);
 
-       fprintf(stderr, "Patch payload is %d bytes.\n", patch.patch_size);
+       fprintf(stderr, "  [h]");
 
        fread((uint8_t*)FCRAM_PATCHBIN_EXEC_LOC, 1, patch.patch_size, f);
 
+       fprintf(stderr, "[x]");
+
        fclose(f);
 
-       fprintf(stderr, "Finding relocation table.\n");
+       fprintf(stderr, "[s]");
        // Now then...find the magical number.
        uint8_t magic[] = { 0xc0, 0x9b, 0xe5, 0x1c };
-       uint8_t* off = memfind((uint8_t*)FCRAM_PATCHBIN_EXEC_LOC, patch.patch_size, magic, 4);
+       uint32_t* link_table = (uint32_t*)memfind((uint8_t*)FCRAM_PATCHBIN_EXEC_LOC, patch.patch_size, magic, 4);
 
-       if (off == NULL) {
-               fprintf(stderr, "Relocation table missing. Abort.\n");
+       if (link_table == NULL) {
+               fprintf(stderr, "\n Table missing. Abort.\n");
                return 1;
        }
 
-       fprintf(stderr, "Relocation table is at %x\n", (uint32_t)off);
+       fprintf(stderr, "[r]");
 
-       uint32_t* link_table = (uint32_t*)(off + 4);
+       // 0 - magic
 
        // memory.c
-       link_table[3] = (uint32_t)strlen;
-       link_table[5] = (uint32_t)isprint;
-       link_table[7] = (uint32_t)memcpy;
-       link_table[9] = (uint32_t)memmove;
-       link_table[11] = (uint32_t)memset;
-       link_table[13] = (uint32_t)memcmp;
-       link_table[15] = (uint32_t)strncpy;
-       link_table[17] = (uint32_t)strncmp;
-       link_table[19] = (uint32_t)atoi;
-       link_table[21] = (uint32_t)memfind;
+       link_table[2] = (uint32_t)strlen;
+       link_table[4] = (uint32_t)isprint;
+       link_table[6] = (uint32_t)memcpy;
+       link_table[8] = (uint32_t)memmove;
+       link_table[10] = (uint32_t)memset;
+       link_table[12] = (uint32_t)memcmp;
+       link_table[14] = (uint32_t)strncpy;
+       link_table[16] = (uint32_t)strncmp;
+       link_table[18] = (uint32_t)atoi;
+       link_table[20] = (uint32_t)memfind;
 
        // draw.c
-       link_table[23] = (uint32_t)putc;
-       link_table[25] = (uint32_t)puts;
-       link_table[27] = (uint32_t)fprintf;
+       link_table[22] = (uint32_t)putc;
+       link_table[24] = (uint32_t)puts;
+       link_table[26] = (uint32_t)fprintf;
+
+       // Get functions
+       link_table[28] = (uint32_t)get_firm;
+       link_table[30] = (uint32_t)get_firm_proc9_exefs;
+
+       link_table[32] = (uint32_t)get_agb;
+       link_table[34] = (uint32_t)get_agb_proc9_exefs;
+
+       link_table[36] = (uint32_t)get_twl;
+       link_table[38] = (uint32_t)get_twl_proc9_exefs;
+
+       fprintf(stderr, "[b]\n");
+
+       int (*patch_loc)() = (void*)FCRAM_PATCHBIN_EXEC_LOC ;
 
-       fprintf(stderr, "Copied relocations. Running binary.\n");
+       int ret = (*patch_loc)();
 
-       int (*exec)() = (void*)FCRAM_PATCHBIN_EXEC_LOC ;
+       fprintf(stderr, "  Exit: %d\n", ret);
 
-       return (*exec)();
+       return ret;
 }
index 64f3a2aaeae3c0298ed266ac7dc2fdd815f489ed..301f4e890462a37bd3c73774b286d516a2412da8 100644 (file)
@@ -22,8 +22,8 @@
 #define PATH_LOCEMU     PATH_CFW "/locale.conf"    // Locale emulation config
 #define PATH_CPU_CFG    PATH_CFW "/cpu.conf"       // CPU settings config
 
-#define PATH_FIRMWARES  PATH_CFW "/firmware"       // Firmware folder.
-#define PATH_PATCHES    PATH_CFW "/patches"        // Patches folder.
+#define PATH_FIRMWARES  PATH_CFW "/firm"       // Firmware folder.
+#define PATH_PATCHES    PATH_CFW "/bin"            // Patch binary folder.
 #define PATH_TEMP       PATH_CFW "/temp"           // Files that are transient (user can delete them and they will be regenerated)
 #define PATH_KEYS       PATH_CFW "/keys"           // Keyfiles will be loaded from this dir, and additionally the root if not found.
 #define PATH_EXEFS      PATH_CFW "/exefs"          // ExeFS overrides, named like '<titleid>.exefs'
@@ -41,7 +41,7 @@
 #define PATH_AGB_CETK       PATH_KEYS "/agb.cetk"
 #define PATH_AGB_FIRMKEY    PATH_KEYS "/agb.key"
 
-#define PATH_SLOT0X11KEY96  PATH_KEYS "/0x11.key"
+#define PATH_SLOT0X11KEY96  PATH_KEYS "/11.key"
 
 #define PATH_ALT_SLOT0X11KEY96 "/slot0x11key96.bin" // Hey, your perrogative, buddy. I like cleaned up paths.
 
index 6bd196d8dfa56c477aa567c3ae2cb7b194fbbdd1..7e383944259d40b3bbd50a17b136876d291eaba0 100644 (file)
@@ -5,27 +5,13 @@
 #include "config.h"
 #include "common.h"
 
+// TODO - Basically all this needs to move to patcher programs.
+
 uint32_t wait_key();
-int link_and_load_patchbin(char* path);
+int execp(char* path);
 
 // A portion of this file is inherited from Luma3DS.
-/*
-u16 *getFirmWrite(u8 *pos, u32 size) {
-    //Look for FIRM writing code
-    u8 *const off = memsearch(pos, "exe:", size, 4);
-    const u8 pattern[] = {0x00, 0x28, 0x01, 0xDA};
-
-    return (u16 *)memsearch(off - 0x100, pattern, 0x100, 4);
-}
-
-u16 *getFirmWriteSafe(u8 *pos, u32 size) {
-    //Look for FIRM writing code
-    const u8 pattern[] = {0x04, 0x1E, 0x1D, 0xDB};
-
-    return (u16 *)memsearch(pos, pattern, size, 4);
-}
-
-u32 getLoader(u8 *pos, u32 *loaderSize) {
+/*u32 getLoader(u8 *pos, u32 *loaderSize) {
     u8 *off = pos;
     u32 size;
 
@@ -40,32 +26,22 @@ u32 getLoader(u8 *pos, u32 *loaderSize) {
 
     return (u32)(off - pos);
 }
-
-
-// patch_location = (void *)((uintptr_t)firm + section->offset + (version->offset - section->address));
-
-u8 *getProcess9(u8 *pos, u32 size, u32 *process9Size, u32 *process9MemAddr)
-{
-    u8 *off = memsearch(pos, "ess9", size, 4);
-
-    *process9Size = *(u32 *)(off - 0x60) * 0x200;
-    *process9MemAddr = *(u32 *)(off + 0xC);
-
-    //Process9 code offset (start of NCCH + ExeFS offset + ExeFS header size)
-    return off - 0x204 + (*(u32 *)(off - 0x64) * 0x200) + 0x200;
-}
 */
 
-int patch_signatures() {
+/* int patch_signatures() {
     //Look for signature checks
 
        uint8_t pat1[] = {0xC0, 0x1C, 0x76, 0xE7};
        uint8_t pat2[] = {0xB5, 0x22, 0x4D, 0x0C};
 
+       // The code segment.
        uint8_t *firm_mem = (uint8_t*)firm_p9_exefs + sizeof(exefs_h) + firm_p9_exefs->fileHeaders[0].offset;
        uint32_t size = firm_p9_exefs->fileHeaders[0].size;
 
     uint8_t *off  = memfind(firm_mem, size, pat1, 4);
+
+       // We're subbing one because the code goes back 1.
+       // Unique patterns, etc.
     uint8_t *off2 = memfind(firm_mem, size, pat2, 4) - 1;
 
        if (off == NULL) {
@@ -81,20 +57,22 @@ int patch_signatures() {
        fprintf(stderr, "Signatures[0]: 0x%x\n", (uint32_t)off);
        fprintf(stderr, "Signatures[1]: 0x%x\n", (uint32_t)off2);
 
+       // See asm/sigpatches.s for the code here
        uint8_t sigpatch[] = {0x00, 0x20, 0x70, 0x47};
 
        memcpy(off,  sigpatch, 2);
        memcpy(off2, sigpatch, 4);
+
        fprintf(stderr, "Signature patch succeded.\n");
 
        return 0;
-}
+} */
 
 int patch_firmprot() {
        uint8_t *firm_mem = (uint8_t*)firm_p9_exefs + sizeof(exefs_h) + firm_p9_exefs->fileHeaders[0].offset;
        uint32_t size = firm_p9_exefs->fileHeaders[0].size;
 
-    //Look for FIRM writing code
+    // We look for 'exe:' first; this string is close to what we patch
     uint8_t* off = memfind(firm_mem, size, (uint8_t*)"exe:", 4);
 
        if(off == NULL) {
@@ -125,25 +103,28 @@ int patch_firmprot() {
 
 void wait() {
        if (config.options[OPTION_TRACE]) {
-               fprintf(stderr, "Pausing because trace is on.\n");
+               fprintf(stderr, "[press key]\n");
                wait_key();
        }
 }
 
 int patch_firm_all() {
-       link_and_load_patchbin(PATH_PATCHES "/patch.vco");
+       // FIXME - Linker is bork at the moment.
+       execp(PATH_PATCHES "/example.vco");
 
        wait();
 
        // Use builtin signature patcher?
 
+       // TODO - Obviously these get moved to external patchers.
        fprintf(stderr, "Sigpatch: %s\n", ((config.options[OPTION_SIGPATCH]) ? "yes" : "no" ));
        fprintf(stderr, "Protect: %s\n",  ((config.options[OPTION_FIRMPROT]) ? "yes" : "no" ));
 
        wait();
 
        if (config.options[OPTION_SIGPATCH]) {
-               if(patch_signatures()) {
+               // TODO - Patch menu. This is okay-ish for now.
+               if(execp(PATH_PATCHES "/signatures.vco")) {
                        abort("Fatal. Sigpatch has failed.");
                }
        }
index 23253e70a2f5cb2ba2310ac6dd86d89162490bdb..0877155701a693f8f0375f0affef5c96c06d0fe1 100644 (file)
@@ -2,15 +2,15 @@
 .align 4
 .global _start
 _start:
-    @ Change the stack pointer
+    // Change the stack pointer
     mov sp, #0x27000000
 
-    @ Give read/write access to all the memory regions
+    // Give read/write access to all the memory regions
     ldr r5, =0x33333333
     mcr p15, 0, r5, c5, c0, 2 @ write data access
     mcr p15, 0, r5, c5, c0, 3 @ write instruction access
 
-    @ Sets MPU permissions and cache settings
+    // Sets MPU permissions and cache settings
     ldr r0, =0xFFFF001D        @ ffff0000 32k
     ldr r1, =0x01FF801D        @ 01ff8000 32k
     ldr r2, =0x08000027        @ 08000000 1M
@@ -30,24 +30,11 @@ _start:
     mcr p15, 0, r5, c6, c5, 0
     mcr p15, 0, r6, c6, c6, 0
     mcr p15, 0, r7, c6, c7, 0
-    mcr p15, 0, r10, c3, c0, 0 @ Write bufferable 0, 2, 5
-    mcr p15, 0, r11, c2, c0, 0 @ Data cacheable 0, 2, 5
-    mcr p15, 0, r12, c2, c0, 1 @ Inst cacheable 0, 2, 5
 
-    @ Enable caches
-    mrc p15, 0, r4, c1, c0, 0  @ read control register
-    orr r4, r4, #(1<<12)       @ - instruction cache enable
-    orr r4, r4, #(1<<2)        @ - data cache enable
-    orr r4, r4, #(1<<0)        @ - mpu enable
-    mcr p15, 0, r4, c1, c0, 0  @ write control register
+       // Yes, you're reading correctly. We are NOT enabling instruction caching.
+       // It causes issues with the linker, which is why it is left off.
 
-    @ Flush caches
-    mov r5, #0
-    mcr p15, 0, r5, c7, c5, 0  @ flush I-cache
-    mcr p15, 0, r5, c7, c6, 0  @ flush D-cache
-    mcr p15, 0, r5, c7, c10, 4 @ drain write buffer
-
-    @ Fixes mounting of SDMC
+    // Fixes mounting of SDMC
        ldr r0, =0x10000020
        mov r1, #0x340
        str r1, [r0]
index a87b76735b4db03957c3405377741c5735059130..312878e2ca510a51f2dda324d09e0123a9e40945 100644 (file)
 static unsigned int top_cursor_x = 0, top_cursor_y = 0;
 static unsigned int bottom_cursor_x = 0, bottom_cursor_y = 0;
 
-static char text_buffer_top    [TEXT_TOP_SIZE];
-static char text_buffer_bottom [TEXT_BOTTOM_SIZE];
+static char text_buffer_top    [TEXT_TOP_HEIGHT*TEXT_TOP_WIDTH+1];
+static char text_buffer_bottom [TEXT_BOTTOM_HEIGHT*TEXT_BOTTOM_WIDTH+1];
 
-static char color_buffer_top    [TEXT_TOP_SIZE];
-static char color_buffer_bottom [TEXT_BOTTOM_SIZE];
+static char color_buffer_top    [TEXT_TOP_HEIGHT*TEXT_TOP_WIDTH+1];
+static char color_buffer_bottom [TEXT_BOTTOM_HEIGHT*TEXT_BOTTOM_WIDTH+1];
 
 static uint32_t colors[16] = {
        0x000000, // Black
@@ -37,11 +37,21 @@ static uint32_t colors[16] = {
        0xffffff  // White
 };
 
-void clear_screen(uint8_t* screen) {
-       uint32_t size = 0;
-       char* buffer  = 0;
-       uint32_t buffer_size = 0;
+void clear_disp(uint8_t* screen) {
+    if (screen == TOP_SCREEN)
+        screen = framebuffers->top_left;
+    else if (screen == BOTTOM_SCREEN)
+        screen = framebuffers->bottom;
+
+       if(screen == framebuffers->top_left ||
+       screen == framebuffers->top_right) {
+               memset(screen, 0, SCREEN_TOP_SIZE);
+       } else if(screen == framebuffers->bottom) {
+               memset(screen, 0, SCREEN_BOTTOM_SIZE);
+       }
+}
 
+void clear_text(uint8_t* screen) {
     if (screen == TOP_SCREEN)
         screen = framebuffers->top_left;
     else if (screen == BOTTOM_SCREEN)
@@ -49,23 +59,21 @@ void clear_screen(uint8_t* screen) {
 
        if(screen == framebuffers->top_left ||
        screen == framebuffers->top_right) {
-               size = SCREEN_TOP_SIZE;
-               buffer = text_buffer_top;
-               buffer_size = TEXT_TOP_SIZE;
-               top_cursor_x = 0;
-               top_cursor_y = 0;
+               for(int i=0; i < TEXT_TOP_HEIGHT; i++) {
+                       text_buffer_top[i*TEXT_TOP_WIDTH] = 0;
+                       color_buffer_top[i*TEXT_TOP_WIDTH] = 0;
+               }
        } else if(screen == framebuffers->bottom) {
-               size = SCREEN_BOTTOM_SIZE;
-               buffer = text_buffer_bottom;
-               buffer_size = TEXT_BOTTOM_SIZE;
-               bottom_cursor_x = 0;
-               bottom_cursor_y = 0;
-       } else {
-               return; // Invalid buffer.
+               for(int i=0; i < TEXT_BOTTOM_HEIGHT; i++) {
+                       text_buffer_bottom[i*TEXT_BOTTOM_WIDTH] = 0;
+                       color_buffer_bottom[i*TEXT_BOTTOM_WIDTH] = 0;
+               }
        }
+}
 
-    memset(screen, 0, size);
-       memset(buffer, 0, buffer_size);
+void clear_screen(uint8_t* screen) {
+       clear_disp(screen);
+       clear_text(screen);
 }
 
 void set_cursor(void* channel, unsigned int x, unsigned int y) {
@@ -129,75 +137,73 @@ void putc(void* buf, const int c) {
     if (buf == stdout || buf == stderr) {
                unsigned int width  = 0;
                _UNUSED unsigned int height = 0;
-               unsigned int size = 0;
-       unsigned int cursor_x;
-       unsigned int cursor_y;
-       char* colorbuf;
-       char* strbuf;
+       unsigned int *cursor_x;
+       unsigned int *cursor_y;
+       char *colorbuf;
+       char *strbuf;
 
                unsigned char* color = NULL;
 
                if (buf == TOP_SCREEN) {
                        width    = TEXT_TOP_WIDTH;
                        height   = TEXT_TOP_HEIGHT;
-                       size     = TEXT_TOP_SIZE;
            colorbuf = color_buffer_top;
            strbuf   = text_buffer_top;
-           cursor_x = top_cursor_x;
-           cursor_y = top_cursor_y;
+           cursor_x = &top_cursor_x;
+           cursor_y = &top_cursor_y;
                        color = &color_top;
                } else if (buf == BOTTOM_SCREEN) {
                        width    = TEXT_BOTTOM_WIDTH;
                        height   = TEXT_BOTTOM_HEIGHT;
-                       size     = TEXT_BOTTOM_SIZE;
                colorbuf = color_buffer_bottom;
                strbuf   = text_buffer_bottom;
-               cursor_x = bottom_cursor_x;
-               cursor_y = bottom_cursor_y;
+               cursor_x = &bottom_cursor_x;
+               cursor_y = &bottom_cursor_y;
                        color = &color_bottom;
                }
 
-               unsigned int offset = width * cursor_y + cursor_x;
+               if (cursor_x[0] >= width) {
+                       cursor_x[0] = 0;
+                       cursor_y[0]++;
+               }
 
-               if (offset >= size) {
-               // Scroll a line back. This involves memcpy.
-               // Yes, memcpy overwrites part of the buffer it is reading.
-               memcpy(strbuf, strbuf+width, size-width);
-               memcpy(colorbuf, colorbuf+width, size-width);
-               cursor_y -= 1;
-                       offset = width * cursor_y + cursor_x;
-           }
+               while (cursor_y[0] >= height) {
+                       // Scroll.
+                       for(unsigned int y=0; y < height-1; y++) {
+                               memset(&strbuf[y*width], 0, width);
+                               memset(&colorbuf[y*width], 0, width);
+                               strncpy(&strbuf[y*width],   &strbuf[(y+1)*width],   width);
+                               strncpy(&colorbuf[y*width], &colorbuf[(y+1)*width], width);
+                       }
+                       memset(&strbuf[(height-1)*width], 0, width);
+                       memset(&colorbuf[(height-1)*width], 0, width);
 
-               if (offset >= size) {
-               // So if we're being real, this won't ever happen.
-               return;
-           }
+                       cursor_y[0]--;
+
+                       clear_disp(buf); // Clear screen.
+               }
 
            switch(c) {
                case '\n':
-                   cursor_y++;   // Increment line.
-                   cursor_x = 0;
-                   break;
+                   strbuf[cursor_y[0]*width+cursor_x[0]]   = 0;
+                   colorbuf[cursor_y[0]*width+cursor_x[0]] = 0;
+                               cursor_y[0]++;
+                               // Fall through intentional.
                case '\r':
-                   cursor_x = 0; // Reset to beginning of line.
+                   cursor_x[0] = 0; // Reset to beginning of line.
                    break;
                default:
-                   strbuf[offset] = c;
-                   colorbuf[offset] = *color; // White on black.
-                   cursor_x++;
-                   if (cursor_x >= width) {
-                       cursor_y++;
-                       cursor_x = 0;
-                   }
-                   break;
-           }
+                   strbuf[cursor_y[0]*width+cursor_x[0]]   = c;
+                   colorbuf[cursor_y[0]*width+cursor_x[0]] = *color;
+
+                               if (cursor_x[0] + 1 < width) {
+                           strbuf[cursor_y[0]*width+cursor_x[0]+1]   = 0; // Terminate.
+                           colorbuf[cursor_y[0]*width+cursor_x[0]+1] = 0;
+                               }
+
+                   cursor_x[0]++;
 
-           if (buf == TOP_SCREEN) {
-               top_cursor_x = cursor_x;
-               top_cursor_y = cursor_y;
-           } else if (buf == BOTTOM_SCREEN) {
-               bottom_cursor_x = cursor_x;
-               bottom_cursor_y = cursor_y;
+                   break;
            }
        } else {
                // FILE*, not stdin or stdout.
@@ -284,18 +290,22 @@ void put_int(void* channel, int n, int length) {
 
 void fflush(void* channel) {
     if (channel == TOP_SCREEN) {
-               for(int x=0; x < TEXT_TOP_WIDTH; x++) {
-                       for(int y=0; y < TEXT_TOP_HEIGHT; y++) {
+               for(int y=0; y < TEXT_TOP_HEIGHT; y++) {
+                       for(int x=0; x < TEXT_TOP_WIDTH; x++) {
                char c = text_buffer_top[y*TEXT_TOP_WIDTH+x];
+                               if (c == 0)
+                                       break;
                uint32_t color_fg = colors[((color_buffer_top[y*TEXT_TOP_WIDTH+x] >> 4) & 0x0f)];
                uint32_t color_bg = colors[(color_buffer_top[y*TEXT_TOP_WIDTH+x] & 0x0f)];
                                draw_character(framebuffers->top_left, c, x, y, color_fg, color_bg);
                        }
                }
     } else if (channel == BOTTOM_SCREEN) {
-               for(int x=0; x < TEXT_BOTTOM_WIDTH; x++) {
-                       for(int y=0; y < TEXT_BOTTOM_HEIGHT; y++) {
+               for(int y=0; y < TEXT_BOTTOM_HEIGHT; y++) {
+                       for(int x=0; x < TEXT_BOTTOM_WIDTH; x++) {
                char c = text_buffer_bottom[y*TEXT_BOTTOM_WIDTH+x];
+                               if (c == 0)
+                                       break;
                uint32_t color_fg = colors[((color_buffer_bottom[y*TEXT_BOTTOM_WIDTH+x] >> 4) & 0x0f)];
                uint32_t color_bg = colors[(color_buffer_bottom[y*TEXT_BOTTOM_WIDTH+x] & 0x0f)];
                                draw_character(framebuffers->bottom, c, x, y, color_fg, color_bg);
diff --git a/vco/Makefile b/vco/Makefile
new file mode 100644 (file)
index 0000000..a9afaaa
--- /dev/null
@@ -0,0 +1,25 @@
+.PHONY: all copyout
+all: template signatures
+       mkdir -p ../out/corbenik/bin
+       cp template/out/patch.vco ../out/corbenik/bin/example.vco
+       cp signatures/out/patch.vco ../out/corbenik/bin/signatures.vco
+
+.PHONY: clean
+clean: clean_template clean_signatures
+       rm -rf ../out/corbenik/bin
+
+.PHONY: template
+template:
+       make -C template
+
+.PHONY: signatures
+signatures:
+       make -C signatures
+
+.PHONY: clean_template
+clean_template:
+       make -C template clean
+
+.PHONY: clean_signatures
+clean_signatures:
+       make -C signatures clean
diff --git a/vco/README.txt b/vco/README.txt
new file mode 100644 (file)
index 0000000..8ca7465
--- /dev/null
@@ -0,0 +1,44 @@
+Corbenik patch binaries
+----------------------------------
+
+This directory contains the source for vco files - the patcher executables.
+
+You're probably wondering what the heck corbenik does differently from cakes,
+considering it seems similar in many ways.
+
+Patches are actually code for whatever processor they're intended to run on,
+be it ARM9 or ARM11. They're loaded to a static offset in memory, and executed
+from there with relocations to corbenik's internal functions. This keeps patches
+relatively small, and allows complete control over behavior.
+
+Patches should have a declaration of this sort somewhere in them:
+  { 0xc0, 0x9b, 0xe5, 0x1c }
+Followed by a table large enough to fill with all usable functions.
+
+The loader is subject to change at any moment's notice; the ABI is not yet
+stable. It may become an ELF loader at some point. I don't know.
+
+You may want to consult src/loader.c to see what functions are exported, or
+simply base your code on the generic example in the 'template' folder instead.
+
+There's some key differences here, obviously, from running just arm9loader code. Namely:
+
+  1) Patches must not clobber the previous state. Meaning; start does nothing but
+     chain to main.
+
+  2) Patches must properly return, and also return a value. Return code 0 is
+     success; keep this in mind. Corbenik will attempt to reset after a non-
+     zero return code. If you don't know how to return; you're looking for
+     'bx lr'.
+
+  3) Patches must have a symbol table with the appropriate magic.
+     No symbol table? No load. This might be relaxed in future versions
+     to allow patches to be marked static, but IDK.
+
+  4) Don't code a patch that does too fancy stuff. Patches are not intended to
+     be 65k binaries. Seriously.
+
+  5) _start must be at offset 0x24400000. This is where you are in memory.
+
+You can implement shit yourself, but it's an utter waste of memory. Try to use
+the linker exports unless you have a good reason not to.
diff --git a/vco/signatures/Makefile b/vco/signatures/Makefile
new file mode 120000 (symlink)
index 0000000..25eaf27
--- /dev/null
@@ -0,0 +1 @@
+../template/Makefile
\ No newline at end of file
diff --git a/vco/signatures/linker.ld b/vco/signatures/linker.ld
new file mode 120000 (symlink)
index 0000000..6577326
--- /dev/null
@@ -0,0 +1 @@
+../template/linker.ld
\ No newline at end of file
diff --git a/vco/signatures/src/exported.h b/vco/signatures/src/exported.h
new file mode 120000 (symlink)
index 0000000..0cbf2cf
--- /dev/null
@@ -0,0 +1 @@
+../../template/src/exported.h
\ No newline at end of file
diff --git a/vco/signatures/src/headers.h b/vco/signatures/src/headers.h
new file mode 120000 (symlink)
index 0000000..0be6138
--- /dev/null
@@ -0,0 +1 @@
+../../template/src/headers.h
\ No newline at end of file
diff --git a/vco/signatures/src/link_table.s b/vco/signatures/src/link_table.s
new file mode 120000 (symlink)
index 0000000..501d0b2
--- /dev/null
@@ -0,0 +1 @@
+../../template/src/link_table.s
\ No newline at end of file
diff --git a/vco/signatures/src/main.c b/vco/signatures/src/main.c
new file mode 100644 (file)
index 0000000..e343842
--- /dev/null
@@ -0,0 +1,54 @@
+#include <stdint.h>
+#include <stddef.h>
+#include "exported.h"
+
+uint8_t pat1[] = {0xC0, 0x1C, 0x76, 0xE7};
+uint8_t pat2[] = {0xB5, 0x22, 0x4D, 0x0C};
+
+// See asm/sigpatches.s for the code here
+uint8_t sigpatch[] = {0x00, 0x20, 0x70, 0x47};
+
+uint8_t *firm_mem, *off, *off2;
+uint32_t size = 0;
+exefs_h* firm_p9_exefs;
+
+int main() {
+    //Look for signature checks
+       fprintf(stderr, "Applying signature patch\n");
+
+       firm_p9_exefs = get_firm_proc9_exefs();
+
+       fprintf(stderr, "ExeFS: 0x%x\n", firm_p9_exefs);
+
+       // The code segment.
+       firm_mem = (uint8_t*)firm_p9_exefs + sizeof(exefs_h) + firm_p9_exefs->fileHeaders[0].offset;
+       size     = firm_p9_exefs->fileHeaders[0].size;
+
+       fprintf(stderr, "Search, P0.\n");
+    off  = memfind(firm_mem, size, pat1, 4);
+
+       if (off == NULL) {
+               fprintf(stderr, "Failed, P0.\n");
+               return 1; // Failed to find sigpatch. Ugh.
+       }
+
+       // We're subbing one because the code goes back 1.
+       // Unique patterns, etc.
+       fprintf(stderr, "Search, P1.\n");
+    off2 = memfind(firm_mem, size, pat2, 4) - 1;
+
+       if (off2 == NULL) {
+               fprintf(stderr, "Failed, P1.\n");
+               return 2; // Failed to find sigpatch. Ugh.
+       }
+
+       fprintf(stderr, "Signatures, P0, 0x%x\n", (uint32_t)off);
+       memcpy(off,  sigpatch, 2);
+
+       fprintf(stderr, "Signatures, P1, 0x%x\n", (uint32_t)off2);
+       memcpy(off2, sigpatch, 4);
+
+       fprintf(stderr, "Succeded.\n");
+
+       return 0;
+}
diff --git a/vco/signatures/src/start.s b/vco/signatures/src/start.s
new file mode 120000 (symlink)
index 0000000..e408660
--- /dev/null
@@ -0,0 +1 @@
+../../template/src/start.s
\ No newline at end of file
diff --git a/vco/signatures/tool b/vco/signatures/tool
new file mode 120000 (symlink)
index 0000000..37fac4b
--- /dev/null
@@ -0,0 +1 @@
+../template/tool/
\ No newline at end of file
similarity index 97%
rename from patchbins/firmprot/Makefile
rename to vco/template/Makefile
index e2f940b5e7fdb97b4ff94b8730876a7f1a408a72..8a9bca2130ccea3404ca463097c56af0d4c444dc 100644 (file)
@@ -14,7 +14,7 @@ dir_build  := build
 dir_out    := out
 
 ASFLAGS := -mlittle-endian -mcpu=arm946e-s -march=armv5te
-CFLAGS  := -MMD -MP -Wall -Wextra -Werror -O0 $(ASFLAGS) -fno-builtin -std=c11 -DVERSION=\"$(REVISION)\"
+CFLAGS  := -MMD -MP -Wall -Wextra -Werror -O0 $(ASFLAGS) -fno-builtin -std=c11 -marm
 FLAGS   := dir_out=$(abspath $(dir_out)) --no-print-directory
 LDFLAGS := -nostdlib -Wl,-z,defs -lgcc
 
similarity index 74%
rename from patchbins/signatures/src/exported.h
rename to vco/template/src/exported.h
index 9c102aeff2d0431797e9719a0ae338e951cd57dd..495cf313fcebf1746980760a93b75286ce2ffe04 100644 (file)
@@ -1,11 +1,10 @@
 #ifndef EXPORTED_H
 #define EXPORTED_H
 
-#define stdout (void*)0
-#define stderr (void*)1
+#include "headers.h"
 
-extern uint8_t* memory_offset;
-extern uint32_t* memory_len;
+#define stdout ((void*)0)
+#define stderr ((void*)2)
 
 extern int strlen(const char *string);
 extern int isprint(char c);
@@ -22,4 +21,13 @@ extern void putc(void* buf, const int c);
 extern void puts(void* buf, const char *string);
 extern void fprintf(void* channel, const char* format, ...);
 
+extern firm_h* get_firm();
+extern exefs_h* get_firm_proc9_exefs();
+
+extern firm_h* get_agb();
+extern exefs_h* get_agb_proc9_exefs();
+
+extern firm_h* get_twl();
+extern exefs_h* get_twl_proc9_exefs();
+
 #endif
diff --git a/vco/template/src/headers.h b/vco/template/src/headers.h
new file mode 120000 (symlink)
index 0000000..0214d8a
--- /dev/null
@@ -0,0 +1 @@
+../../../source/firm/headers.h
\ No newline at end of file
diff --git a/vco/template/src/link_table.s b/vco/template/src/link_table.s
new file mode 100644 (file)
index 0000000..0c459b5
--- /dev/null
@@ -0,0 +1,69 @@
+.section .text.table
+.align 4
+
+.macro stub name
+       .global \name
+       \name :
+               ldr pc, [pc, #-4] // Load the data after this to the PC. return will be before this call.
+               bx lr // Fall through in case of error.
+.endm
+
+// (int) [0]
+.global MAGIC_START
+MAGIC_START:
+       .byte 0xc0
+       .byte 0x9b
+       .byte 0xe5
+       .byte 0x1c
+
+// Exported functions.
+
+// memory.c
+// (int) [3]
+stub strlen
+// (int) [5]
+stub isprint
+// (int) [7]
+stub memcpy
+// (int) [9]
+stub memmove
+// (int) [11]
+stub memset
+// (int) [13]
+stub memcmp
+// (int) [15]
+stub strncpy
+// (int) [17]
+stub strncmp
+// (int) [19]
+stub atoi
+// (int) [21]
+stub memfind
+
+// draw.c
+// (int) [23]
+stub putc
+// (int) [25]
+stub puts
+// (int) [27]
+stub fprintf
+
+// Wrappers to get shit.
+
+// Gets NATIVE_FIRM memory offset as (firm_h*)
+stub get_firm
+
+// Get NATIVE_FIRM process9
+stub get_firm_proc9_exefs
+
+// Gets AGB_FIRM.
+stub get_agb
+
+// Get AGB_FIRM process9 exefs
+stub get_agb_proc9_exefs
+
+// Gets TWL_FIRM.
+stub get_twl
+
+// Get TWL_FIRM process9 exefs
+stub get_twl_proc9_exefs
diff --git a/vco/template/src/start.s b/vco/template/src/start.s
new file mode 100644 (file)
index 0000000..441e530
--- /dev/null
@@ -0,0 +1,7 @@
+.section .text.start
+.align 4
+.global _start
+_start:
+       b main
+_die:
+       b _die // I have no clue how one would end up here.
similarity index 95%
rename from patchbins/signatures/tool/compile_header.c
rename to vco/template/tool/compile_header.c
index bf8b2ad11f0b06293236ac14f774a5b7f3a348b0..049ff7d1c71c746e1a556c51fea9acffe4d45ccd 100644 (file)
@@ -23,6 +23,13 @@ void read_str(char* name, char* to, size_t len) {
        FILE* hdl = fopen(name, "rb");
        int r = fread(to, 1, len-1, hdl);
        fclose(hdl);
+
+       for(int i=len-1; i >= 0; i--) {
+               if (to[i] == '\n') {
+                       to[i] = 0;
+                       break;
+               }
+       }
 }
 
 uint32_t size = 0;
@@ -40,8 +47,6 @@ uint8_t* read_file_mem(char* name) {
        int r = fread(mem, 1, size, hdl);
        fclose(hdl);
 
-       printf("%d\n", size);
-
        return mem;
 }