From: root Date: Thu, 19 May 2016 22:51:27 +0000 (-0400) Subject: Split out patches from patcher in loader X-Git-Tag: stable-1~61 X-Git-Url: https://chaos.moe/g/?a=commitdiff_plain;h=966459bc8b3ad252741d5f892bd5da4971d3cc29;p=corbenik%2Fcorbenik.git Split out patches from patcher in loader --- diff --git a/external/loader/Makefile b/external/loader/Makefile index decb4e0..3a19369 100644 --- a/external/loader/Makefile +++ b/external/loader/Makefile @@ -22,7 +22,7 @@ include $(DEVKITARM)/3ds_rules #--------------------------------------------------------------------------------- TARGET := loader BUILD := build -SOURCES := source +SOURCES := source source/patch DATA := data INCLUDES := include diff --git a/external/loader/source/exheader.h b/external/loader/source/exheader.h old mode 100755 new mode 100644 diff --git a/external/loader/source/patch/block_cart_update.c b/external/loader/source/patch/block_cart_update.c new file mode 100644 index 0000000..c5a2b0c --- /dev/null +++ b/external/loader/source/patch/block_cart_update.c @@ -0,0 +1,25 @@ +#include <3ds.h> +#include "../memory.h" +#include "../patcher.h" +#include "../ifile.h" + +#ifndef PATH_MAX +#define PATH_MAX 255 +#define _MAX_LFN 255 +#endif +#include "../config.h" +#include "../../../../source/patch_format.h" + +void disable_cart_updates(u64 progId, u8 *code, u32 size) { + static const u8 stopCartUpdatesPattern[] = {0x0C, 0x18, 0xE1, 0xD8}; + static const u8 stopCartUpdatesPatch[] = {0x0B, 0x18, 0x21, 0xC8}; + + //Disable updates from foreign carts (makes carts region-free) + patchMemory(code, size, + stopCartUpdatesPattern, + sizeof(stopCartUpdatesPattern), 0, + stopCartUpdatesPatch, + sizeof(stopCartUpdatesPatch), 2 + ); +} + diff --git a/external/loader/source/patch/block_eshop_update.c b/external/loader/source/patch/block_eshop_update.c new file mode 100644 index 0000000..94b1bbf --- /dev/null +++ b/external/loader/source/patch/block_eshop_update.c @@ -0,0 +1,25 @@ +#include <3ds.h> +#include "../memory.h" +#include "../patcher.h" +#include "../ifile.h" + +#ifndef PATH_MAX +#define PATH_MAX 255 +#define _MAX_LFN 255 +#endif +#include "../config.h" +#include "../../../../source/patch_format.h" + +void disable_eshop_updates(u64 progId, u8 *code, u32 size) { + static const u8 skipEshopUpdateCheckPattern[] = {0x30, 0xB5, 0xF1, 0xB0}; + static const u8 skipEshopUpdateCheckPatch[] = {0x00, 0x20, 0x08, 0x60, 0x70, 0x47}; + + //Skip update checks to access the EShop + patchMemory(code, size, + skipEshopUpdateCheckPattern, + sizeof(skipEshopUpdateCheckPattern), 0, + skipEshopUpdateCheckPatch, + sizeof(skipEshopUpdateCheckPatch), 1 + ); +} + diff --git a/external/loader/source/patch/block_nim_update.c b/external/loader/source/patch/block_nim_update.c new file mode 100644 index 0000000..8ce8a3e --- /dev/null +++ b/external/loader/source/patch/block_nim_update.c @@ -0,0 +1,25 @@ +#include <3ds.h> +#include "../memory.h" +#include "../patcher.h" +#include "../ifile.h" + +#ifndef PATH_MAX +#define PATH_MAX 255 +#define _MAX_LFN 255 +#endif +#include "../config.h" +#include "../../../../source/patch_format.h" + +void disable_nim_updates(u64 progId, u8 *code, u32 size) { + static const u8 blockAutoUpdatesPattern[] = {0x25, 0x79, 0x0B, 0x99}; + static const u8 blockAutoUpdatesPatch[] = {0xE3, 0xA0}; + + //Block silent auto-updates + patchMemory(code, size, + blockAutoUpdatesPattern, + sizeof(blockAutoUpdatesPattern), 0, + blockAutoUpdatesPatch, + sizeof(blockAutoUpdatesPatch), 1 + ); +} + diff --git a/external/loader/source/patch/friends_ver.c b/external/loader/source/patch/friends_ver.c new file mode 100644 index 0000000..6c67ebe --- /dev/null +++ b/external/loader/source/patch/friends_ver.c @@ -0,0 +1,25 @@ +#include <3ds.h> +#include "../memory.h" +#include "../patcher.h" +#include "../ifile.h" + +#ifndef PATH_MAX +#define PATH_MAX 255 +#define _MAX_LFN 255 +#endif +#include "../config.h" +#include "../../../../source/patch_format.h" + +void fake_friends_version(u64 progId, u8 *code, u32 size) { + static const u8 fpdVerPattern[] = {0xE0, 0x1E, 0xFF, 0x2F, 0xE1, 0x01, 0x01, 0x01}; + static const u8 fpdVerPatch = 0x06; // Latest version. + + //Allow online access to work with old friends modules + patchMemory(code, size, + fpdVerPattern, + sizeof(fpdVerPattern), 9, + &fpdVerPatch, + sizeof(fpdVerPatch), 1 + ); +} + diff --git a/external/loader/source/patch/mset_str.c b/external/loader/source/patch/mset_str.c new file mode 100644 index 0000000..f0b2880 --- /dev/null +++ b/external/loader/source/patch/mset_str.c @@ -0,0 +1,25 @@ +#include <3ds.h> +#include "../memory.h" +#include "../patcher.h" +#include "../ifile.h" + +#ifndef PATH_MAX +#define PATH_MAX 255 +#define _MAX_LFN 255 +#endif +#include "../config.h" +#include "../../../../source/patch_format.h" + +void settings_string(u64 progId, u8 *code, u32 size) { + static const u16 verPattern[] = u"Ver."; + static const u16 verPatch[] = u".hax"; + + //Patch Ver. string + patchMemory(code, size, + verPattern, + sizeof(verPattern) - sizeof(u16), 0, + verPatch, + sizeof(verPatch) - sizeof(u16), 1 + ); +} + diff --git a/external/loader/source/patch/patch.h b/external/loader/source/patch/patch.h new file mode 100644 index 0000000..1c4be64 --- /dev/null +++ b/external/loader/source/patch/patch.h @@ -0,0 +1,10 @@ +#pragma once + +void disable_cart_updates(u64 progId, u8 *code, u32 size); +void disable_eshop_updates(u64 progId, u8 *code, u32 size); +void disable_nim_updates(u64 progId, u8 *code, u32 size); +void fake_friends_version(u64 progId, u8 *code, u32 size); +void settings_string(u64 progId, u8 *code, u32 size); +void region_patch(u64 progId, u8 *code, u32 size); +void ro_sigpatch(u64 progId, u8 *code, u32 size); +void secureinfo_sigpatch(u64 progId, u8 *code, u32 size); diff --git a/external/loader/source/patch/regionfree.c b/external/loader/source/patch/regionfree.c new file mode 100644 index 0000000..823735e --- /dev/null +++ b/external/loader/source/patch/regionfree.c @@ -0,0 +1,24 @@ +#include <3ds.h> +#include "../memory.h" +#include "../patcher.h" +#include "../ifile.h" + +#ifndef PATH_MAX +#define PATH_MAX 255 +#define _MAX_LFN 255 +#endif +#include "../config.h" +#include "../../../../source/patch_format.h" + +void region_patch(u64 progId, u8 *code, u32 size) { + static const u8 regionFreePattern[] = {0x00, 0x00, 0x55, 0xE3, 0x01, 0x10, 0xA0, 0xE3}; + static const u8 regionFreePatch[] = {0x01, 0x00, 0xA0, 0xE3, 0x1E, 0xFF, 0x2F, 0xE1}; + + //Patch SMDH region checks + patchMemory(code, size, + regionFreePattern, + sizeof(regionFreePattern), -16, + regionFreePatch, + sizeof(regionFreePatch), 1 + ); +} diff --git a/external/loader/source/patch/ro_sigs.c b/external/loader/source/patch/ro_sigs.c new file mode 100644 index 0000000..0fb6cb2 --- /dev/null +++ b/external/loader/source/patch/ro_sigs.c @@ -0,0 +1,43 @@ +#include <3ds.h> +#include "../memory.h" +#include "../patcher.h" +#include "../ifile.h" + +#ifndef PATH_MAX +#define PATH_MAX 255 +#define _MAX_LFN 255 +#endif +#include "../config.h" +#include "../../../../source/patch_format.h" + +void ro_sigpatch(u64 progId, u8 *code, u32 size) { + static const u8 sigCheckPattern[] = {0x30, 0x40, 0x2D, 0xE9, 0x02, 0x50, 0xA0, 0xE1}; + static const u8 sha256ChecksPattern1[] = {0x30, 0x40, 0x2D, 0xE9, 0x24, 0xD0, 0x4D, 0xE2}; + static const u8 sha256ChecksPattern2[] = {0xF8, 0x4F, 0x2D, 0xE9, 0x01, 0x70, 0xA0, 0xE1}; + + // mov r0, #0; bx lr - equivalent to 'return 0;' + static const u8 stub[] = {0x00, 0x00, 0xA0, 0xE3, 0x1E, 0xFF, 0x2F, 0xE1}; + + //Disable CRR0 signature (RSA2048 with SHA256) check + patchMemory(code, size, + sigCheckPattern, + sizeof(sigCheckPattern), 0, + stub, + sizeof(stub), 1 + ); + + //Disable CRO0/CRR0 SHA256 hash checks (section hashes, and hash table) + patchMemory(code, size, + sha256ChecksPattern1, + sizeof(sha256ChecksPattern1), 0, + stub, + sizeof(stub), 1 + ); + + patchMemory(code, size, + sha256ChecksPattern2, + sizeof(sha256ChecksPattern2), 0, + stub, + sizeof(stub), 1 + ); +} diff --git a/external/loader/source/patch/secinfo_sigs.c b/external/loader/source/patch/secinfo_sigs.c new file mode 100644 index 0000000..3f2fcce --- /dev/null +++ b/external/loader/source/patch/secinfo_sigs.c @@ -0,0 +1,25 @@ +#include <3ds.h> +#include "../memory.h" +#include "../patcher.h" +#include "../ifile.h" + +#ifndef PATH_MAX +#define PATH_MAX 255 +#define _MAX_LFN 255 +#endif +#include "../config.h" +#include "../../../../source/patch_format.h" + +void secureinfo_sigpatch(u64 progId, u8 *code, u32 size) { + static const u8 secureinfoSigCheckPattern[] = {0x06, 0x46, 0x10, 0x48, 0xFC}; + static const u8 secureinfoSigCheckPatch[] = {0x00, 0x26}; + + //Disable SecureInfo signature check + patchMemory(code, size, + secureinfoSigCheckPattern, + sizeof(secureinfoSigCheckPattern), 0, + secureinfoSigCheckPatch, + sizeof(secureinfoSigCheckPatch), 1 + ); +} + diff --git a/external/loader/source/patcher.c b/external/loader/source/patcher.c index d679401..27ba299 100644 --- a/external/loader/source/patcher.c +++ b/external/loader/source/patcher.c @@ -10,6 +10,8 @@ #include "config.h" #include "../../../source/patch_format.h" +#include "patch/patch.h" + static int memcmp(const void *buf1, const void *buf2, u32 size) { const u8 *buf1c = (const u8 *)buf1; @@ -50,7 +52,7 @@ static u8 *memsearch(u8 *startPos, const void *pattern, u32 size, u32 patternSiz return NULL; } -static u32 patchMemory(u8 *start, u32 size, const void *pattern, u32 patSize, int offset, const void *replace, u32 repSize, u32 count) +u32 patchMemory(u8 *start, u32 size, const void *pattern, u32 patSize, int offset, const void *replace, u32 repSize, u32 count) { u32 i; @@ -159,28 +161,22 @@ void load_config() { static int loadTitleLocaleConfig(u64 progId, u8 *regionId, u8 *languageId) { // FIXME - Rewrite this function to use a single line-based config + // Directory seeks have severe issues on FAT and // dumping configs based on 3dsdb (more than 1000) causes things - // to kind a choke. - - /* Here we look for "/corbenik/locale/[u64 titleID in hex, uppercase].txt" - If it exists it should contain, for example, "EUR IT" */ + // to kinda choke. FAT is not meant for large numbers of files per + // directory due to linear seeks rather than tree or hash-based indexes - char path[] = "/corbenik/locales/0000000000000000.txt"; + char path[] = "/corbenik/etc/locale.conf"; // The locale config file. - u32 i = 0, j = 0; - while(path[j] != 0) { - if (path[j] == '/') - i = j; - j++; - } - i += 1; + char progIdStr[17]; // Sizeof titleid as string + null terminator + progIdStr[sizeof(progIdStr)-1] = 0; // Set null term - while(progId > 0) - { + // Hexdump progId + for(int i=0; i < 8; i++) { static const char hexDigits[] = "0123456789ABCDEF"; - path[i--] = hexDigits[(u32)(progId & 0xF)]; - progId >>= 4; + progIdStr[i*2] = hexDigits[(((uint8_t*)progId)[i] >> 4) & 0xf]; + progIdStr[i*2+1] = hexDigits[ ((uint8_t*)progId)[i] & 0xf]; } IFile file; @@ -190,11 +186,19 @@ static int loadTitleLocaleConfig(u64 progId, u8 *regionId, u8 *languageId) char buf[6]; u64 total; + // TODO - Open and seek file properly + ret = IFile_Read(&file, &total, buf, 6); IFile_Close(&file); if(!R_SUCCEEDED(ret) || total < 6) return -1; + // TODO - Split by nl/spaces strtok style. This is not acceptable code. + // Entries should be of the format: + // + // No attempt will be made to fix dumbass use of CRLF or CR-only, but newline + // characters should be treated as spaces. + for(u32 i = 0; i < 7; ++i) { // TODO - Permit alternative names. They're using fixed strings for ease of use; @@ -336,84 +340,6 @@ static void patchCfgGetRegion(u8 *code, u32 size, u8 regionId, u32 CFGUHandleOff } } -static void region_patch(u64 progId, u8 *code, u32 size) { - static const u8 regionFreePattern[] = {0x00, 0x00, 0x55, 0xE3, 0x01, 0x10, 0xA0, 0xE3}; - static const u8 regionFreePatch[] = {0x01, 0x00, 0xA0, 0xE3, 0x1E, 0xFF, 0x2F, 0xE1}; - - //Patch SMDH region checks - patchMemory(code, size, - regionFreePattern, - sizeof(regionFreePattern), -16, - regionFreePatch, - sizeof(regionFreePatch), 1 - ); -} - -static void disable_nim_updates(u64 progId, u8 *code, u32 size) { - static const u8 blockAutoUpdatesPattern[] = {0x25, 0x79, 0x0B, 0x99}; - static const u8 blockAutoUpdatesPatch[] = {0xE3, 0xA0}; - - //Block silent auto-updates - patchMemory(code, size, - blockAutoUpdatesPattern, - sizeof(blockAutoUpdatesPattern), 0, - blockAutoUpdatesPatch, - sizeof(blockAutoUpdatesPatch), 1 - ); -} - -static void disable_eshop_updates(u64 progId, u8 *code, u32 size) { - static const u8 skipEshopUpdateCheckPattern[] = {0x30, 0xB5, 0xF1, 0xB0}; - static const u8 skipEshopUpdateCheckPatch[] = {0x00, 0x20, 0x08, 0x60, 0x70, 0x47}; - - //Skip update checks to access the EShop - patchMemory(code, size, - skipEshopUpdateCheckPattern, - sizeof(skipEshopUpdateCheckPattern), 0, - skipEshopUpdateCheckPatch, - sizeof(skipEshopUpdateCheckPatch), 1 - ); -} - -static void fake_friends_version(u64 progId, u8 *code, u32 size) { - static const u8 fpdVerPattern[] = {0xE0, 0x1E, 0xFF, 0x2F, 0xE1, 0x01, 0x01, 0x01}; - static const u8 fpdVerPatch = 0x06; // Latest version. - - //Allow online access to work with old friends modules - patchMemory(code, size, - fpdVerPattern, - sizeof(fpdVerPattern), 9, - &fpdVerPatch, - sizeof(fpdVerPatch), 1 - ); -} - -static void settings_string(u64 progId, u8 *code, u32 size) { - static const u16 verPattern[] = u"Ver."; - static const u16 verPatch[] = u".hax"; - - //Patch Ver. string - patchMemory(code, size, - verPattern, - sizeof(verPattern) - sizeof(u16), 0, - verPatch, - sizeof(verPatch) - sizeof(u16), 1 - ); -} - -static void disable_cart_updates(u64 progId, u8 *code, u32 size) { - static const u8 stopCartUpdatesPattern[] = {0x0C, 0x18, 0xE1, 0xD8}; - static const u8 stopCartUpdatesPatch[] = {0x0B, 0x18, 0x21, 0xC8}; - - //Disable updates from foreign carts (makes carts region-free) - patchMemory(code, size, - stopCartUpdatesPattern, - sizeof(stopCartUpdatesPattern), 0, - stopCartUpdatesPatch, - sizeof(stopCartUpdatesPatch), 2 - ); -} - static void adjust_cpu_settings(u64 progId, u8 *code, u32 size) { if (!failed_load_config) { u32 cpuSetting = 0; @@ -436,51 +362,6 @@ static void adjust_cpu_settings(u64 progId, u8 *code, u32 size) { } } -static void secureinfo_sigpatch(u64 progId, u8 *code, u32 size) { - static const u8 secureinfoSigCheckPattern[] = {0x06, 0x46, 0x10, 0x48, 0xFC}; - static const u8 secureinfoSigCheckPatch[] = {0x00, 0x26}; - - //Disable SecureInfo signature check - patchMemory(code, size, - secureinfoSigCheckPattern, - sizeof(secureinfoSigCheckPattern), 0, - secureinfoSigCheckPatch, - sizeof(secureinfoSigCheckPatch), 1 - ); -} - -static void ro_sigpatch(u64 progId, u8 *code, u32 size) { - static const u8 sigCheckPattern[] = {0x30, 0x40, 0x2D, 0xE9, 0x02, 0x50, 0xA0, 0xE1}; - static const u8 sha256ChecksPattern1[] = {0x30, 0x40, 0x2D, 0xE9, 0x24, 0xD0, 0x4D, 0xE2}; - static const u8 sha256ChecksPattern2[] = {0xF8, 0x4F, 0x2D, 0xE9, 0x01, 0x70, 0xA0, 0xE1}; - - // mov r0, #0; bx lr - equivalent to 'return 0;' - static const u8 stub[] = {0x00, 0x00, 0xA0, 0xE3, 0x1E, 0xFF, 0x2F, 0xE1}; - - //Disable CRR0 signature (RSA2048 with SHA256) check - patchMemory(code, size, - sigCheckPattern, - sizeof(sigCheckPattern), 0, - stub, - sizeof(stub), 1 - ); - - //Disable CRO0/CRR0 SHA256 hash checks (section hashes, and hash table) - patchMemory(code, size, - sha256ChecksPattern1, - sizeof(sha256ChecksPattern1), 0, - stub, - sizeof(stub), 1 - ); - - patchMemory(code, size, - sha256ChecksPattern2, - sizeof(sha256ChecksPattern2), 0, - stub, - sizeof(stub), 1 - ); -} - void language_emu(u64 progId, u8 *code, u32 size) { if(!failed_load_config && config.options[OPTION_LOADER_LANGEMU]) { u32 tidHigh = (progId & 0xFFFFFFF000000000LL) >> 0x24; diff --git a/external/loader/source/patcher.h b/external/loader/source/patcher.h index 710b8fc..ad83c8d 100644 --- a/external/loader/source/patcher.h +++ b/external/loader/source/patcher.h @@ -11,3 +11,5 @@ u32 get_ro_extend(u64 progId, u32 size_orig); 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); diff --git a/source/patcher.c b/source/patcher.c index 0e1758a..d4e3c23 100644 --- a/source/patcher.c +++ b/source/patcher.c @@ -37,10 +37,10 @@ extern int doing_autoboot; void wait() { if (config.options[OPTION_TRACE] && !doing_autoboot) { - fprintf(stderr, " [WAIT]"); + fprintf(stderr, " [WAIT]"); wait_key(); } - fprintf(stderr, "\r \r"); + fprintf(stderr, "\r \r"); } int patch_firm_all() {