diff --git a/source/channel/channel_launcher.cpp b/source/channel/channel_launcher.cpp index f1c123ba..1c4a048f 100644 --- a/source/channel/channel_launcher.cpp +++ b/source/channel/channel_launcher.cpp @@ -11,18 +11,19 @@ #include "loader/fs.h" #include "loader/fst.h" #include "loader/utils.h" +#include "memory/mem2.hpp" #include "memory/memory.h" #include "unzip/lz77.h" #include "types.h" bool Identify_GenerateTik(signed_blob **outbuf, u32 *outlen) { - signed_blob *buffer = (signed_blob *)memalign(32, ALIGN32(STD_SIGNED_TIK_SIZE)); + signed_blob *buffer = (signed_blob*)MEM2_memalign(32, STD_SIGNED_TIK_SIZE); if(!buffer) return false; memset(buffer, 0, STD_SIGNED_TIK_SIZE); - sig_rsa2048 *signature = (sig_rsa2048 *)buffer; + sig_rsa2048 *signature = (sig_rsa2048*)buffer; signature->type = ES_SIG_RSA2048; tik *tik_data = (tik *)SIGNATURE_PAYLOAD(buffer); @@ -38,8 +39,9 @@ bool Identify_GenerateTik(signed_blob **outbuf, u32 *outlen) bool Identify(u64 titleid) { char filepath[ISFS_MAXPATH] ATTRIBUTE_ALIGN(32); + memset(filepath, 0, ISFS_MAXPATH); - gprintf("Reading TMD..."); + gprintf("Reading TMD for %08x %08x...", TITLE_UPPER(titleid), TITLE_LOWER(titleid)); sprintf(filepath, "/title/%08x/%08x/content/title.tmd", TITLE_UPPER(titleid), TITLE_LOWER(titleid)); u32 tmdSize; u8 *tmdBuffer = ISFS_GetFile(filepath, &tmdSize, -1); @@ -54,7 +56,7 @@ bool Identify(u64 titleid) signed_blob *tikBuffer = NULL; gprintf("Generating fake ticket..."); - if(!Identify_GenerateTik(&tikBuffer,&tikSize)) + if(!Identify_GenerateTik(&tikBuffer, &tikSize)) { gprintf("Failed!\n"); return false; @@ -62,8 +64,10 @@ bool Identify(u64 titleid) gprintf("Success!\n"); gprintf("Reading certs..."); + memset(filepath, 0, ISFS_MAXPATH); strcpy(filepath, "/sys/cert.sys"); - u32 certSize; + + u32 certSize = 0; u8 *certBuffer = ISFS_GetFile(filepath, &certSize, -1); if (certBuffer == NULL || certSize == 0) { @@ -75,8 +79,12 @@ bool Identify(u64 titleid) gprintf("Success!\n"); gprintf("ES_Identify\n"); - s32 ret = ES_Identify((signed_blob*)certBuffer, certSize, (signed_blob*)tmdBuffer, tmdSize, tikBuffer, tikSize, NULL); - if (ret < 0) + u32 keyId = 0; + DCFlushRange(tmdBuffer, tmdSize); + DCFlushRange(tikBuffer, tikSize); + DCFlushRange(certBuffer, certSize); + s32 ret = ES_Identify((signed_blob*)certBuffer, certSize, (signed_blob*)tmdBuffer, tmdSize, tikBuffer, tikSize, &keyId); + if(ret < 0) { switch(ret) { @@ -97,7 +105,7 @@ bool Identify(u64 titleid) break; } } - + gprintf("Key ID: %u\n", keyId); free(tmdBuffer); free(tikBuffer); free(certBuffer); diff --git a/source/channel/identify.c b/source/channel/identify.c index d9a668f0..65e99ff6 100644 --- a/source/channel/identify.c +++ b/source/channel/identify.c @@ -5,43 +5,80 @@ #include #include +#include "gecko/gecko.hpp" +#include "memory/memory.h" #include "identify.h" -const u8 isfs_permissions_old[] = { 0x42, 0x8B, 0xD0, 0x01, 0x25, 0x66 }; -const u8 isfs_permissions_patch[] = { 0x42, 0x8B, 0xE0, 0x01, 0x25, 0x66 }; - -static bool apply_patch(const u8 *old, u32 old_size, const u8 *patch, u32 patch_size) +static bool apply_patch(char *name, const u8 *old, u32 old_size, const u8 *patch, u32 patch_size, u32 patch_offset) { - u8 *ptr = (u8*)0x93A00000; - bool found = false; - u8 *location = NULL; - while((u32)ptr < 0x93B00000) + u8 *ptr = (u8*)0x93400000; + bool found = false; + u8 *location = NULL; + while((u32)ptr < (0x94000000 - patch_size)) { - if(!memcmp(ptr, old, old_size)) + if(memcmp(ptr, old, old_size) == 0) { - found = true; - location = ptr; - u8 *start = location; - u32 i; - for(i = 0; i < patch_size; i++) - { + found = true; + location = ptr + patch_offset; + u8 *start = location; + u32 i; + for(i = 0; i < patch_size; i++) + { *location = patch[i]; location++; } - DCFlushRange((u8 *)(((u32)start) >> 5 << 5), (patch_size >> 5 << 5) + 64); + DCFlushRange((u8 *)(((u32)start) >> 5 << 5), (patch_size >> 5 << 5) + 64); break; - } - ptr++; - } - return found; + } + ptr++; + } + if(found) + gprintf("apply_patch '%s': found at %08x\n", name, ptr); + else + gprintf("apply_patch '%s': not found\n", name); + return found; } +const u8 isfs_permissions_old[] = { 0x42, 0x8B, 0xD0, 0x01, 0x25, 0x66 }; +const u8 isfs_permissions_patch[] = { 0x42, 0x8B, 0xE0, 0x01, 0x25, 0x66 }; +static const u8 setuid_old[] = { 0xD1, 0x2A, 0x1C, 0x39 }; +static const u8 setuid_patch[] = { 0x46, 0xC0 }; +const u8 es_identify_old[] = { 0x28, 0x03, 0xD1, 0x23 }; +const u8 es_identify_patch[] = { 0x00, 0x00 }; +const u8 hash_old[] = { 0x20, 0x07, 0x23, 0xA2 }; +const u8 hash_patch[] = { 0x00 }; +const u8 new_hash_old[] = { 0x20, 0x07, 0x4B, 0x0B }; + bool Patch_ISFS_Permission(bool enable) { + /* Disable memory protection */ + write16(MEM_PROT, 0); + /* Do Patches */ + bool ret = false; if(enable) - return apply_patch(isfs_permissions_old, sizeof(isfs_permissions_old), - isfs_permissions_patch, sizeof(isfs_permissions_patch)); + { + gprintf("Enabling ISFS Patches...\n"); + ret = apply_patch("isfs_permissions", isfs_permissions_old, sizeof(isfs_permissions_old), isfs_permissions_patch, sizeof(isfs_permissions_patch), 0); + } else /* Just revert it */ - return apply_patch(isfs_permissions_patch, sizeof(isfs_permissions_patch), - isfs_permissions_old, sizeof(isfs_permissions_old)); + { + gprintf("Disabling ISFS Patches...\n"); + ret = apply_patch("isfs_permissions", isfs_permissions_patch, sizeof(isfs_permissions_patch), isfs_permissions_old, sizeof(isfs_permissions_old), 0); + } + /* Enable memory protection */ + write16(MEM_PROT, 1); + return ret; +} + +void Patch_Channel_Boot(void) +{ + /* Disable memory protection */ + write16(MEM_PROT, 0); + /* Do Patching */ + apply_patch("es_setuid", setuid_old, sizeof(setuid_old), setuid_patch, sizeof(setuid_patch), 0); + apply_patch("es_identify", es_identify_old, sizeof(es_identify_old), es_identify_patch, sizeof(es_identify_patch), 2); + apply_patch("hash_check", hash_old, sizeof(hash_old), hash_patch, sizeof(hash_patch), 1); + apply_patch("new_hash_check", new_hash_old, sizeof(new_hash_old), hash_patch, sizeof(hash_patch), 1); + /* Enable memory protection */ + write16(MEM_PROT, 1); } diff --git a/source/channel/identify.h b/source/channel/identify.h index 8ddc4e14..0c6e5644 100644 --- a/source/channel/identify.h +++ b/source/channel/identify.h @@ -7,6 +7,7 @@ extern "C" #define _PATCHER_H_ bool Patch_ISFS_Permission(bool enable); +void Patch_Channel_Boot(void); #endif diff --git a/source/channel/nand.cpp b/source/channel/nand.cpp index dac259c9..e32ebb8c 100644 --- a/source/channel/nand.cpp +++ b/source/channel/nand.cpp @@ -1053,38 +1053,24 @@ s32 Nand::Do_Region_Change(string id) void Nand::Enable_ISFS_Patches(void) { if(AHBRPOT_Patched()) - { - // Disable memory protection - write16(MEM_PROT, 0); - // Do patches - gprintf("Enabling ISFS Patches: %d\n", Patch_ISFS_Permission(true)); - // Enable memory protection - write16(MEM_PROT, 1); - } + Patch_ISFS_Permission(true); } void Nand::Disable_ISFS_Patches(void) { if(AHBRPOT_Patched()) - { - // Disable memory protection - write16(MEM_PROT, 0); - // Do patches - gprintf("Disabling ISFS Patches: %d\n", Patch_ISFS_Permission(false)); - // Enable memory protection - write16(MEM_PROT, 1); - } + Patch_ISFS_Permission(false); } void Nand::Init_ISFS() { - if(IOS_GetVersion() == 58) + gprintf("Init ISFS\n"); + ISFS_Initialize(); + if(IOS_GetType(IOS_GetVersion()) == IOS_TYPE_NORMAL_IOS) { Enable_ISFS_Patches(); AccessPatched = true; } - gprintf("Init ISFS\n"); - ISFS_Initialize(); } void Nand::DeInit_ISFS() diff --git a/source/menu/menu.hpp b/source/menu/menu.hpp index 8eeb9bae..b97b4e76 100644 --- a/source/menu/menu.hpp +++ b/source/menu/menu.hpp @@ -974,7 +974,7 @@ private: bool init_network; void _netInit(); bool _loadFile(u8 * &buffer, u32 &size, const char *path, const char *file); - int _loadIOS(u8 ios, int userIOS, string id); + int _loadIOS(u8 ios, int userIOS, string id, bool RealNAND_Channels = false); void _launch(dir_discHdr *hdr); void _launchGame(dir_discHdr *hdr, bool dvd); void _launchChannel(dir_discHdr *hdr); diff --git a/source/menu/menu_game.cpp b/source/menu/menu_game.cpp index 58b92252..b6d1192e 100644 --- a/source/menu/menu_game.cpp +++ b/source/menu/menu_game.cpp @@ -13,6 +13,7 @@ #include "channel/channel_launcher.h" #include "channel/channels.h" #include "channel/nand.hpp" +#include "channel/identify.h" #include "devicemounter/DeviceHandler.hpp" #include "devicemounter/sdhc.h" #include "devicemounter/usbstorage.h" @@ -943,10 +944,10 @@ void CMenu::_launchHomebrew(const char *filepath, vector arguments) BootHomebrew(); } -int CMenu::_loadIOS(u8 gameIOS, int userIOS, string id) +int CMenu::_loadIOS(u8 gameIOS, int userIOS, string id, bool RealNAND_Channels) { gprintf("Game ID# %s requested IOS %d. User selected %d\n", id.c_str(), gameIOS, userIOS); - if(neek2o()) + if(neek2o() || RealNAND_Channels) { if(!loadIOS(gameIOS, false)) { @@ -1098,7 +1099,7 @@ void CMenu::_launchChannel(dir_discHdr *hdr) gameIOS = ChannelHandle.GetRequestedIOS(gameTitle); if(NAND_Emu && !neek2o()) NandHandle.Disable_Emu(); - if(_loadIOS(gameIOS, userIOS, id) == LOAD_IOS_FAILED) + if(_loadIOS(gameIOS, userIOS, id, !NAND_Emu) == LOAD_IOS_FAILED) Sys_Exit(); if((CurrentIOS.Type == IOS_TYPE_D2X || neek2o()) && returnTo != 0) { @@ -1130,6 +1131,7 @@ void CMenu::_launchChannel(dir_discHdr *hdr) { setLanguage(language); ocarina_load_code(cheatFile, cheatSize); + Patch_Channel_Boot(); /* Patch for everything */ Identify(gameTitle); ExternalBooter_ChannelSetup(gameTitle); WiiFlow_ExternalBooter(videoMode, vipatch, countryPatch, patchVidMode, aspectRatio, 0, TYPE_CHANNEL);