]> Chaos Git - corbenik/corbenik.git/commitdiff
Loader work
authorchaoskagami <chaos.kagami@gmail.com>
Thu, 2 Jun 2016 20:13:37 +0000 (16:13 -0400)
committerchaoskagami <chaos.kagami@gmail.com>
Thu, 2 Jun 2016 20:13:37 +0000 (16:13 -0400)
Now loader doesn't care what bytecode it's running since it loads
from cache files generated during the bootup stage.

It's now back up to sane/tolerably slow speeds on boot.

Still a few kinks to iron out, though.

external/loader/source/interp.h
external/loader/source/patcher.c
source/interp.c
source/patch/aadowngrade.c [deleted file]
source/patch/memexec.c [deleted file]
source/patch/prot.c [deleted file]
source/patch/sig.c [deleted file]
source/patch/unitinfo.c [deleted file]
source/patch_format.h
source/patcher.c

index 06849dd198f782bdee3e2859adee8fb05b60f32f..c34412e3a51671f221056c8febd4c070bb2ddd4c 100644 (file)
@@ -1,6 +1,6 @@
 #ifndef __INTERP_H
 #define __INTERP_H
 
-int execb(char* filename, uint64_t tid, uint8_t* search_mem, uint32_t search_len);
+int execb(uint64_t tid, uint8_t* search_mem, uint32_t search_len);
 
 #endif
index 8a72b2bfcf2d2550f4685c0c599d29fe4de3cb85..55c7f45337a04b8eb76ec8417db215a56c2013e4 100644 (file)
@@ -356,16 +356,7 @@ patch_text(u64 progId, u8* text, u32 size, u32 orig_size)
        if (progId == 0x0004013000008002LL)
         adjust_cpu_settings(progId, text, orig_size);
 
-       execb(PATH_PATCHES "/block_nim_update.vco", progId, text, orig_size);
-       execb(PATH_PATCHES "/block_eshop_update.vco", progId, text, orig_size);
-       execb(PATH_PATCHES "/block_cart_update.vco", progId, text, orig_size);
-       execb(PATH_PATCHES "/errdisp.vco", progId, text, orig_size);
-       execb(PATH_PATCHES "/friends_ver.vco", progId, text, orig_size);
-       execb(PATH_PATCHES "/mset_str.vco", progId, text, orig_size);
-//     execb(PATH_PATCHES "/ns_force_menu.vco", progId, text, orig_size);
-       execb(PATH_PATCHES "/regionfree.vco", progId, text, orig_size);
-       execb(PATH_PATCHES "/secinfo_sigs.vco", progId, text, orig_size);
-       execb(PATH_PATCHES "/ro_sigs.vco", progId, text, orig_size);
+       execb(progId, text, orig_size);
 
     language_emu(progId, text, orig_size);
 }
index 462d26553d8b9e43e4de107549a89dc4e10304b1..b20e0e94b2199108488e7d11cad34f2c243eb960 100644 (file)
@@ -248,8 +248,10 @@ int exec_bytecode(uint8_t* bytecode, uint32_t len, int debug) {
                                break;
                        case OP_NEXT:
                                bytecode = code + 1;
+#ifndef LOADER
                                set_mode = 3;
                                current_mode = &modes[set_mode];
+#endif
                                offset = 0;
                                test_was_false = 0;
                                code = bytecode;
@@ -286,31 +288,37 @@ int exec_bytecode(uint8_t* bytecode, uint32_t len, int debug) {
 }
 
 #ifdef LOADER
-int execb(char* filename, uint64_t tid, uint8_t* search_mem, uint32_t search_len) {
+int execb(uint64_t tid, uint8_t* search_mem, uint32_t search_len) {
 #else
 int execb(char* filename) {
 #endif
        uint32_t patch_len;
-       struct system_patch* patch;
 #ifdef LOADER
-       log("  check ");
-       log(filename);
-       log("\n");
+       char cache_path[] = PATH_LOADER_CACHE "/0000000000000000";
+       int len = strlen(cache_path) - 16;
 
-       uint8_t  patch_dat2[MAX_PATCHSIZE];
-       uint8_t *patch_dat = patch_dat2;
+       uint8_t* title_buf = (uint8_t*)&tid;
 
-       patch = (struct system_patch*)patch_dat;
+       for(int j = 0; j < 8; j++) {
+               cache_path[len+(j*2)] =   ("0123456789ABCDEF")[(title_buf[j] >> 4) & 0x0f];
+               cache_path[len+(j*2)+1] = ("0123456789ABCDEF")[ title_buf[j] & 0x0f];
+       }
+
+       static uint8_t  patch_dat[MAX_PATCHSIZE];
 
        Handle file;
        u32 total;
 
     // Open file.
-    if (!R_SUCCEEDED(fileOpen(&file, ARCHIVE_SDMC, filename, FS_OPEN_READ))) {
+    if (!R_SUCCEEDED(fileOpen(&file, ARCHIVE_SDMC, cache_path, FS_OPEN_READ))) {
         // Failed to open.
-        return 1;
+        return 0; // No patches.
     }
 
+       log("  patch: ");
+       log(cache_path);
+       log("\n");
+
        u64 file_size;
 
        if (!R_SUCCEEDED(FSFILE_GetSize(file, &file_size))) {
@@ -341,45 +349,12 @@ int execb(char* filename) {
        modes[18].memory = search_mem;
        modes[18].size   = search_len;
 
-       // Check magic.
-       if (memcmp(patch->magic, "AIDA", 4)) {
-               log("  magic wrong\n");
-
-               return 1; // Incorrect patch magic.
-       }
-
-       // Check TID supported.
-       if (patch->titles == 0) {
-               return 0; // Not an error - this patch isn't meant for us.
-       }
-
-       log("  checking tid\n");
-
-       uint8_t* title_buf = patch_dat + sizeof(struct system_patch);
-
-       int apply = 0;
-
-       for(uint32_t i=0; i < patch->titles; i++, title_buf += 8) {
-               if(!memcmp(title_buf, (uint8_t*)&tid, 8)) {
-                       // Applicable patch found.
-                       log("  applicable\n");
-                       apply = 1;
-                       break;
-               }
-       }
-
-       if (!apply) {
-               // Not meant for us.
-               return 0;
-       }
-
-       // Patch is relevant to us, so we'll apply it.
-
        log("  exec\n");
 
-       uint8_t* patch_mem = (uint8_t*)patch + sizeof(struct system_patch) + (patch->depends * 8) + (patch->titles * 8);
-       patch_len = patch->size;
+       uint8_t* patch_mem = (uint8_t*)patch_dat;
+       patch_len = file_size;
 #else
+       struct system_patch* patch;
        uint8_t* patch_mem;
        // Read patch to scrap memory.
 
@@ -396,17 +371,40 @@ int execb(char* filename) {
                return 1;
        }
 
+       patch_mem = (uint8_t*)patch + sizeof(struct system_patch) + (patch->depends * 8) + (patch->titles * 8);
+       patch_len = patch->size;
+
        if (patch->titles != 0) {
                // Not an error, per se, but it means this patch is meant for loader, not us.
                // Patches intended for use during boot will always be applied to zero titles.
                // We should generate a cache for loader in a file intended for titleid.
+               uint8_t* title_buf = (uint8_t*)patch + sizeof(struct system_patch);
+
+               for(uint32_t i=0; i < patch->titles; i++, title_buf += 8) {
+                       // FIXME - This is outputting once per boot. We need to detect and nuke the cache.
+                       char cache_path[] = PATH_LOADER_CACHE "/0000000000000000";
+                       int len = strlen(cache_path) - 16;
+
+                       for(int j = 0; j < 8; j++) {
+                               cache_path[len+(j*2)] =   ("0123456789ABCDEF")[(title_buf[j] >> 4) & 0x0f];
+                               cache_path[len+(j*2)+1] = ("0123456789ABCDEF")[ title_buf[j] & 0x0f];
+                       }
+
+                       char reset = 0xFF;
+
+                       FILE* cache = fopen(cache_path, "w");
+                       fseek(cache, 0, SEEK_END);
+                       fwrite(patch_mem, 1, patch_len, cache);
+                       fwrite(&reset, 1, 1, cache);
+                       fclose(cache);
+                       // Add to cache.
+               }
+
                return 0;
        }
 
        fprintf(stderr, "Patch: %s\n", patch->name);
 
-       patch_mem = (uint8_t*)patch + sizeof(struct system_patch) + (patch->depends * 8) + (patch->titles * 8);
-       patch_len = patch->size;
 #endif
        return exec_bytecode(patch_mem, patch_len, 0);
 }
diff --git a/source/patch/aadowngrade.c b/source/patch/aadowngrade.c
deleted file mode 100644 (file)
index f7aa638..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#include "patch_file.h"
-
-PATCH(aadowngrade)
-{
-       execb(PATH_PATCHES "/aadowngrade.vco");
-
-    return 0;
-}
diff --git a/source/patch/memexec.c b/source/patch/memexec.c
deleted file mode 100644 (file)
index 4fc0b33..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-#include "patch_file.h"
-
-// This patch clears MPU settings which lock down memory
-// execution from userland. You should NOT enable this
-// unless you know you need it, because it makes an obvious
-// behavioral change that can be used maliciously and/or to
-// detect CFW use rather easily.
-
-PATCH(memexec)
-{
-       execb(PATH_PATCHES "/memexec.vco");
-
-    return 0;
-}
diff --git a/source/patch/prot.c b/source/patch/prot.c
deleted file mode 100644 (file)
index 47ebcf3..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-#include "patch_file.h"
-
-// This patch applies the FIRM protection code needed for safe a9lh usage.
-
-PATCH(firmprot)
-{
-       execb(PATH_PATCHES "/prot.vco");
-
-    return 0;
-}
diff --git a/source/patch/sig.c b/source/patch/sig.c
deleted file mode 100644 (file)
index dbc46e5..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-#include "patch_file.h"
-
-// This patch is responsible for fixing signature checks for the firmware.
-
-PATCH(signatures)
-{
-       execb(PATH_PATCHES "/sig.vco");
-
-    return 0;
-}
diff --git a/source/patch/unitinfo.c b/source/patch/unitinfo.c
deleted file mode 100644 (file)
index 9649449..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-#include "patch_file.h"
-
-// This patch makes the console think it is a developer unit.
-// Note that this is generally invasive and not useful to users;
-// usually the ErrDisp patch in loader should be good enough for
-// debugging crashes.
-
-PATCH(unitinfo)
-{
-       execb(PATH_PATCHES "/unitinfo.vco");
-
-    return 0;
-}
index 9c9186426bdedd3209caa46a5c625541ad9917f4..e6990712d7158a6f138c0a88c41cc530b4f9a31f 100644 (file)
@@ -42,6 +42,9 @@
 #define PATH_FIRMWARES PATH_CFW "/lib/firmware" // Firmware folder.
 #define PATH_MODULES PATH_CFW "/lib/module"     // Sysmodule location
 #define PATH_SERVICES PATH_CFW "/lib/service"   // Service code location.
+
+#define PATH_LOADER_CACHE PATH_CFW "/lib/loader" // Cached patch bytecode for loader.
+
 #define PATH_TEMP                                                              \
     PATH_CFW "/tmp" // Files that are transient (user can delete them and they
                     // will be regenerated)
index a93332e026f29fe24746e15adb07776dfd0c0ae0..4f2d0ad45ab749765e3e9d80308750cfe6bb0837 100644 (file)
@@ -4,18 +4,14 @@
 #include "firm/firm.h"
 #include "config.h"
 #include "common.h"
+#include "interp.h"
 
 // TODO - Basically all this needs to move to patcher programs.
 
 uint32_t wait_key();
 
-extern int patch_signatures();
-extern int patch_firmprot();
 extern int patch_services();
 extern int patch_modules();
-extern int patch_aadowngrade();
-extern int patch_memexec();
-extern int patch_unitinfo();
 
 extern int doing_autoboot;
 
@@ -32,25 +28,21 @@ wait()
 int
 patch_firm_all()
 {
-    // Use builtin signature patcher?
-
-    if (config.options[OPTION_SIGPATCH]) {
-        // TODO - Patch menu. This is okay-ish for now.
-        //             if(execp(PATH_PATCHES "/signatures.vco")) {
-        if (patch_signatures()) {
-            abort("Fatal. Sigpatch has failed.");
-        }
-
-           wait();
-    }
-
-    if (config.options[OPTION_FIRMPROT]) {
-        if (patch_firmprot()) {
-            abort("Fatal. Firmprot has failed.");
-        }
-
-           wait();
-    }
+       // Remove cache
+       f_unlink(PATH_LOADER_CACHE);
+       f_mkdir(PATH_LOADER_CACHE);
+
+       // Loader only uses TID cache bytecode, so run through these.
+       execb(PATH_PATCHES "/block_nim_update.vco");
+       execb(PATH_PATCHES "/block_eshop_update.vco");
+       execb(PATH_PATCHES "/block_cart_update.vco");
+       execb(PATH_PATCHES "/errdisp.vco");
+       execb(PATH_PATCHES "/friends_ver.vco");
+       execb(PATH_PATCHES "/mset_str.vco");
+//     execb(PATH_PATCHES "/ns_force_menu.vco");
+       execb(PATH_PATCHES "/regionfree.vco");
+       execb(PATH_PATCHES "/secinfo_sigs.vco");
+       execb(PATH_PATCHES "/ro_sigs.vco");
 
     // Replace loader?
     if (config.options[OPTION_LOADER]) {
@@ -77,8 +69,26 @@ patch_firm_all()
                wait();
     }
 
+    // Use builtin signature patcher?
+    if (config.options[OPTION_SIGPATCH]) {
+        // TODO - Patch menu. This is okay-ish for now.
+               if(execb(PATH_PATCHES "/sig.vco")) {
+            abort("Fatal. Sigpatch has failed.");
+        }
+
+           wait();
+    }
+
+    if (config.options[OPTION_FIRMPROT]) {
+               if(execb(PATH_PATCHES "/prot.vco")) {
+            abort("Fatal. Firmprot has failed.");
+        }
+
+           wait();
+    }
+
        if (config.options[OPTION_AADOWNGRADE]) {
-        if (patch_aadowngrade()) {
+               if(execb(PATH_PATCHES "/aadowngrade.vco")) {
             abort("Anti-anti-downgrade patch failed.");
         }
 
@@ -86,7 +96,7 @@ patch_firm_all()
        }
 
        if (config.options[OPTION_UNITINFO]) {
-        if (patch_unitinfo()) {
+               if(execb(PATH_PATCHES "/unitinfo.vco")) {
             abort("UNITINFO patch failed.");
         }
 
@@ -94,7 +104,7 @@ patch_firm_all()
        }
 
        if (config.options[OPTION_MEMEXEC]) {
-        if (patch_memexec()) {
+               if(execb(PATH_PATCHES "/memexec.vco")) {
             abort("MPU execution patch failed.");
         }