]> Chaos Git - corbenik/corbenik.git/commitdiff
Reboot is now functional again, w00t
authorchaoskagami <chaos.kagami@gmail.com>
Wed, 7 Sep 2016 18:13:57 +0000 (14:13 -0400)
committerchaoskagami <chaos.kagami@gmail.com>
Wed, 7 Sep 2016 18:13:57 +0000 (14:13 -0400)
.gitignore
include/firm/firm.h
include/patch/emunand.h
include/patcher.h
source/Makefile.am
source/firm/firm.c
source/main.c
source/patch/emunand.c
source/patch/module.c
source/patch/reboot.c
source/patcher.c

index 9a12a1a3d1d135e251dcc57ca97de0c1cc6c0e76..3bf7965185d5aee3dbc2fffab662a9ad01d916f2 100644 (file)
@@ -31,6 +31,8 @@ depcomp
 /external/Makefile
 /include/Makefile
 /source/corbenik
+/source/corbenik.bin
 /m4
 /include/config.h
 /include/stamp-h1
+/source/corbenik.map
index 93023f30369d9715ac8ef0467ad0597c8eef8286..453bd6075d7a813b5ce7542094a7a9281f510fde 100644 (file)
@@ -31,12 +31,16 @@ struct firm_signature
  */
 struct firm_signature *get_firm_info(firm_h *firm);
 
+/* Loads a firmware off disk, returning it. The memory should be free()'d when done, unless you plan to boot.
+ */
+int prepatch_firm(const char *path, const char *prepatch_path, const char* module_path);
+
 /* Boots the CFW, generating caches and applying patches as-needed to the specified FIRM
  */
-int boot_cfw(char *firm_path);
+int boot_firm(const char *firm_path, const char *prepatch_path, const char* module_path);
 
 /* Loads a firmware off disk, returning it. The memory should be free()'d when done, unless you plan to boot.
  */
-firm_h* load_firm(const char *path);
+firm_h* load_firm(const char *path, size_t *size_out);
 
 #endif
index 1c26bcd9ad61f017ab36d309a19c3a634eb7b0f9..4f294022b6135c1c806000bac22a038acdf73ca9 100644 (file)
@@ -3,6 +3,6 @@
 
 #include <stdint.h>
 
-void patch_emunand(firm_h* firm_loc, uint32_t size);
+int patch_emunand(firm_h* firm_loc, uint32_t size);
 
 #endif
index 40e09d8eb49864ba5f6abbe4607f0383f11e1aac..17ae1380cb8f060ce3eddfad6cfe9e3e36445bb9 100644 (file)
@@ -5,7 +5,7 @@
  *
  * \return zero on success
  */
-int patch_firm_all(uint64_t tid, firm_h* firm);
+int patch_firm_all(uint64_t tid, firm_h* firm, const char* module_path);
 
 /* Generates patch cache for boot/loader for the current configuration.
  *
@@ -13,4 +13,8 @@ int patch_firm_all(uint64_t tid, firm_h* firm);
  */
 int generate_patch_cache();
 
+int patch_svc_calls(firm_h* firm_loc);
+int patch_reboot(firm_h* firm_loc);
+int patch_modules(firm_h* firm_loc, const char* module_path);
+
 #endif
index f62fb997681deda5de582756b450e80e05fa9d10..69045da704df726fda1488d272f4fd8827216962 100644 (file)
@@ -2,7 +2,7 @@ include $(top_srcdir)/common.mk
 
 noinst_PROGRAMS = corbenik
 corbenik_CFLAGS=$(AM_CFLAGS) -T$(srcdir)/linker.ld -nostartfiles
-corbenik_LDFLAGS=$(AM_LDFLAGS) -lctr9
+corbenik_LDFLAGS=$(AM_LDFLAGS) -lctr9 -Wl,-Map,corbenik.map
 EXTRA_DIST = linker.ld
 
 install:
index 376d3b1efafebad5e08b740f61b1cea664de1738..9d15e6240ce6993b5ed515d39e982624f3e12677 100644 (file)
@@ -10,7 +10,7 @@
 #include <firm/internal.h>
 
 firm_h*
-load_firm(const char *path)
+load_firm(const char *path, size_t *size_out)
 {
     int success = 0;
 
@@ -21,6 +21,9 @@ load_firm(const char *path)
 
     size_t size = fsize(firm_file);
 
+    if (size_out)
+        *size_out = size;
+
     uint8_t* mem = malloc(size);
 
     firm_h *firm = (firm_h*)mem;
@@ -69,7 +72,7 @@ load_firm(const char *path)
 
                     patch_entry(firm, sig->type);
 
-                    if (patch_section_keys(firm, sig->k9l)) {
+                    if (sig->type == type_native && patch_section_keys(firm, sig->k9l)) {
                         free(firm);
                         free(mem);
                         return NULL;
@@ -86,9 +89,44 @@ load_firm(const char *path)
 }
 
 int
-boot_cfw(char* firm_path)
+prepatch_firm(const char* firm_path, const char* prepatch_path, const char* module_path)
 {
-    firm_h* firm = load_firm(firm_path);
+       size_t size = 0;
+    firm_h* firm = load_firm(firm_path, &size);
+
+    if (firm == NULL)
+        return 1;
+
+    struct firm_signature *sig = get_firm_info(firm);
+
+    uint64_t tid = 0x0004013800000002LLu;
+
+    if (sig->console == console_n3ds)
+        tid |= 0x20000000LLu;
+
+    tid |= sig->type * 0x100LLu;
+
+    free(sig);
+
+    if (patch_firm_all(tid, firm, module_path)) {
+               free(firm);
+        return 1;
+       }
+
+       FILE* f = fopen(prepatch_path, "w");
+       fwrite(firm, 1, size, f);
+       fclose(f);
+
+       free(firm);
+
+       return 0;
+}
+
+int
+boot_firm(const char* firm_path, const char* prepatch_path, const char* module_path)
+{
+       size_t size = 0;
+    firm_h* firm = load_firm(firm_path, &size);
 
     if (firm == NULL)
         return 1;
@@ -104,8 +142,14 @@ boot_cfw(char* firm_path)
 
     free(sig);
 
-    if (patch_firm_all(tid, firm) != 0)
+    if (patch_firm_all(tid, firm, module_path)) {
+               free(firm);
         return 1;
+       }
+
+       FILE* f = fopen(prepatch_path, "w");
+       fwrite(firm, 1, size, f);
+       fclose(f);
 
     firmlaunch(firm); // <- should NOT return if all is well
 
index 7da5e7715ebea1584d323ee27d04451c35d40efb..cb3135ac87e8ec093bd01a964ecc211cb137802d 100644 (file)
@@ -63,7 +63,17 @@ main(int argc, char** argv)
         generate_patch_cache();
     }
 
-    boot_cfw(config->firm[0]);
+    if (prepatch_firm(config->firm[1], PATH_TWL_P, PATH_MODULE_TWL)) {
+        fprintf(stderr, "WARNING: Failed to load/patch TWL.\n");
+        wait();
+    }
+
+    if(prepatch_firm(config->firm[2], PATH_AGB_P, PATH_MODULE_AGB)) {
+        fprintf(stderr, "WARNING: Failed to load/patch AGB.\n");
+        wait();
+    }
+
+    boot_firm(config->firm[0], PATH_NATIVE_P, PATH_MODULE_NATIVE);
 
     panic("Firmlaunch failed!\n");
 }
index 8c18055f701ccaf270a9331f246ffd0baa536724..69a6e093ae621edb516ff9f6e9675203912c5b3a 100644 (file)
@@ -113,7 +113,7 @@ patchMPU(uint8_t *pos, uint32_t size)
     fprintf(stderr, "emunand: mpu @ %lx\n", (uint32_t)off);
 }
 
-void
+int
 patch_emunand(firm_h* firm_loc, uint32_t index)
 {
 #if 0
@@ -127,11 +127,11 @@ patch_emunand(firm_h* firm_loc, uint32_t index)
     // Copy emuNAND code
     void *emuCodeOffset = getEmuCode(arm9Section, arm9SectionSize);
     if (!emuCodeOffset)
-        panic("emunand: code missing from arm9?\n");
+        return 1;
 
     FILE *f = fopen(PATH_EMUNAND_CODE, "r");
     if (!f)
-        panic("emunand: code not found on SD.\n");
+        return 1;
 
     uint32_t emunand_size = fsize(f);
     fread(emuCodeOffset, 1, emunand_size, f);
@@ -147,7 +147,7 @@ patch_emunand(firm_h* firm_loc, uint32_t index)
              *pos_sdmmc  = (uint32_t *)memfind(emuCodeOffset, emunand_size, "SDMC", 4);
 
     if (!pos_offset || !pos_head || !pos_sdmmc)
-        panic("emunand: couldn't find pattern in hook?\n");
+        return 1;
 
     verify_emunand(index, pos_offset, pos_head);
 
@@ -168,4 +168,5 @@ patch_emunand(firm_h* firm_loc, uint32_t index)
 
     fprintf(stderr, "emunand: patched MPU settings\n");
 #endif
+    return 0;
 }
index 82a76f6e69c246e2d0579bf8af45f3595f4883a6..d148e512501ce4f5bb58f6615d53cd693834dc6a 100644 (file)
@@ -87,10 +87,10 @@ end_inj:
 }
 
 int
-patch_modules(firm_h* firm_loc)
+patch_modules(firm_h* firm_loc, const char* module_path)
 {
     firm_modules = firm_loc;
-    recurse_call(PATH_MODULE_NATIVE, inject_module);
+    recurse_call(module_path, inject_module);
 
     return 0;
 }
index 332d9bfb39bccd62cf163ce6a6e5ae228c2bf517..80c557b301233d00068f4da1d9e6c3e2ccb49708 100644 (file)
@@ -14,7 +14,7 @@ getProcess9(uint8_t *pos, uint32_t size, uint32_t *process9Size, uint32_t *proce
     return off - 0x204 + (*(uint32_t *)(off - 0x64) * 0x200) + 0x200;
 }
 
-void
+int
 patch_reboot(firm_h* firm_loc)
 {
     // Look for firmlaunch code
@@ -51,7 +51,7 @@ patch_reboot(firm_h* firm_loc)
     // Put the fOpen offset in the right location
     uint32_t *pos_fopen = (uint32_t *)memfind(off, size, "open", 4);
     if (!pos_fopen)
-        panic("reboot: fopen location missing\n");
+        return 1;
 
     *pos_fopen = fOpenOffset;
 
@@ -60,7 +60,7 @@ patch_reboot(firm_h* firm_loc)
     uint32_t *pos_agb = (uint32_t *)memfind(off, size, "AGBF", 4);
 
     if (!pos_native && !pos_twl && !pos_agb)
-        panic("reboot: missing string placeholder?\n");
+        return 1;
 
     fprintf(stderr, "reboot: NATF @ %lx\n", (uint32_t)pos_native);
     fprintf(stderr, "reboot: TWLF @ %lx\n", (uint32_t)pos_twl);
@@ -104,8 +104,10 @@ patch_reboot(firm_h* firm_loc)
 
     f = fopen(PATH_REBOOT_CODE, "r");
     if (!f)
-        panic("reboot: boot not found on SD\n");
+        return 1;
 
     fread(mem, 1, fsize(f), f);
     fclose(f);
+
+    return 0;
 }
index 61293efedefa05131dce998f16f17e0c94b7762a..5393f47b88ae36d9af150deaa055e3ea899792a1 100644 (file)
@@ -1,12 +1,6 @@
 #include <common.h>
 #include <stdint.h>
 
-// TODO - Basically all this needs to move to patcher programs.
-
-extern int patch_svc_calls(firm_h*);
-extern int patch_modules(firm_h*);
-extern int patch_reboot(firm_h*);
-
 extern int doing_autoboot;
 
 extern uint8_t *enable_list;
@@ -51,43 +45,43 @@ generate_patch_cache()
 }
 
 int
-patch_firm_all(uint64_t tid, firm_h* firm)
+patch_firm_all(uint64_t tid, firm_h* firm, const char* module_path)
 {
-    execb(tid, firm);
-
-    fprintf(stderr, "VM exited without issue\n");
-
-    // Hook firmlaunch?
-    if (get_opt_u32(OPTION_REBOOT)) {
-        patch_reboot(firm);
-
-        wait();
-    }
+    int exit = 0;
 
-    // Use EmuNAND?
-    if (get_opt_u32(OPTION_EMUNAND)) {
-        // Yes.
-        patch_emunand(firm, get_opt_u32(OPTION_EMUNAND_INDEX));
-
-        wait();
-    }
+    execb(tid, firm);
 
-    // Inject services?
-    if (get_opt_u32(OPTION_SVCS)) {
-        if (patch_svc_calls(firm)) {
-            panic("Fatal. Svc inject has failed.");
-        }
-        wait();
+    switch (tid) {
+        case 0x0004013800000002LLu: // NFIRM
+        case 0x0004013820000002LLu:
+            // Hook firmlaunch?
+            if (get_opt_u32(OPTION_REBOOT))
+                patch_reboot(firm);
+
+            // Use EmuNAND?
+            if (get_opt_u32(OPTION_EMUNAND))
+                patch_emunand(firm, get_opt_u32(OPTION_EMUNAND_INDEX));
+
+            // Inject services?
+            if (get_opt_u32(OPTION_SVCS))
+                if (patch_svc_calls(firm))
+                    exit |= 2;
+            break;
+        case 0x0004013800000102LLu:
+        case 0x0004013820000102LLu:
+            break;
+        case 0x0004013800000202LLu:
+        case 0x0004013820000202LLu:
+            break;
+        default:
+            exit |= 4;
+            break;
     }
 
     // Replace loader?
-    if (get_opt_u32(OPTION_LOADER)) {
-        if (patch_modules(firm)) {
-            panic("Fatal. Loader inject has failed.");
-        }
-        // This requires OPTION_SIGPATCH.
-        wait();
-    }
+    if (get_opt_u32(OPTION_LOADER))
+        if (patch_modules(firm, module_path))
+            exit |= 1;
 
     return 0;
 }