]> Chaos Git - corbenik/corbenik.git/commitdiff
Add logging to loader (yes, that means sdmc write support)
authorchaoskagami <chaos.kagami@gmail.com>
Tue, 31 May 2016 11:53:37 +0000 (07:53 -0400)
committerchaoskagami <chaos.kagami@gmail.com>
Tue, 31 May 2016 11:53:37 +0000 (07:53 -0400)
18 files changed:
external/loader/README.md
external/loader/source/internal.h
external/loader/source/loader.c
external/loader/source/logger.c [new file with mode: 0644]
external/loader/source/logger.h [new file with mode: 0644]
external/loader/source/memory.c [new file with mode: 0644]
external/loader/source/memory.h [new file with mode: 0644]
external/loader/source/patch/block_cart_update.c
external/loader/source/patch/block_eshop_update.c
external/loader/source/patch/block_nim_update.c
external/loader/source/patch/friends_ver.c
external/loader/source/patch/mset_str.c
external/loader/source/patch/patch.h
external/loader/source/patch/regionfree.c
external/loader/source/patch/ro_sigs.c
external/loader/source/patch/secinfo_sigs.c
external/loader/source/patcher.c
external/loader/source/patcher.h

index ca2d3ec1974827798e69eedc6775c312fb8855b4..579f44e03a4160ec83b614773b15a0dc3333f4e9 100644 (file)
@@ -13,40 +13,52 @@ There is support for patching any executable after it's loaded but
 before it starts. For example, you can patch `menu` to skip region checks and 
 have region free game launching directly from the home menu.
 
-This currently requires recompilation which makes it less than ideal.
+There is also support for SDMC read/write (not found in original loader
+implementation) which means that information can be logged to SD.
 
-There is also support for SDMC reading (not found in original loader
-implementation) which  means that patches can be loaded from the SD card.
-Ultimately, there will be a patch system that supports easy loading of
-patches from the SD card.
+## About this fork
 
-## Changes I've made
+A lot of the 'disassembled' looking code has been rewritten for readability
+(notable the lzss decompressor), and some cruft was cleaned out. Notably,
+IFile increased the cxi size by two (!) pages, and therefore has been removed,
+as it offers nothing over direct use of FSFILE and FSLDR.
 
-A lot of the 'disassembled' looking code has been rewritten for readability, and
-many cruft-ish artifacts of it have been cleaned up. Some wrapper functions
-have also been rewritten out of the code, and anything nigh-unreadable and
-non-rewritable has been documented when I managed to figure out what it does.
+This version of loader is capable of logging to the filesystem through added
+write support. Tecnically, all the work for this was already in place, but IFile
+didn't allow accessing this functionality. This makes debugging much easier,
+since you can now actually figure out what went wrong.
 
-At the moment there is also experimental support for resizing segments before
-loading the executable. This means that segments can be appended to. Notably,
-this allows tacking on code to the end.
+Experimental support for resizing segments before loading the executable was
+added. This means that segments can be appended to. Notably, this allows tacking
+code onto the end.
 
-The text, data, and ro segments are handled separately to streamline the new
-segment resizing and limit search space to speed things up a tad. Why search
-text, data and ro (big) when you know it is in text?
+The text, data, and ro segments are now handled separately to speed things up
+marginally, since if you know a patch is applied to text there's no reason to
+search the data segment, etc.
 
 ## Imported changes from other 3ds_injector forks
 
-I updated it to the latest git ctrulib (in which FS_Archive is a u64,
-not a struct.) @TuxSH did the work before me, although it required manual
-conflict merges since my tree differs a LOT from both @yifanlu and his
-version.
+This was updated to the latest git ctrulib (in which FS_Archive typing has
+changed to allow mountpoints.)
+
+@TuxSH did this work before me, although I had to implement changes
+manually due to my tree sharing almost nothing at this point with upstream or
+Luma. It did serve as a useful reference, though. :)
 
 ## Build
 You need a working 3DS build environment with a fairly recent copy of devkitARM, 
 ctrulib, and makerom.
 
-This is not intended to be used with anything but corbenik, so please don't use
-binaries of this with any other CFW. For devs - message me if there's any changes
-you want help merging. I'll be glad to help. I'm not into anti-competitive
-behavior. ;P
+This will automatically be built by corbenik's top-level makefile, so you shouldn't
+need to monkey around in here if you aren't making changes.
+
+## Misc
+
+This is not intended to be used with anything but corbenik due to specific use of
+structures incompatible with other CFW, so don't attempt to inject this with other
+CFWs. At best, it doesn't work. At worst, you can't boot without removing it.
+
+For devs - message me if there's any changes you want help merging to your fork.
+I'll be glad to help, either to explain what has been done here or to port changes.
+I'm not into anti-competitive behavior, since we're all just trying to make the 3DS
+better as a whole. ;P
index f41080477ea8c0f1a3a5e368ecf6468de8f6933f..a3ead0742430a35dbbe23f4c6b3379fc176275f9 100644 (file)
@@ -1,8 +1,8 @@
 #ifndef __INTERNAL_H
 #define __INTERNAL_H
 
-// This is a GCC builtin, and so there's no need to carry an implementation
-// here.
+// These are libc builtins, so there's no need to carry an implementation here.
 void* memcpy(void* dest, const void* src, size_t len);
+size_t strlen(const char* string);
 
 #endif
index b7ed35b38d8e50e20733c463d87319a9059b65e3..e0a0269170de6cc7ea0476a6a01c815149f948fa 100644 (file)
@@ -7,6 +7,7 @@
 #include "srvsys.h"
 #include "lzss.h"
 #include "internal.h"
+#include "logger.h"
 
 // TODO - a lot of this is unecessarily verbose and shitty. Clean it up to be
 // tidy.
@@ -160,6 +161,8 @@ loader_LoadProcess(Handle* process, u64 prog_handle)
     u64 progid;
     u32 text_grow, data_grow, ro_grow;
 
+       openLogger();
+
     // make sure the cached info corrosponds to the current prog_handle
     if (g_cached_prog_handle != prog_handle) {
         res = loader_GetProgramInfo(&g_exheader, prog_handle);
@@ -182,6 +185,8 @@ loader_LoadProcess(Handle* process, u64 prog_handle)
         return MAKERESULT(RL_PERMANENT, RS_INVALIDARG, 1, 2);
     }
 
+       logstr("validated params\n");
+
     load_config(); // First order of business - we need the config file.
 
     // Check and set the CPU mode. Possible values: 0 - Keep o3ds speed, 1 -
@@ -255,6 +260,8 @@ loader_LoadProcess(Handle* process, u64 prog_handle)
             &codeset, &codesetinfo, (void*)shared_addr.text_addr,
             (void*)shared_addr.ro_addr, (void*)shared_addr.data_addr);
         if (res >= 0) {
+                       closeLogger();
+
             res =
                 svcCreateProcess(process, codeset,
                                  g_exheader.arm11kernelcaps.descriptors, count);
diff --git a/external/loader/source/logger.c b/external/loader/source/logger.c
new file mode 100644 (file)
index 0000000..b440683
--- /dev/null
@@ -0,0 +1,60 @@
+#include <3ds.h>
+#include "patcher.h"
+#include "fsldr.h"
+#include "internal.h"
+#include "memory.h"
+
+#ifndef PATH_MAX
+#define PATH_MAX 255
+#define _MAX_LFN 255
+#endif
+#include "config.h"
+#include "../../../source/patch_format.h"
+
+#include "patch/patch.h"
+
+Handle log_file_hdl;
+int logger_is_initd = 0;
+
+void openLogger() {
+    Result r;
+
+    if (logger_is_initd)
+        return;
+
+    r = fileOpen(&log_file_hdl, ARCHIVE_SDMC, "/corbenik/loader.log", FS_OPEN_WRITE|FS_OPEN_READ|FS_OPEN_CREATE);
+
+    if (R_FAILED(r)) {
+        logger_is_initd = -1;
+    }
+
+       logger_is_initd = 1;
+}
+
+void logstr(const char* str) {
+       if (logger_is_initd == -1)
+               return; // Errored during init. Don't bother.
+
+       u32 len = strlen(str);
+       u64 size;
+       u32 wrote;
+       Result r;
+
+       // Get current size.
+       r = FSFILE_GetSize(log_file_hdl, &size);
+    if (R_FAILED(r))
+               return;
+
+       // Expand file size.
+       r = FSFILE_SetSize(log_file_hdl, size+len);
+    if (R_FAILED(r))
+               return;
+
+       // Write data.
+       FSFILE_Write(log_file_hdl, &wrote, size, str, len, 0);
+}
+
+void closeLogger() {
+       FSFILE_Close(log_file_hdl);
+       logger_is_initd = 0;
+}
diff --git a/external/loader/source/logger.h b/external/loader/source/logger.h
new file mode 100644 (file)
index 0000000..912f9bd
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef __LOGGER_H
+#define __LOGGER_H
+
+void openLogger();
+void logstr(const char* str);
+void closeLogger();
+
+#endif
diff --git a/external/loader/source/memory.c b/external/loader/source/memory.c
new file mode 100644 (file)
index 0000000..40a9ddd
--- /dev/null
@@ -0,0 +1,92 @@
+#include <3ds.h>
+#include "patcher.h"
+#include "fsldr.h"
+#include "internal.h"
+
+#ifndef PATH_MAX
+#define PATH_MAX 255
+#define _MAX_LFN 255
+#endif
+#include "config.h"
+#include "../../../source/patch_format.h"
+
+#include "patch/patch.h"
+
+int
+memcmp(const void* buf1, const void* buf2, u32 size)
+{
+    const u8* buf1c = (const u8*)buf1;
+    const u8* buf2c = (const u8*)buf2;
+
+    for (u32 i = 0; i < size; i++) {
+        int cmp = buf1c[i] - buf2c[i];
+        if (cmp)
+            return cmp;
+    }
+
+    return 0;
+}
+
+// Quick Search algorithm, adapted from
+// http://igm.univ-mlv.fr/~lecroq/string/node19.html#SECTION00190
+u8*
+memfind(u8* startPos, u32 size, const void* pattern, u32 patternSize)
+{
+    const u8* patternc = (const u8*)pattern;
+
+    // Preprocessing
+    u32 table[256];
+
+    for (u32 i = 0; i < 256; ++i)
+        table[i] = patternSize + 1;
+    for (u32 i = 0; i < patternSize; ++i)
+        table[patternc[i]] = patternSize - i;
+
+    // Searching
+    u32 j = 0;
+
+    while (j <= size - patternSize) {
+        if (memcmp(patternc, startPos + j, patternSize) == 0)
+            return startPos + j;
+        j += table[startPos[j + patternSize]];
+    }
+
+    return NULL;
+}
+
+u32
+patchMemory(u8* start, u32 size, const void* pattern, u32 patSize, int offset,
+            const void* replace, u32 repSize, u32 count)
+{
+    u32 i;
+
+    for (i = 0; i < count; i++) {
+        u8* found = memfind(start, size, pattern, patSize);
+
+        if (found == NULL)
+            break;
+
+        // FIXME - This is throwing on Werror.
+        memcpy(found + offset, replace, repSize);
+
+        u32 at = (u32)(found - start);
+
+        if (at + patSize > size)
+            break;
+
+        size -= at + patSize;
+        start = found + patSize;
+    }
+
+    return i;
+}
+
+size_t
+strnlen(const char* string, size_t maxlen)
+{
+    size_t size;
+
+    for (size = 0; *string && size < maxlen; string++, size++);
+
+    return size;
+}
diff --git a/external/loader/source/memory.h b/external/loader/source/memory.h
new file mode 100644 (file)
index 0000000..9eebaa7
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef __MEMORY_H
+#define __MEMORY_H
+
+int memcmp(const void* buf1, const void* buf2, u32 size);
+u8* memfind(u8* startPos, u32 size, const void* pattern, u32 patternSize);
+u32 patchMemory(u8* start, u32 size, const void* pattern, u32 patSize, int offset,
+                const void* replace, u32 repSize, u32 count);
+size_t strnlen(const char* string, size_t maxlen);
+
+#endif
index bf307c8c1e5e81bee485d4f95fca673c9ef61251..5ba83fe0464c74be625e7b149c8fc4670d05e0dd 100644 (file)
@@ -10,4 +10,6 @@ disable_cart_updates(u64 progId, u8* code, u32 size)
     patchMemory(code, size, stopCartUpdatesPattern,
                 sizeof(stopCartUpdatesPattern), 0, stopCartUpdatesPatch,
                 sizeof(stopCartUpdatesPatch), 2);
+
+       logstr("disable_cart_updates\n");
 }
index d240154915ddb5dc57de4207a3f6ba6f9fd2dcb6..c0c480391117dc85b68ddd9baa742f79f5db68f2 100644 (file)
@@ -12,4 +12,6 @@ disable_eshop_updates(u64 progId, u8* code, u32 size)
                 sizeof(skipEshopUpdateCheckPattern), 0,
                 skipEshopUpdateCheckPatch, sizeof(skipEshopUpdateCheckPatch),
                 1);
+
+       logstr("disable_eshop_updates\n");
 }
index eee7d5397300f215b67853bc549ac844b0112f45..c3753dabc43fa26113502d24650c171c05cac2c7 100644 (file)
@@ -10,4 +10,6 @@ disable_nim_updates(u64 progId, u8* code, u32 size)
     patchMemory(code, size, blockAutoUpdatesPattern,
                 sizeof(blockAutoUpdatesPattern), 0, blockAutoUpdatesPatch,
                 sizeof(blockAutoUpdatesPatch), 1);
+
+       logstr("disable_nim_updates\n");
 }
index fc50ecb7174e40b598a066f1998eb40c02f51071..07a0e24dfe323b3c4c81236ba8ab36b49ba61cec 100644 (file)
@@ -10,4 +10,6 @@ fake_friends_version(u64 progId, u8* code, u32 size)
     // Allow online access to work with old friends modules
     patchMemory(code, size, fpdVerPattern, sizeof(fpdVerPattern), 9,
                 &fpdVerPatch, sizeof(fpdVerPatch), 1);
+
+       logstr("fake_friends_version\n");
 }
index 96908792f6fceb9ad38ccc9cf739e787eecfb950..f5ba815cf72e62a91e16ce5a6ac7137e6ac325d9 100644 (file)
@@ -9,4 +9,6 @@ settings_string(u64 progId, u8* code, u32 size)
     // Patch Ver. string
     patchMemory(code, size, verPattern, sizeof(verPattern) - sizeof(u16), 0,
                 verPatch, sizeof(verPatch) - sizeof(u16), 1);
+
+       logstr("settings_string\n");
 }
index a9ed7ed39b285c94587dd1f4197255f0d39e37cf..de6c95d883625f86760ced7b081301242b23ec6b 100644 (file)
@@ -3,6 +3,8 @@
 
 #include <3ds.h>
 #include "../patcher.h"
+#include "../memory.h"
+#include "../logger.h"
 
 #ifndef PATH_MAX
 #define PATH_MAX 255
index a50a00bc129d3c413aac2f24232c233e49818be9..6f9d5059fe7e0e891af311400d6f576935c18b22 100644 (file)
@@ -11,4 +11,6 @@ region_patch(u64 progId, u8* code, u32 size)
     // Patch SMDH region checks
     patchMemory(code, size, regionFreePattern, sizeof(regionFreePattern), -16,
                 regionFreePatch, sizeof(regionFreePatch), 1);
+
+       logstr("region_patch\n");
 }
index c9985a204ec0858a511b7a66fd7a5f38fbaf02d0..76e598035e1a7fd1f0598f365279e06a39cc11c9 100644 (file)
@@ -23,4 +23,6 @@ ro_sigpatch(u64 progId, u8* code, u32 size)
 
     patchMemory(code, size, sha256ChecksPattern2, sizeof(sha256ChecksPattern2),
                 0, stub, sizeof(stub), 1);
+
+       logstr("ro_sigpatch\n");
 }
index c7bd706c87682a9052ed18c30589744ed8195b29..52b62a19780f6554ec0bce0f961c14cb0770f322 100644 (file)
@@ -11,4 +11,6 @@ secureinfo_sigpatch(u64 progId, u8* code, u32 size)
     patchMemory(code, size, secureinfoSigCheckPattern,
                 sizeof(secureinfoSigCheckPattern), 0, secureinfoSigCheckPatch,
                 sizeof(secureinfoSigCheckPatch), 1);
+
+       logstr("secureinfo_sigpatch\n");
 }
index ad97176398e224f4c5180c40a330870da2172e35..d41fa17434c3587a950d1091a14c25806bd4c0c7 100644 (file)
@@ -2,6 +2,8 @@
 #include "patcher.h"
 #include "fsldr.h"
 #include "internal.h"
+#include "memory.h"
+#include "logger.h"
 
 #ifndef PATH_MAX
 #define PATH_MAX 255
 
 #include "patch/patch.h"
 
-static int
-memcmp(const void* buf1, const void* buf2, u32 size)
-{
-    const u8* buf1c = (const u8*)buf1;
-    const u8* buf2c = (const u8*)buf2;
-
-    for (u32 i = 0; i < size; i++) {
-        int cmp = buf1c[i] - buf2c[i];
-        if (cmp)
-            return cmp;
-    }
-
-    return 0;
-}
-
-// Quick Search algorithm, adapted from
-// http://igm.univ-mlv.fr/~lecroq/string/node19.html#SECTION00190
-static u8*
-memfind(u8* startPos, u32 size, const void* pattern, u32 patternSize)
-{
-    const u8* patternc = (const u8*)pattern;
-
-    // Preprocessing
-    u32 table[256];
-
-    for (u32 i = 0; i < 256; ++i)
-        table[i] = patternSize + 1;
-    for (u32 i = 0; i < patternSize; ++i)
-        table[patternc[i]] = patternSize - i;
-
-    // Searching
-    u32 j = 0;
-
-    while (j <= size - patternSize) {
-        if (memcmp(patternc, startPos + j, patternSize) == 0)
-            return startPos + j;
-        j += table[startPos[j + patternSize]];
-    }
-
-    return NULL;
-}
-
-u32
-patchMemory(u8* start, u32 size, const void* pattern, u32 patSize, int offset,
-            const void* replace, u32 repSize, u32 count)
-{
-    u32 i;
-
-    for (i = 0; i < count; i++) {
-        u8* found = memfind(start, size, pattern, patSize);
-
-        if (found == NULL)
-            break;
-
-        // FIXME - This is throwing on Werror.
-        memcpy(found + offset, replace, repSize);
-
-        u32 at = (u32)(found - start);
-
-        if (at + patSize > size)
-            break;
-
-        size -= at + patSize;
-        start = found + patSize;
-    }
-
-    return i;
-}
-
-static inline size_t
-strnlen(const char* string, size_t maxlen)
-{
-    size_t size;
-
-    for (size = 0; *string && size < maxlen; string++, size++)
-        ;
-
-    return size;
-}
-
-static int
+int
 fileOpen(Handle* file, FS_ArchiveID id, const char* path, int flags)
 {
     FS_Path apath;
@@ -149,6 +71,8 @@ load_config()
 
     failed_load_config = 0;
 
+       logstr("loaded config file\n");
+
     return;
 }
 
@@ -210,6 +134,10 @@ static int loadTitleLocaleConfig(u64 progId, u8 *regionId, u8 *languageId)
                                break;
                        }
                }
+
+               logstr("langemu cfg applied\n");
+               logstr(path);
+               logstr("\n");
        }
        return ret;
 }
@@ -308,6 +236,8 @@ patchCfgGetLanguage(u8* code, u32 size, u8 languageId,
                             0xE3B00000; // (1 or 2 instructions)         => movs
                                         // r0, 0             (result code)
 
+                                               logstr("patched language\n");
+
                         // We're done
                         return;
                     }
@@ -342,6 +272,8 @@ patchCfgGetRegion(u8* code, u32 size, u8 regionId, u32 CFGUHandleOffset)
             break;
         }
     }
+
+       logstr("patched region\n");
 }
 
 static void
@@ -399,6 +331,8 @@ language_emu(u64 progId, u8* code, u32 size)
             }
         }
     }
+
+       logstr("set up langemu\n");
 }
 
 void
index 085dc7bb3a81bb0c82b8b9ace39f725fa09f02cc..6619e6fc515d3c96a63a6ae03e2c1ab808f39df9 100644 (file)
@@ -13,8 +13,7 @@ u32 get_data_extend(u64 progId, u32 size_orig);
 
 void load_config();
 
-u32 patchMemory(u8* start, u32 size, const void* pattern, u32 patSize,
-                int offset, const void* replace, u32 repSize, u32 count);
+int fileOpen(Handle* file, FS_ArchiveID id, const char* path, int flags);
 
 u8 get_cpumode(u64 progId);