mirror of
https://github.com/Fledge68/WiiFlow_Lite.git
synced 2024-11-23 19:59:16 +01:00
-use regular ios if booting channels from real nand
(fixes wiiu wii mode and maybe original nintendo channels)
This commit is contained in:
parent
11276dbcbb
commit
e564058569
@ -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);
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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()
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user