]> Chaos Git - corbenik/corbenik.git/commitdiff
So, we now are capable of signature patches.
authorroot <chaos.kagami@gmail.com>
Sat, 14 May 2016 23:11:28 +0000 (19:11 -0400)
committerroot <chaos.kagami@gmail.com>
Sat, 14 May 2016 23:11:28 +0000 (19:11 -0400)
12 files changed:
asm/backdoor.s [new file with mode: 0644]
asm/sigpatches.s [new file with mode: 0644]
source/config.c
source/config.h
source/firm/firm.c
source/firm/firm.h
source/firm/version.c [new file with mode: 0644]
source/main.c
source/menu.c
source/patch_format.h
source/patcher.c
source/std/draw.c

diff --git a/asm/backdoor.s b/asm/backdoor.s
new file mode 100644 (file)
index 0000000..bcd09e1
--- /dev/null
@@ -0,0 +1,14 @@
+// This is svcBackdoor's code from earlier FIRMs
+.arm.little
+.create "backdoor.bin", 0
+       bic r1, sp, #0xff
+       orr r1, r1, #0xf00
+       add r1, r1, #0x28
+       ldr r2, [r1]
+       stmdb r2!, {sp, lr}
+       mov sp, r2
+       blx r0
+       pop {r0, r1}
+       mov sp, r0
+       bx r1
+.close
diff --git a/asm/sigpatches.s b/asm/sigpatches.s
new file mode 100644 (file)
index 0000000..dd1220e
--- /dev/null
@@ -0,0 +1,12 @@
+.arm.little
+
+.create "sig1.to", 0
+.thumb
+mov r0, #0
+.close
+
+.create "sig2.to", 0
+.thumb
+mov r0, #0
+bx lr
+.close
index d4e8eaaca6f9dd22f37ed40e30bda6d2a3d1a7b1..e6b9a0049692508af365948216ab6d9f6dfdce17 100644 (file)
@@ -2,6 +2,8 @@
 
 FILE* conf_handle;
 
+struct config_file config;
+
 void regenerate_config() {
        f_mkdir(PATH_CFW);
     f_mkdir(PATH_FIRMWARES);
@@ -17,6 +19,7 @@ void regenerate_config() {
     memcpy(&(config.magic), CONFIG_MAGIC, 4);
     config.config_ver = config_version;
 
+
     if(!(conf_handle = fopen(PATH_CONFIG, "w")))
         abort("Failed to open config for write?\n");
 
@@ -63,3 +66,14 @@ void load_config() {
     fprintf(BOTTOM_SCREEN, "Config file loaded.\n");
 }
 
+void save_config() {
+       fprintf(stderr, "Saving config.\n");
+
+    f_unlink(PATH_CONFIG);
+
+    if(!(conf_handle = fopen(PATH_CONFIG, "w")))
+        abort("Failed to open config for write?\n");
+
+    fwrite(&config, 1, sizeof(config), conf_handle);
+    fclose(conf_handle);
+}
index 5b4d2506ebc58876cc387b9122df0d48ad9fc8c8..632554329f2f768223aaf9da2365847d94a6f533 100644 (file)
@@ -15,7 +15,7 @@ struct config_file {
     uint64_t patch_ids[256];    // What patches are enabled by UUID. 256 is an arbitrary limit - contact me if you hit it.
 }__attribute__((packed));
 
-_UNUSED static struct config_file config;
+extern struct config_file config;
 
 #define OPTION_SIGPATCH     0  // Use builtin signature patch.
 #define OPTION_LOADER       1  // Use builtin loader module replacer.
@@ -38,6 +38,7 @@ _UNUSED static struct config_file config;
 #define ARROW_COLOR         14 // Color of Arrow.
 
 void load_config();
+void save_config();
 
 /*
 [CORBENIK]
index 27e6000059f601c089d7881825866e382897bc4d..29187ec3366c2b1a10914f55c0107e2c0743f56f 100644 (file)
@@ -8,17 +8,19 @@
 firm_h *firm_loc = (firm_h *)FCRAM_FIRM_LOC;
 static uint32_t firm_size = FCRAM_SPACING;
 firm_section_h firm_proc9;
+exefs_h *firm_p9_exefs;
 
 firm_h *twl_firm_loc = (firm_h *)FCRAM_TWL_FIRM_LOC;
 static uint32_t twl_firm_size = FCRAM_SPACING * 2;
 firm_section_h twl_firm_proc9;
+exefs_h *twl_firm_p9_exefs;
 
 firm_h *agb_firm_loc = (firm_h *)FCRAM_AGB_FIRM_LOC;
 static uint32_t agb_firm_size = FCRAM_SPACING;
 firm_section_h agb_firm_proc9;
+exefs_h *agb_firm_p9_exefs;
 
 static int update_96_keys = 0;
-static int save_firm = 0;
 
 static volatile uint32_t *const a11_entry = (volatile uint32_t *)0x1FFFFFF8;
 
@@ -77,13 +79,12 @@ int decrypt_firm_title(firm_h *dest, ncch_h *ncch, uint32_t *size, void *key) {
     return 0;
 }
 
-int decrypt_arm9bin(arm9bin_h *header, uint64_t firm_title) {
+int decrypt_arm9bin(arm9bin_h *header, uint64_t firm_title, uint8_t version) {
     uint8_t slot = 0x15;
 
     fprintf(BOTTOM_SCREEN, "Decrypting ARM9 FIRM binary\n");
 
-//    if (firm_title == NATIVE_FIRM_TITLEID && version > 0x0F) {
-    if (firm_title == NATIVE_FIRM_TITLEID) {
+    if (firm_title == NATIVE_FIRM_TITLEID && version > 0x0F) {
         uint8_t decrypted_keyx[AES_BLOCK_SIZE];
 
         slot0x11key96_init();
@@ -162,9 +163,12 @@ int load_firm(firm_h *dest, char *path, char *path_firmkey, uint32_t *size, uint
         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);
+
     // The N3DS firm has an additional encryption layer for ARM9
-    // Only run if n3ds.
-    {
+       if (fsig->console == console_n3ds) {
         // Look for the arm9 section
         for (firm_section_h *section = dest->section;
                 section < dest->section + 4; section++) {
@@ -179,7 +183,7 @@ int load_firm(firm_h *dest, char *path, char *path_firmkey, uint32_t *size, uint
 
                 if (arm9bin_iscrypt) {
                     // Decrypt the arm9bin.
-                    if (decrypt_arm9bin((arm9bin_h *)((uintptr_t)dest + section->offset), firm_title)) {
+                    if (decrypt_arm9bin((arm9bin_h *)((uintptr_t)dest + section->offset), firm_title, fsig->version)) {
                         fprintf(BOTTOM_SCREEN, "Couldn't decrypt ARM9 FIRM binary.\n"
                                                "Check if you have the needed key at:\n"
                                                "  " PATH_SLOT0X11KEY96 "\n");
@@ -189,9 +193,9 @@ 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");
-//                    if (firm_type == NATIVE_FIRM && firm_current->version > 0x0F) {
+                    if (firm_title == NATIVE_FIRM_TITLEID && fsig->version > 0x0F) {
                         slot0x11key96_init(); // This has to be loaded regardless, otherwise boot will fail.
-//                    }
+                    }
                 }
 
                 // We assume there's only one section to decrypt.
@@ -206,7 +210,7 @@ int load_firm(firm_h *dest, char *path, char *path_firmkey, uint32_t *size, uint
         write_file(dest, path, *size);
     }
 
-    //if (firm_current->console == console_n3ds)
+    if (fsig->console == console_n3ds)
     {
         fprintf(BOTTOM_SCREEN, "Fixing arm9 entrypoint\n");
 
@@ -257,13 +261,6 @@ void boot_firm() {
         fprintf(BOTTOM_SCREEN, "Updated keyX keyslots\n");
     }
 
-    struct memory_header *memory = (void *)(memory_loc + 1);
-    while ((uintptr_t)memory < (uintptr_t)memory_loc + *memory_loc) {
-        memcpy((void *)memory->location, memory + 1, memory->size);
-        memory = (void *)((uintptr_t)(memory + 1) + memory->size);
-    }
-    fprintf(BOTTOM_SCREEN, "Copied memory\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);
@@ -279,7 +276,7 @@ void boot_firm() {
     ((void (*)())firm_loc->a9Entry)();
 }
 
-int find_proc9(firm_h* firm, firm_section_h* process9) {
+int find_proc9(firm_h* firm, firm_section_h* process9, exefs_h** p9exefs) {
        for (firm_section_h *section = firm->section; section < firm->section + 4; section++) {
                if (section->address == 0)
                        break;
@@ -292,10 +289,10 @@ int find_proc9(firm_h* firm, firm_section_h* process9) {
                                        if (ncch->magic == NCCH_MAGIC) {
                                                // Found Process9
                                                ncch_ex_h *p9exheader = (ncch_ex_h *)(ncch + 1);
-                                               exefs_h *p9exefs = (exefs_h *)(p9exheader + 1);
+                                               *p9exefs = (exefs_h *)(p9exheader + 1);
                                                process9->address = p9exheader->sci.textCodeSet.address;
-                                               process9->size = p9exefs->fileHeaders[0].size;
-                                               process9->offset = (void*)(p9exefs + 1) - (void*)firm;
+                                               process9->size = (*p9exefs)->fileHeaders[0].size;
+                                               process9->offset = (void*)((*p9exefs) + 1) - (void*)firm;
                                                fprintf(BOTTOM_SCREEN, "Found Process9 for FIRM.\n");
                                                return 0;
                                        }
@@ -314,19 +311,19 @@ int load_firms() {
     fprintf(BOTTOM_SCREEN, "Loading NATIVE_FIRM\n");
     if (load_firm(firm_loc, PATH_NATIVE_F, PATH_NATIVE_FIRMKEY, &firm_size, NATIVE_FIRM_TITLEID) != 0)
         return 1;
-    find_proc9(firm_loc, &firm_proc9);
+    find_proc9(firm_loc, &firm_proc9, &firm_p9_exefs);
 
     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");
        else
-       find_proc9(twl_firm_loc, &twl_firm_proc9);
+       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");
        else
-       find_proc9(agb_firm_loc, &agb_firm_proc9);
+       find_proc9(agb_firm_loc, &agb_firm_proc9, &agb_firm_p9_exefs);
 
     return 0;
 }
@@ -336,41 +333,5 @@ void boot_cfw() {
     if (patch_firm_all() != 0)
         return;
 
-    // Only save the firm if that option is required (or it's needed for autoboot),
-    //   and either the patches have been modified, or the file doesn't exist.
-    if ((save_firm || config.options[OPTION_AUTOBOOT]) &&
-            f_stat(PATH_NATIVE_P, NULL) != 0) {
-        fprintf(BOTTOM_SCREEN, "Saving patched NATIVE_FIRM\n");
-        if (write_file(firm_loc, PATH_NATIVE_P, firm_size) != firm_size) {
-            fprintf(BOTTOM_SCREEN, "%pFailed to save patched FIRM.\nWriting SD failed.\nThis is fatal.\n", COLOR(RED, BLACK));
-            return;
-        }
-    }
-
-    if ((save_firm || config.options[OPTION_AUTOBOOT]) &&
-            f_stat(PATH_MEMBIN, NULL) != 0) {
-        fprintf(BOTTOM_SCREEN, "Saving patched memory\n");
-        if (write_file(memory_loc, PATH_MEMBIN, *memory_loc) != *memory_loc) {
-            fprintf(BOTTOM_SCREEN, "%pFailed to save the patched FIRM\nWriting SD failed.\n", COLOR(RED, BLACK));
-            return;
-        }
-    }
-
-    if (f_stat(PATH_TWL_P, NULL) != 0) {
-        fprintf(BOTTOM_SCREEN, "Saving patched TWL_FIRM\n");
-        if (write_file(twl_firm_loc, PATH_TWL_P, twl_firm_size) != twl_firm_size) {
-            fprintf(BOTTOM_SCREEN, "%pFailed to save the patched FIRM\nWriting SD failed.\n", COLOR(RED, BLACK));
-            return;
-        }
-    }
-
-    if (f_stat(PATH_AGB_P, NULL) != 0) {
-        fprintf(BOTTOM_SCREEN, "Saving patched AGB_FIRM\n");
-        if (write_file(agb_firm_loc, PATH_AGB_P, agb_firm_size) != agb_firm_size) {
-            fprintf(BOTTOM_SCREEN, "%pFailed to save the patched FIRM\nWriting SD failed.\n", COLOR(RED, BLACK));
-            return;
-        }
-    }
-
     boot_firm();
 }
index 20eb89ba7eabce09db55e602176550ab6e972f64..73f6e578d355688df81cb8725f9e6b3501e96809 100644 (file)
@@ -3,14 +3,32 @@
 #include <stdint.h>
 #include "headers.h"
 
+enum consoles {
+       console_o3ds,
+       console_n3ds
+};
+
+struct firm_signature {
+       uint8_t sig[0x10];
+       unsigned int version;
+       char version_string[16];
+       enum consoles console;
+};
+
 extern firm_h *firm_loc;
 extern struct firm_signature *current_firm;
+extern firm_section_h firm_proc9;
+extern exefs_h *firm_p9_exefs;
 
 extern firm_h *twl_firm_loc;
 extern struct firm_signature *current_twl_firm;
+extern firm_section_h twl_firm_proc9;
+extern exefs_h *twl_firm_p9_exefs;
 
 extern firm_h *agb_firm_loc;
 extern struct firm_signature *current_agb_firm;
+extern firm_section_h agb_firm_proc9;
+extern exefs_h *agb_firm_p9_exefs;
 
 struct firm_signature *get_firm_info(firm_h *firm);
 void slot0x11key96_init();
diff --git a/source/firm/version.c b/source/firm/version.c
new file mode 100644 (file)
index 0000000..dfd9180
--- /dev/null
@@ -0,0 +1,105 @@
+#include "firm.h"
+#include "../common.h"
+
+// We use the firm's section 0's hash to identify the version
+struct firm_signature firm_signatures[] = {
+    {
+        .sig = {0xEE, 0xE2, 0x81, 0x2E, 0xB9, 0x10, 0x0D, 0x03, 0xFE, 0xA2, 0x3F, 0x44, 0xB5, 0x1C, 0xB3, 0x5E},
+        .version = 0x1F,
+        .version_string = "4.1.0",
+        .console = console_o3ds
+    }, {
+        .sig = {0x8C, 0x29, 0xDA, 0x7B, 0xB5, 0x5F, 0xFE, 0x44, 0x1F, 0x66, 0x79, 0x70, 0x8E, 0xE4, 0x42, 0xE3},
+        .version = 0x2A,
+        .version_string = "6.1.0",
+        .console = console_o3ds
+    }, {
+        .sig = {0x1D, 0x96, 0x80, 0xD9, 0x0A, 0xA9, 0xDB, 0xE8, 0x29, 0x77, 0xCB, 0x7D, 0x90, 0x55, 0xB7, 0xF9},
+        .version = 0x30,
+        .version_string = "7.2.0",
+        .console = console_o3ds
+    }, {
+        .sig = {0x3B, 0x61, 0x2E, 0xBA, 0x42, 0xAE, 0x24, 0x46, 0xAD, 0x60, 0x2F, 0x7B, 0x52, 0x16, 0x82, 0x91},
+        .version = 0x37,
+        .version_string = "8.0.0",
+        .console = console_o3ds
+    }, {
+        .sig = {0x3F, 0xBF, 0x14, 0x06, 0x33, 0x77, 0x82, 0xDE, 0xB2, 0x68, 0x83, 0x01, 0x6B, 0x1A, 0x71, 0x69},
+        .version = 0x38,
+        .version_string = "9.0.0",
+        .console = console_o3ds
+    }, {
+        .sig = {0x5C, 0x6A, 0x51, 0xF3, 0x79, 0x4D, 0x21, 0x91, 0x0B, 0xBB, 0xFD, 0x17, 0x7B, 0x72, 0x6B, 0x59},
+        .version = 0x49,
+        .version_string = "9.6.0",
+        .console = console_o3ds
+    }, {
+        .sig = {0xF5, 0x7E, 0xC3, 0x86, 0x1F, 0x8D, 0x8E, 0xFB, 0x44, 0x61, 0xF3, 0x16, 0x51, 0x0A, 0x57, 0x7D},
+        .version = 0x50,
+        .version_string = "10.4.0",
+        .console = console_o3ds
+    }, {
+        .sig = {0xE9, 0xAD, 0x74, 0x9D, 0x46, 0x9C, 0x9C, 0xF4, 0x96, 0x9E, 0x1A, 0x7A, 0xDF, 0x40, 0x2A, 0x82},
+        .version = 0x52,
+        .version_string = "11.0.0",
+        .console = console_o3ds
+    }, {
+        .sig = {0x31, 0xCC, 0x46, 0xCD, 0x61, 0x7A, 0xE7, 0x13, 0x7F, 0xE5, 0xFC, 0x20, 0x46, 0x91, 0x6A, 0xBB},
+        .version = 0x04,
+        .version_string = "9.0.0",
+        .console = console_n3ds
+    }, {
+        .sig = {0x40, 0x35, 0x6C, 0x9A, 0x24, 0x36, 0x93, 0x7B, 0x76, 0xFE, 0x5D, 0xB1, 0x4D, 0x05, 0x06, 0x52},
+        .version = 0x0F,
+        .version_string = "9.5.0",
+        .console = console_n3ds
+    }, {
+        .sig = {0x07, 0xFE, 0x9A, 0x62, 0x3F, 0xDE, 0x54, 0xC1, 0x9B, 0x06, 0x91, 0xD8, 0x4F, 0x44, 0x9C, 0x21},
+        .version = 0x1B,
+        .version_string = "10.2.0",
+        .console = console_n3ds
+    }, {
+        .sig = {0x1A, 0x56, 0x5C, 0xFF, 0xC9, 0xCC, 0x62, 0xBB, 0x2B, 0xC2, 0x23, 0xB6, 0x4F, 0x48, 0xD1, 0xCC},
+        .version = 0x1F,
+        .version_string = "10.4.0",
+        .console = console_n3ds
+    }, {
+        .sig = {0x52, 0x30, 0x0F, 0x55, 0xA2, 0x64, 0x4E, 0xFF, 0x96, 0x90, 0xF0, 0xE5, 0x6E, 0xC8, 0x2E, 0xB3},
+        .version = 0x21,
+        .version_string = "11.0.0",
+        .console = console_n3ds
+    },
+    {
+        .sig = {0xE8, 0xB8, 0x82, 0xF5, 0x8C, 0xC4, 0x1B, 0x24, 0x05, 0x60, 0x6D, 0xB8, 0x74, 0xF5, 0xE5, 0xDD},
+        .version = 0x16,
+        .version_string = "6.2.0_TWL",
+        .console = console_o3ds
+    }, {
+        .sig = {0x0F, 0x05, 0xC5, 0xF3, 0x60, 0x83, 0x8B, 0x9D, 0xC8, 0x44, 0x3F, 0xB3, 0x06, 0x4D, 0x30, 0xC7},
+        .version = 0x00,
+        .version_string = "9.0.0_TWL",
+        .console = console_n3ds
+    },
+    {
+        .sig = {0x65, 0xB7, 0x55, 0x78, 0x97, 0xE6, 0x5C, 0xD6, 0x11, 0x74, 0x95, 0xDD, 0x61, 0xE8, 0x08, 0x40},
+        .version = 0x0B,
+        .version_string = "6.0.0_AGB",
+        .console = console_o3ds
+    }, {
+        .sig = {0xAF, 0x81, 0xA1, 0xAB, 0xBA, 0xAC, 0xAC, 0xA7, 0x30, 0xE8, 0xD8, 0x74, 0x7C, 0x47, 0x1C, 0x5D},
+        .version = 0x00,
+        .version_string = "9.0.0_AGB",
+        .console = console_n3ds
+    },
+       {.version = 0xFF} // Terminate list
+};
+
+struct firm_signature *get_firm_info(firm_h *firm) {
+    for (struct firm_signature *signature = firm_signatures; signature->version != 0xFF; signature++) {
+        if (memcmp(signature->sig, firm->section[0].hash, 0x10) == 0) {
+            return signature;
+        }
+    }
+
+    return NULL;
+}
index bf2ab7280fd313cc1539a95dc1b53de66913cbf0..e0ea618d8612dca2b297f6e41a7f35a34842c6ae 100644 (file)
@@ -1,7 +1,8 @@
 #include "common.h"
 #include "firm/firm.h"
 
-void init_system() {}
+void init_system() {
+}
 
 int menu_handler();
 
@@ -23,6 +24,10 @@ int main() {
         in_menu = menu_handler();
     }
 
-    init_system();
+       fprintf(BOTTOM_SCREEN, "Booting CFW\n");
+
+       save_config(); // Save config file.
+
+       boot_cfw();
     // Under ideal conditions, we never get here.
 }
index 1c153a68b36eec0dd8f35118d909a8c6fa43902a..a44090bfad33b7b01160ba80577dffe3269ce8bc 100644 (file)
 #define MENU_HELP     5
 #define MENU_RESET    6
 #define MENU_POWER    7
+#define MENU_DUMPBOOT 8
 
 static int cursor_y = 0;
 static int which_menu = 1;
 static int need_redraw = 1;
 
+int menu_dumpboot() {
+       // No, we can't dump the whole bootrom.
+       // I'm still curious what's in the readable half.
+
+       FILE *output9;
+    if(!(output9 = fopen("/bootrom9_low.bin", "w")))
+        abort("Failed to open file for write?\n");
+
+    fwrite((uint8_t*)0xffff0000, 1, 0x8000, output9);
+    fclose(output9);
+
+       fprintf(stderr, "Dumped 0x8000 bytes at 0xffff0000\n");
+
+       return MENU_MAIN;
+}
+
 uint32_t wait_key() {
     uint32_t get = 0;
     while(get == 0) {
@@ -179,9 +196,10 @@ int menu_main() {
         "Help/Readme",
         "Reset",
         "Power off",
+        "Dump partial arm9 bootrom",
         "Boot firmware"
     };
-    int menu_max = 6;
+    int menu_max = 8;
 
     header();
 
@@ -219,6 +237,8 @@ int menu_main() {
         case BUTTON_A:
                        need_redraw = 1;
                        cursor_y = 0;
+            if (ret == 9)
+                               return MENU_BOOTME; // Boot meh, damnit!
             return ret;
     }
 
@@ -249,6 +269,9 @@ int menu_handler() {
         case MENU_HELP:
             to_menu = menu_help();
             break;
+        case MENU_DUMPBOOT:
+            to_menu = menu_dumpboot();
+            break;
         case MENU_BOOTME:
             return 0;
         case MENU_RESET:
index 38879af549fd570b9afbb20432bf940136333a09..d5957cdf8d15d9f7faabc4a577618b4d907f32ed 100644 (file)
@@ -70,6 +70,9 @@ struct system_patch {
     uint8_t patch_data[];     // The data for the patch. This is a sort of interpreted code...see below.
 } __attribute__((packed));
 
+struct patch_opcode {
+} __attribute__((packed));
+
 /*
 [PATCH]
 version=1
index 422fd369d2a191b6f646f18ad37b8ab4e4b51db1..344f859a1f705af4bc751de982dff39bd3b4ecbe 100644 (file)
 #include <stdint.h>
 #include "std/unused.h"
 #include "std/memory.h"
+#include "firm/firm.h"
 #include "config.h"
+#include "common.h"
 
-#define SIGNATURE_CHECK     {0x00, 0x20}
-#define SIGNATURE_CHECK_FIX {0x70, 0x60, 0x70, 0x47}
+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_firm_all() {
        // Use builtin signature patcher?
+
+       fprintf(stderr, "Signature patch: %s\n", ((config.options[OPTION_SIGPATCH]) ? "yes" : "no" ));
        if (config.options[OPTION_SIGPATCH]) {
-               // Yes.
-               // memfind(
+               if(patch_signatures()) {
+                       abort("Fatal. Sigpatch has failed.");
+               }
        }
 
        // Replace loader?
@@ -23,8 +109,11 @@ int patch_firm_all() {
        // Use ARM9 hook thread?
        if (config.options[OPTION_ARM9THREAD]) {
                // Yes.
+
                // FIXME - NYI
        }
 
+       wait_key();
+
        return 0;
 }
index bb10b62a8f50ff975d15a6de75b23e3425c71ae6..a87b76735b4db03957c3405377741c5735059130 100644 (file)
@@ -263,6 +263,17 @@ void put_uint64(void* channel, uint64_t n, int length) {
     puts(channel, out);
 }
 
+void put_hexdump(void* channel, unsigned int num) {
+       uint8_t* num_8 = (uint8_t*)&num;
+       for(int i=3; i>=0; i--) {
+               uint8_t high = (num_8[i] >> 4) & 0xf;
+               uint8_t low  = num_8[i] & 0xf;
+
+               putc(channel, ("0123456789abcdef")[high]);
+               putc(channel, ("0123456789abcdef")[low]);
+       }
+}
+
 void put_uint(void* channel, unsigned int n, int length) {
     put_uint64(channel, n, length);
 }
@@ -386,6 +397,9 @@ check_format:
                 case 'l':
                     ++type_size;
                     goto check_format;
+                               case 'x':
+                                       put_hexdump(channel, va_arg( ap, unsigned int ));
+                                       break;
                 default:
                     if (*ref >= '0' && *ref <= '9') {
                         length = *ref - '0';