-use regular ios if booting channels from real nand

(fixes wiiu wii mode and maybe original nintendo channels)
This commit is contained in:
fix94.1 2012-12-08 21:16:05 +00:00
parent 11276dbcbb
commit e564058569
6 changed files with 89 additions and 55 deletions

View File

@ -11,18 +11,19 @@
#include "loader/fs.h" #include "loader/fs.h"
#include "loader/fst.h" #include "loader/fst.h"
#include "loader/utils.h" #include "loader/utils.h"
#include "memory/mem2.hpp"
#include "memory/memory.h" #include "memory/memory.h"
#include "unzip/lz77.h" #include "unzip/lz77.h"
#include "types.h" #include "types.h"
bool Identify_GenerateTik(signed_blob **outbuf, u32 *outlen) 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) if(!buffer)
return false; return false;
memset(buffer, 0, STD_SIGNED_TIK_SIZE); memset(buffer, 0, STD_SIGNED_TIK_SIZE);
sig_rsa2048 *signature = (sig_rsa2048 *)buffer; sig_rsa2048 *signature = (sig_rsa2048*)buffer;
signature->type = ES_SIG_RSA2048; signature->type = ES_SIG_RSA2048;
tik *tik_data = (tik *)SIGNATURE_PAYLOAD(buffer); tik *tik_data = (tik *)SIGNATURE_PAYLOAD(buffer);
@ -38,8 +39,9 @@ bool Identify_GenerateTik(signed_blob **outbuf, u32 *outlen)
bool Identify(u64 titleid) bool Identify(u64 titleid)
{ {
char filepath[ISFS_MAXPATH] ATTRIBUTE_ALIGN(32); 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)); sprintf(filepath, "/title/%08x/%08x/content/title.tmd", TITLE_UPPER(titleid), TITLE_LOWER(titleid));
u32 tmdSize; u32 tmdSize;
u8 *tmdBuffer = ISFS_GetFile(filepath, &tmdSize, -1); u8 *tmdBuffer = ISFS_GetFile(filepath, &tmdSize, -1);
@ -54,7 +56,7 @@ bool Identify(u64 titleid)
signed_blob *tikBuffer = NULL; signed_blob *tikBuffer = NULL;
gprintf("Generating fake ticket..."); gprintf("Generating fake ticket...");
if(!Identify_GenerateTik(&tikBuffer,&tikSize)) if(!Identify_GenerateTik(&tikBuffer, &tikSize))
{ {
gprintf("Failed!\n"); gprintf("Failed!\n");
return false; return false;
@ -62,8 +64,10 @@ bool Identify(u64 titleid)
gprintf("Success!\n"); gprintf("Success!\n");
gprintf("Reading certs..."); gprintf("Reading certs...");
memset(filepath, 0, ISFS_MAXPATH);
strcpy(filepath, "/sys/cert.sys"); strcpy(filepath, "/sys/cert.sys");
u32 certSize;
u32 certSize = 0;
u8 *certBuffer = ISFS_GetFile(filepath, &certSize, -1); u8 *certBuffer = ISFS_GetFile(filepath, &certSize, -1);
if (certBuffer == NULL || certSize == 0) if (certBuffer == NULL || certSize == 0)
{ {
@ -75,8 +79,12 @@ bool Identify(u64 titleid)
gprintf("Success!\n"); gprintf("Success!\n");
gprintf("ES_Identify\n"); gprintf("ES_Identify\n");
s32 ret = ES_Identify((signed_blob*)certBuffer, certSize, (signed_blob*)tmdBuffer, tmdSize, tikBuffer, tikSize, NULL); u32 keyId = 0;
if (ret < 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) switch(ret)
{ {
@ -97,7 +105,7 @@ bool Identify(u64 titleid)
break; break;
} }
} }
gprintf("Key ID: %u\n", keyId);
free(tmdBuffer); free(tmdBuffer);
free(tikBuffer); free(tikBuffer);
free(certBuffer); free(certBuffer);

View File

@ -5,43 +5,80 @@
#include <ogc/machine/processor.h> #include <ogc/machine/processor.h>
#include <string.h> #include <string.h>
#include "gecko/gecko.hpp"
#include "memory/memory.h"
#include "identify.h" #include "identify.h"
const u8 isfs_permissions_old[] = { 0x42, 0x8B, 0xD0, 0x01, 0x25, 0x66 }; static bool apply_patch(char *name, const u8 *old, u32 old_size, const u8 *patch, u32 patch_size, u32 patch_offset)
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)
{ {
u8 *ptr = (u8*)0x93A00000; u8 *ptr = (u8*)0x93400000;
bool found = false; bool found = false;
u8 *location = NULL; u8 *location = NULL;
while((u32)ptr < 0x93B00000) while((u32)ptr < (0x94000000 - patch_size))
{ {
if(!memcmp(ptr, old, old_size)) if(memcmp(ptr, old, old_size) == 0)
{ {
found = true; found = true;
location = ptr; location = ptr + patch_offset;
u8 *start = location; u8 *start = location;
u32 i; u32 i;
for(i = 0; i < patch_size; i++) for(i = 0; i < patch_size; i++)
{ {
*location = patch[i]; *location = patch[i];
location++; location++;
} }
DCFlushRange((u8 *)(((u32)start) >> 5 << 5), (patch_size >> 5 << 5) + 64); DCFlushRange((u8 *)(((u32)start) >> 5 << 5), (patch_size >> 5 << 5) + 64);
break; break;
} }
ptr++; ptr++;
} }
return found; 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) bool Patch_ISFS_Permission(bool enable)
{ {
/* Disable memory protection */
write16(MEM_PROT, 0);
/* Do Patches */
bool ret = false;
if(enable) 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 */ 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);
} }

View File

@ -7,6 +7,7 @@ extern "C"
#define _PATCHER_H_ #define _PATCHER_H_
bool Patch_ISFS_Permission(bool enable); bool Patch_ISFS_Permission(bool enable);
void Patch_Channel_Boot(void);
#endif #endif

View File

@ -1053,38 +1053,24 @@ s32 Nand::Do_Region_Change(string id)
void Nand::Enable_ISFS_Patches(void) void Nand::Enable_ISFS_Patches(void)
{ {
if(AHBRPOT_Patched()) if(AHBRPOT_Patched())
{ Patch_ISFS_Permission(true);
// 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);
}
} }
void Nand::Disable_ISFS_Patches(void) void Nand::Disable_ISFS_Patches(void)
{ {
if(AHBRPOT_Patched()) if(AHBRPOT_Patched())
{ Patch_ISFS_Permission(false);
// 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);
}
} }
void Nand::Init_ISFS() 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(); Enable_ISFS_Patches();
AccessPatched = true; AccessPatched = true;
} }
gprintf("Init ISFS\n");
ISFS_Initialize();
} }
void Nand::DeInit_ISFS() void Nand::DeInit_ISFS()

View File

@ -974,7 +974,7 @@ private:
bool init_network; bool init_network;
void _netInit(); void _netInit();
bool _loadFile(u8 * &buffer, u32 &size, const char *path, const char *file); 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 _launch(dir_discHdr *hdr);
void _launchGame(dir_discHdr *hdr, bool dvd); void _launchGame(dir_discHdr *hdr, bool dvd);
void _launchChannel(dir_discHdr *hdr); void _launchChannel(dir_discHdr *hdr);

View File

@ -13,6 +13,7 @@
#include "channel/channel_launcher.h" #include "channel/channel_launcher.h"
#include "channel/channels.h" #include "channel/channels.h"
#include "channel/nand.hpp" #include "channel/nand.hpp"
#include "channel/identify.h"
#include "devicemounter/DeviceHandler.hpp" #include "devicemounter/DeviceHandler.hpp"
#include "devicemounter/sdhc.h" #include "devicemounter/sdhc.h"
#include "devicemounter/usbstorage.h" #include "devicemounter/usbstorage.h"
@ -943,10 +944,10 @@ void CMenu::_launchHomebrew(const char *filepath, vector<string> arguments)
BootHomebrew(); 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); 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)) if(!loadIOS(gameIOS, false))
{ {
@ -1098,7 +1099,7 @@ void CMenu::_launchChannel(dir_discHdr *hdr)
gameIOS = ChannelHandle.GetRequestedIOS(gameTitle); gameIOS = ChannelHandle.GetRequestedIOS(gameTitle);
if(NAND_Emu && !neek2o()) if(NAND_Emu && !neek2o())
NandHandle.Disable_Emu(); NandHandle.Disable_Emu();
if(_loadIOS(gameIOS, userIOS, id) == LOAD_IOS_FAILED) if(_loadIOS(gameIOS, userIOS, id, !NAND_Emu) == LOAD_IOS_FAILED)
Sys_Exit(); Sys_Exit();
if((CurrentIOS.Type == IOS_TYPE_D2X || neek2o()) && returnTo != 0) if((CurrentIOS.Type == IOS_TYPE_D2X || neek2o()) && returnTo != 0)
{ {
@ -1130,6 +1131,7 @@ void CMenu::_launchChannel(dir_discHdr *hdr)
{ {
setLanguage(language); setLanguage(language);
ocarina_load_code(cheatFile, cheatSize); ocarina_load_code(cheatFile, cheatSize);
Patch_Channel_Boot(); /* Patch for everything */
Identify(gameTitle); Identify(gameTitle);
ExternalBooter_ChannelSetup(gameTitle); ExternalBooter_ChannelSetup(gameTitle);
WiiFlow_ExternalBooter(videoMode, vipatch, countryPatch, patchVidMode, aspectRatio, 0, TYPE_CHANNEL); WiiFlow_ExternalBooter(videoMode, vipatch, countryPatch, patchVidMode, aspectRatio, 0, TYPE_CHANNEL);