mirror of
https://github.com/wiiu-env/PayloadLoaderInstaller.git
synced 2025-01-15 09:49:14 +01:00
WIP
This commit is contained in:
parent
8dabb403ca
commit
29e8b0b8c3
1
Makefile
1
Makefile
@ -20,6 +20,7 @@ include $(DEVKITPRO)/wut/share/wut_rules
|
||||
TARGET := $(notdir $(CURDIR))
|
||||
BUILD := build
|
||||
SOURCES := source \
|
||||
source/common \
|
||||
source/utils \
|
||||
source/fs
|
||||
DATA := data
|
||||
|
2
payload
2
payload
@ -1 +1 @@
|
||||
Subproject commit f0171236eaa5093ccd17894924841bbb2fc6c1e1
|
||||
Subproject commit c4c14496afc12b3f4f5ae6e9c335e379a212d1c2
|
@ -1,12 +1,11 @@
|
||||
#include "ApplicationState.h"
|
||||
#include "WiiUScreen.h"
|
||||
#include "ScreenUtils.h"
|
||||
#include "../build/safe_rpx.h"
|
||||
#include "../build/safe_payload.h"
|
||||
#include <sysapp/launch.h>
|
||||
#include <iosuhax.h>
|
||||
|
||||
extern "C" void OSForceFullRelaunch();
|
||||
extern "C" void OSShutdown();
|
||||
|
||||
void ApplicationState::render() {
|
||||
WiiUScreen::clearScreen();
|
||||
@ -36,22 +35,36 @@ void ApplicationState::render() {
|
||||
} else if (this->state == STATE_CHECK_PATCH_POSSIBLE) {
|
||||
WiiUScreen::drawLine("Check if console can be patched.");
|
||||
} else if (this->state == STATE_CHECK_PATCH_POSSIBLE_DONE) {
|
||||
WiiUScreen::drawLinef("Compatible title: %s", appInfo->appName);
|
||||
WiiUScreen::drawLinef("Compatible title:");
|
||||
WiiUScreen::drawLinef("%s", appInfo->appName);
|
||||
WiiUScreen::drawLine();
|
||||
if (this->fstPatchPossible) {
|
||||
|
||||
if (this->fstAlreadyPatched) {
|
||||
WiiUScreen::drawLine("[ X ] title.fst is already patched!");
|
||||
} else if (this->fstPatchPossible) {
|
||||
WiiUScreen::drawLine("[ X ] title.fst can be patched!");
|
||||
} else {
|
||||
WiiUScreen::drawLine("[ ] title.fst can NOT be patched!");
|
||||
}
|
||||
if (this->cosPatchPossible) {
|
||||
if (this->cosAlreadyPatched) {
|
||||
WiiUScreen::drawLine("[ X ] cos.xml is already patched!");
|
||||
} else if (this->cosPatchPossible) {
|
||||
WiiUScreen::drawLine("[ X ] cos.xml can be patched!");
|
||||
} else {
|
||||
WiiUScreen::drawLine("[ ] cos.xml can NOT be patched!");
|
||||
}
|
||||
if (this->systemXMLPatchPossible) {
|
||||
WiiUScreen::drawLine("[ X ] system.xml can be patched!");
|
||||
if (this->rpxAlreadyPatched) {
|
||||
WiiUScreen::drawLine("[ X ] safe.rpx is already patched!");
|
||||
} else {
|
||||
WiiUScreen::drawLine("[ ] system.xml can NOT be patched!");
|
||||
WiiUScreen::drawLine("[ X ] safe.rpx can to be patched!");
|
||||
}
|
||||
|
||||
WiiUScreen::drawLine();
|
||||
WiiUScreen::drawLinef("System is booting into: ");
|
||||
if (this->coldbootTitle == nullptr) {
|
||||
WiiUScreen::drawLinef("%ll016X (Unknown title)", this->coldbootTitleId);
|
||||
} else {
|
||||
WiiUScreen::drawLinef("%ll016X (%s)", this->coldbootTitle->tid, this->coldbootTitle->name);
|
||||
}
|
||||
|
||||
WiiUScreen::drawLine();
|
||||
@ -82,6 +95,17 @@ void ApplicationState::render() {
|
||||
} else if (this->selectedOption == 2) {
|
||||
WiiUScreen::drawLine(" Back Coldboot > No Coldboot");
|
||||
}
|
||||
} else if (this->state == STATE_INSTALL_NO_COLDBOOT_ALLOWED) {
|
||||
WiiUScreen::drawLine("Note: To install Aroma as coldboot you need to run this installer");
|
||||
WiiUScreen::drawLine("from an already running Aroma instance (and not the browser)");
|
||||
WiiUScreen::drawLine("After the installation has finished, reboot the console, open the");
|
||||
WiiUScreen::drawLine("Health & Safety app and run the Aroma installer.");
|
||||
WiiUScreen::drawLine();
|
||||
if (this->selectedOption == 0) {
|
||||
WiiUScreen::drawLine("> Back Install without Coldboot");
|
||||
} else if (this->selectedOption == 1) {
|
||||
WiiUScreen::drawLine("> Back > Install without Coldboot");
|
||||
}
|
||||
} else if (this->state == STATE_INSTALL_CONFIRM_DIALOG) {
|
||||
WiiUScreen::drawLine("Are you REALLY sure you want to install Aroma?");
|
||||
WiiUScreen::drawLine("Installing could permanently damage your console");
|
||||
@ -116,7 +140,7 @@ void ApplicationState::render() {
|
||||
} else if (this->state == STATE_INSTALL_SUCCESS) {
|
||||
WiiUScreen::drawLine("Aroma was successfully installed");
|
||||
WiiUScreen::drawLine();
|
||||
WiiUScreen::drawLine("Press A to reboot the console");
|
||||
WiiUScreen::drawLine("Press A to shutdown the console");
|
||||
}
|
||||
printFooter();
|
||||
WiiUScreen::flipBuffers();
|
||||
@ -166,6 +190,13 @@ void ApplicationState::update(Input *input) {
|
||||
}
|
||||
}
|
||||
} else if (this->state == STATE_INSTALL_CHOOSE_COLDBOOT) {
|
||||
|
||||
if (!InstallerService::isColdBootAllowed()) {
|
||||
this->installColdboot = false;
|
||||
this->state = STATE_INSTALL_NO_COLDBOOT_ALLOWED;
|
||||
return;
|
||||
}
|
||||
|
||||
proccessMenuNavigation(input, 3);
|
||||
if (entrySelected(input)) {
|
||||
if (this->selectedOption == 0) { // Back
|
||||
@ -179,6 +210,16 @@ void ApplicationState::update(Input *input) {
|
||||
this->selectedOption = 0;
|
||||
return;
|
||||
}
|
||||
} else if (this->state == STATE_INSTALL_NO_COLDBOOT_ALLOWED) {
|
||||
proccessMenuNavigation(input, 2);
|
||||
if (entrySelected(input)) {
|
||||
if (this->selectedOption == 0) {
|
||||
this->state = STATE_CHECK_PATCH_POSSIBLE_DONE;
|
||||
} else {
|
||||
this->state = STATE_INSTALL_CONFIRM_DIALOG;
|
||||
}
|
||||
this->selectedOption = 0;
|
||||
}
|
||||
} else if (this->state == STATE_INSTALL_CONFIRM_DIALOG) {
|
||||
proccessMenuNavigation(input, 2);
|
||||
if (entrySelected(input)) {
|
||||
@ -232,6 +273,9 @@ void ApplicationState::update(Input *input) {
|
||||
if (IOSUHAX_FSA_FlushVolume(fsaFd, "/vol/storage_mlc01") == 0) {
|
||||
DEBUG_FUNCTION_LINE("Flushed mlc");
|
||||
}
|
||||
if (IOSUHAX_FSA_FlushVolume(fsaFd, "/vol/system") == 0) {
|
||||
DEBUG_FUNCTION_LINE("Flushed slc");
|
||||
}
|
||||
IOSUHAX_FSA_Close(fsaFd);
|
||||
} else {
|
||||
DEBUG_FUNCTION_LINE("Failed to open fsa");
|
||||
@ -240,8 +284,7 @@ void ApplicationState::update(Input *input) {
|
||||
}
|
||||
} else if (this->state == STATE_INSTALL_SUCCESS) {
|
||||
if (entrySelected(input)) {
|
||||
OSForceFullRelaunch();
|
||||
SYSLaunchMenu();
|
||||
OSShutdown();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -260,8 +303,26 @@ void ApplicationState::checkPatchPossible() {
|
||||
DEBUG_FUNCTION_LINE("ERROR");
|
||||
return;
|
||||
}
|
||||
|
||||
this->coldbootTitleId = InstallerService::getColdbootTitleId("storage_slc_installer:/config");
|
||||
|
||||
this->coldbootTitle = nullptr;
|
||||
for (int i = 0; GameList[i].tid != 0; i++) {
|
||||
if (GameList[i].tid == this->coldbootTitleId) {
|
||||
this->coldbootTitle = &GameList[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG_FUNCTION_LINE("CHECK FST");
|
||||
|
||||
InstallerService::eResults result;
|
||||
|
||||
this->fstAlreadyPatched = ((result = InstallerService::checkFSTAlreadyValid(this->appInfo->path, this->appInfo->fstHash)) == InstallerService::SUCCESS);
|
||||
this->rpxAlreadyPatched = ((result = InstallerService::checkRPXAlreadyValid(this->appInfo->path, RPX_HASH)) == InstallerService::SUCCESS);
|
||||
this->cosAlreadyPatched = ((result = InstallerService::checkCOSAlreadyValid(this->appInfo->path, this->appInfo->cosHash)) == InstallerService::SUCCESS);
|
||||
this->tmdValid = ((result = InstallerService::checkTMDValid(this->appInfo->path, this->appInfo->tmdHash)) == InstallerService::SUCCESS);
|
||||
|
||||
this->fstPatchPossible = ((result = InstallerService::checkFST(this->appInfo->path, this->appInfo->fstHash)) == InstallerService::SUCCESS);
|
||||
if (result != InstallerService::SUCCESS) {
|
||||
DEBUG_FUNCTION_LINE("ERROR: %s", InstallerService::ErrorMessage(result).c_str());
|
||||
@ -281,7 +342,6 @@ void ApplicationState::checkPatchPossible() {
|
||||
void ApplicationState::getAppInformation() {
|
||||
DEBUG_FUNCTION_LINE("About to call getInstalledAppInformation");
|
||||
this->appInfo = InstallerService::getInstalledAppInformation();
|
||||
DEBUG_FUNCTION_LINE("back");
|
||||
if (!this->appInfo) {
|
||||
DEBUG_FUNCTION_LINE("ERROR =(");
|
||||
this->state = STATE_ERROR;
|
||||
|
@ -23,6 +23,7 @@ public:
|
||||
STATE_CHECK_PATCH_POSSIBLE,
|
||||
STATE_CHECK_PATCH_POSSIBLE_DONE,
|
||||
STATE_INSTALL_CHOOSE_COLDBOOT,
|
||||
STATE_INSTALL_NO_COLDBOOT_ALLOWED,
|
||||
STATE_INSTALL_CONFIRM_DIALOG,
|
||||
STATE_INSTALL_STARTED,
|
||||
STATE_INSTALL_FST,
|
||||
@ -70,4 +71,10 @@ private:
|
||||
|
||||
eGameState state;
|
||||
eErrorState error = ERROR_NONE;
|
||||
uint64_t coldbootTitleId;
|
||||
_gList_t *coldbootTitle;
|
||||
bool fstAlreadyPatched;
|
||||
bool rpxAlreadyPatched;
|
||||
bool cosAlreadyPatched;
|
||||
bool tmdValid;
|
||||
};
|
||||
|
@ -14,21 +14,6 @@
|
||||
#include <malloc.h>
|
||||
#include <sstream>
|
||||
|
||||
systemXMLInformation systemXMLHashInformation[] = {
|
||||
{WII_U_MENU_JAP, 0x0005001010040000L, "2645065A42D18D390C78543E3C4FE7E1D1957A63", "5E5C707E6DAF82393E93971BE98BE3B12204932A"},
|
||||
{WII_U_MENU_USA, 0x0005001010040100L, "124562D41A02C7112DDD5F9A8F0EE5DF97E23471", "DC0F9941E99C629625419F444B5A5B177A67309F"},
|
||||
{WII_U_MENU_EUR, 0x0005001010040200L, "F06041A4E5B3F899E748F1BAEB524DE058809F1D", "A0273C466DE15F33EC161BCD908B5BFE359FE6E0"},
|
||||
{HEALTH_SAFETY_JAP, 0x000500101004E000L, "066D672824128713F0A7D156142A68B998080148", "2849DE91560F6667FE7415F89FC916BE3A27DE75"},
|
||||
{HEALTH_SAFETY_USA, 0x000500101004E100L, "0EBCA1DFC0AB7A6A7FE8FB5EAF23179621B726A1", "83CF5B1CE0B64C51D15B1EFCAD659063790EB590"},
|
||||
{HEALTH_SAFETY_EUR, 0x000500101004E200L, "DE46EC3E9B823ABA6CB0638D0C4CDEEF9C793BDD", "ED59630448EC6946F3E51618DA3681EC3A84D391"}
|
||||
};
|
||||
|
||||
appInformation supportedApps[] = {
|
||||
{0x000500101004E000L, "Health and Safety Information [JPN]", false, {'\0'}, "9D34DDD91604D781FDB0727AC75021833304964C", "F6EBF7BC8AE3AF3BB8A42E0CF3FDA051278AEB03"},
|
||||
{0x000500101004E100L, "Health and Safety Information [USA]", false, {'\0'}, "045734666A36C7EF0258A740855886EBDB20D59B", "F6EBF7BC8AE3AF3BB8A42E0CF3FDA051278AEB03"},
|
||||
{0x000500101004E200L, "Health and Safety Information [EUR]", false, {'\0'}, "130A76F8B36B36D43B88BBC74393D9AFD9CFD2A4", "F6EBF7BC8AE3AF3BB8A42E0CF3FDA051278AEB03"},
|
||||
};
|
||||
|
||||
InstallerService::eResults InstallerService::checkCOS(const std::string &path, char *hash) {
|
||||
std::string cosFilePath = path + "/code/cos.xml";
|
||||
DEBUG_FUNCTION_LINE("Loading %s", cosFilePath.c_str());
|
||||
@ -61,8 +46,7 @@ InstallerService::eResults InstallerService::checkSystemXML(const std::string &p
|
||||
std::string inputFile = std::string(path + "/system.xml");
|
||||
|
||||
systemXMLInformation *data = nullptr;
|
||||
int arrayLength = (sizeof(systemXMLHashInformation) / sizeof(*systemXMLHashInformation));
|
||||
for (int i = 0; i < arrayLength; i++) {
|
||||
for (int i = 0; systemXMLHashInformation[i].titleId != 0; i++) {
|
||||
if (systemXMLHashInformation[i].titleId == titleId) {
|
||||
data = &systemXMLHashInformation[i];
|
||||
break;
|
||||
@ -76,7 +60,6 @@ InstallerService::eResults InstallerService::checkSystemXML(const std::string &p
|
||||
|
||||
DEBUG_FUNCTION_LINE("Setting coldboot to %016llX", data->titleId);
|
||||
|
||||
|
||||
pugi::xml_document doc;
|
||||
pugi::xml_parse_result resultSystem = doc.load_file(inputFile.c_str());
|
||||
|
||||
@ -89,13 +72,22 @@ InstallerService::eResults InstallerService::checkSystemXML(const std::string &p
|
||||
snprintf(tmp, 17, "%016llX", data->titleId);
|
||||
|
||||
doc.child("system").child("default_title_id").first_child().set_value(tmp);
|
||||
if (!doc.child("system").child("log").attribute("length")) {
|
||||
doc.child("system").child("log").append_attribute("length") = "0";
|
||||
}
|
||||
if (!doc.child("system").child("standby").attribute("length")) {
|
||||
doc.child("system").child("standby").append_attribute("length") = "0";
|
||||
}
|
||||
if (!doc.child("system").child("ramdisk").attribute("length")) {
|
||||
doc.child("system").child("ramdisk").append_attribute("length") = "0";
|
||||
}
|
||||
|
||||
std::stringstream ss;
|
||||
doc.save(ss, " ", pugi::format_default, pugi::encoding_utf8);
|
||||
|
||||
std::string newHash = Utils::calculateSHA1(ss.str().c_str(), ss.str().size());
|
||||
|
||||
if (std::string(data->hash) == newHash) {
|
||||
if (std::string(data->hash) == newHash || std::string(data->hash2) == newHash) {
|
||||
DEBUG_FUNCTION_LINE("Success! system.xml is compatible");
|
||||
return SUCCESS;
|
||||
} else {
|
||||
@ -163,9 +155,8 @@ std::optional<appInformation> InstallerService::getInstalledAppInformation() {
|
||||
DEBUG_FUNCTION_LINE("%d titles found on the WiiU", titleCount);
|
||||
bool success = false;
|
||||
|
||||
int arrayLength = (sizeof(supportedApps) / sizeof(*supportedApps));
|
||||
for (uint32_t i = 0; i < titleCount; ++i) {
|
||||
for (int j = 0; j < arrayLength; ++j) {
|
||||
for (int j = 0; supportedApps[j].titleId != 0; j++) {
|
||||
if (titleList[i].titleId == supportedApps[j].titleId) {
|
||||
DEBUG_FUNCTION_LINE("%s is on the Wii U (%s) %d", supportedApps[j].appName, titleList[i].path, sizeof(supportedApps[j].path));
|
||||
supportedApps[j].onTheWiiU = true;
|
||||
@ -175,11 +166,12 @@ std::optional<appInformation> InstallerService::getInstalledAppInformation() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(titleList);
|
||||
|
||||
if (success) {
|
||||
success = false;
|
||||
for (int j = 0; j < arrayLength; ++j) {
|
||||
for (int j = 0; supportedApps[j].titleId != 0; j++) {
|
||||
if (supportedApps[j].onTheWiiU) {
|
||||
std::string path(supportedApps[j].path);
|
||||
if (!StringTools::replace(path, "/vol/storage_mlc01", "storage_mlc_installer:")) {
|
||||
@ -440,7 +432,6 @@ InstallerService::eResults InstallerService::patchCOS(const std::string &path, c
|
||||
return COS_XML_HASH_MISMATCH;
|
||||
}
|
||||
|
||||
|
||||
InstallerService::eResults InstallerService::copyRPX(const std::string &path, const uint8_t *rpx_data, size_t size, const std::string &rpx_hash) {
|
||||
std::string rpxSourceFilePath = path + "/code/safe.rpx";
|
||||
std::string rpxBackupFilePath = path + "/code/sbac.rpx";
|
||||
@ -508,8 +499,7 @@ InstallerService::eResults InstallerService::patchSystemXML(const std::string &p
|
||||
}
|
||||
|
||||
systemXMLInformation *data = nullptr;
|
||||
int arrayLength = (sizeof(systemXMLHashInformation) / sizeof(*systemXMLHashInformation));
|
||||
for (int i = 0; i < arrayLength; i++) {
|
||||
for (int i = 0; systemXMLHashInformation[i].titleId != 0; i++) {
|
||||
if (systemXMLHashInformation[i].titleId == titleId) {
|
||||
data = &systemXMLHashInformation[i];
|
||||
break;
|
||||
@ -534,6 +524,15 @@ InstallerService::eResults InstallerService::patchSystemXML(const std::string &p
|
||||
snprintf(tmp, 17, "%016llX", data->titleId);
|
||||
|
||||
doc.child("system").child("default_title_id").first_child().set_value(tmp);
|
||||
if (!doc.child("system").child("log").attribute("length")) {
|
||||
doc.child("system").child("log").append_attribute("length") = "0";
|
||||
}
|
||||
if (!doc.child("system").child("standby").attribute("length")) {
|
||||
doc.child("system").child("standby").append_attribute("length") = "0";
|
||||
}
|
||||
if (!doc.child("system").child("ramdisk").attribute("length")) {
|
||||
doc.child("system").child("ramdisk").append_attribute("length") = "0";
|
||||
}
|
||||
doc.save_file(finalFile.c_str(), " ", pugi::format_default, pugi::encoding_utf8);
|
||||
|
||||
std::string newHash = Utils::hashFile(finalFile);
|
||||
@ -559,3 +558,63 @@ InstallerService::eResults InstallerService::patchSystemXML(const std::string &p
|
||||
|
||||
return SYSTEM_XML_HASH_MISMATCH;
|
||||
}
|
||||
|
||||
uint64_t InstallerService::getColdbootTitleId(const std::string &path) {
|
||||
std::string inputFile = std::string(path + "/system.xml");
|
||||
|
||||
pugi::xml_document doc;
|
||||
pugi::xml_parse_result resultSystem = doc.load_file(inputFile.c_str());
|
||||
|
||||
if (!resultSystem) {
|
||||
DEBUG_FUNCTION_LINE("Error while parsing %s: %s", inputFile.c_str(), resultSystem.description());
|
||||
return SYSTEM_XML_PARSING_FAILED;
|
||||
}
|
||||
|
||||
DEBUG_FUNCTION_LINE("%s", doc.child("system").child("default_title_id").first_child().value());
|
||||
|
||||
uint64_t result = strtoull(doc.child("system").child("default_title_id").first_child().value(), nullptr, 16);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
InstallerService::eResults InstallerService::checkFSTAlreadyValid(const std::string &path, const std::string &hash) {
|
||||
std::string filePath = path + "/code/title.fst";
|
||||
return checkFileHash(filePath, hash);
|
||||
}
|
||||
|
||||
InstallerService::eResults InstallerService::checkTMDValid(const std::string &path, const std::string &hash) {
|
||||
std::string filePath = path + "/code/title.fst";
|
||||
return checkFileHash(filePath, hash);
|
||||
}
|
||||
|
||||
InstallerService::eResults InstallerService::checkCOSAlreadyValid(const std::string &path, const std::string &hash) {
|
||||
std::string filePath = path + "/code/cos.xml";
|
||||
return checkFileHash(filePath, hash);
|
||||
}
|
||||
|
||||
InstallerService::eResults InstallerService::checkRPXAlreadyValid(const std::string &path, const std::string &hash) {
|
||||
std::string filePath = path + "/code/safe.rpx";
|
||||
return checkFileHash(filePath, hash);
|
||||
}
|
||||
|
||||
InstallerService::eResults InstallerService::checkFileHash(const std::string &filePath, const std::string &hash) {
|
||||
uint8_t *fileData = nullptr;
|
||||
uint32_t fileDataSize = 0;
|
||||
|
||||
if (FSUtils::LoadFileToMem(filePath.c_str(), &fileData, &fileDataSize) < 0) {
|
||||
return FAILED_TO_LOAD_FILE;
|
||||
}
|
||||
|
||||
std::string newHash = Utils::calculateSHA1((const char *) fileData, fileDataSize);
|
||||
|
||||
free(fileData);
|
||||
fileData = nullptr;
|
||||
|
||||
if (StringTools::strCompareIC(hash, newHash)) {
|
||||
return SUCCESS;
|
||||
} else {
|
||||
DEBUG_FUNCTION_LINE("expected %s actual %s", hash.c_str(), newHash.c_str());
|
||||
return FST_HASH_MISMATCH;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "utils/pugixml.hpp"
|
||||
#include "common/common.h"
|
||||
#include <optional>
|
||||
#include <coreinit/memorymap.h>
|
||||
|
||||
class InstallerService {
|
||||
public:
|
||||
@ -28,6 +29,20 @@ public:
|
||||
FAILED_TO_LOAD_FILE = -18,
|
||||
};
|
||||
|
||||
static bool isColdBootAllowed(){
|
||||
if (OSIsAddressValid(0x00FFFFF8)) {
|
||||
uint64_t bootedFrom = *((uint64_t *) 0x00FFFFF8);
|
||||
if (
|
||||
bootedFrom == 0x000500101004E000L || // H&S JAP
|
||||
bootedFrom == 0x000500101004E100L || // H&S USA
|
||||
bootedFrom == 0x000500101004E200L // H&S EUR
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static eResults patchCOS(const std::string &path, char *hash);
|
||||
|
||||
static eResults checkCOS(const std::string &path, char *hash);
|
||||
@ -39,17 +54,29 @@ public:
|
||||
static std::optional<appInformation> getInstalledAppInformation();
|
||||
|
||||
static std::string ErrorMessage(eResults error);
|
||||
|
||||
static std::string ErrorDescription(eResults error);
|
||||
|
||||
static eResults patchFST(const std::string &path, const char *hash);
|
||||
|
||||
static eResults copyRPX(const std::string &path, const uint8_t *rpx_data, size_t size, const std::string &rpx_hash);
|
||||
|
||||
|
||||
static eResults patchSystemXML(const std::string &path, uint64_t id);
|
||||
|
||||
static uint64_t getColdbootTitleId(const std::string &path);
|
||||
|
||||
static eResults checkFSTAlreadyValid(const std::string &path, const std::string &hash);
|
||||
|
||||
static eResults checkTMDValid(const std::string &path, const std::string &hash);
|
||||
|
||||
static eResults checkCOSAlreadyValid(const std::string &path, const std::string &hash);
|
||||
|
||||
static eResults checkRPXAlreadyValid(const std::string &path, const std::string &hash);
|
||||
|
||||
private:
|
||||
static eResults patchFSTData(uint8_t *fstData, uint32_t size);
|
||||
|
||||
static bool patchCOSXMLData(pugi::xml_document *doc);
|
||||
|
||||
static eResults checkFileHash(const std::string &filePath, const std::string &hash);
|
||||
};
|
117
source/common/common.cpp
Normal file
117
source/common/common.cpp
Normal file
@ -0,0 +1,117 @@
|
||||
#include "common.h"
|
||||
|
||||
systemXMLInformation systemXMLHashInformation[] = {
|
||||
{WII_U_MENU_JAP, 0x0005001010040000L, "2645065A42D18D390C78543E3C4FE7E1D1957A63", "5E5C707E6DAF82393E93971BE98BE3B12204932A"},
|
||||
{WII_U_MENU_USA, 0x0005001010040100L, "124562D41A02C7112DDD5F9A8F0EE5DF97E23471", "DC0F9941E99C629625419F444B5A5B177A67309F"},
|
||||
{WII_U_MENU_EUR, 0x0005001010040200L, "F06041A4E5B3F899E748F1BAEB524DE058809F1D", "A0273C466DE15F33EC161BCD908B5BFE359FE6E0"},
|
||||
{HEALTH_SAFETY_JPN, 0x000500101004E000L, "066D672824128713F0A7D156142A68B998080148", "2849DE91560F6667FE7415F89FC916BE3A27DE75"},
|
||||
{HEALTH_SAFETY_USA, 0x000500101004E100L, "0EBCA1DFC0AB7A6A7FE8FB5EAF23179621B726A1", "83CF5B1CE0B64C51D15B1EFCAD659063790EB590"},
|
||||
{HEALTH_SAFETY_EUR, 0x000500101004E200L, "DE46EC3E9B823ABA6CB0638D0C4CDEEF9C793BDD", "ED59630448EC6946F3E51618DA3681EC3A84D391"},
|
||||
{MAX_SYSTEM_XML_DEFAULT_TITLE_ID, 0, {'\0'}, {'\0'}},
|
||||
};
|
||||
|
||||
appInformation supportedApps[] = {
|
||||
{0x000500101004E000L, "Health and Safety Information [JPN]", false, {'\0'}, "9D34DDD91604D781FDB0727AC75021833304964C", "F6EBF7BC8AE3AF3BB8A42E0CF3FDA051278AEB03", "2CF358E1F51932D305911A6836ED37DB0F94ABE4"},
|
||||
{0x000500101004E100L, "Health and Safety Information [USA]", false, {'\0'}, "045734666A36C7EF0258A740855886EBDB20D59B", "F6EBF7BC8AE3AF3BB8A42E0CF3FDA051278AEB03", "C53C219FB8F777F9AB8F430D6BE4BC034D5638BA"},
|
||||
{0x000500101004E200L, "Health and Safety Information [PAL]", false, {'\0'}, "130A76F8B36B36D43B88BBC74393D9AFD9CFD2A4", "F6EBF7BC8AE3AF3BB8A42E0CF3FDA051278AEB03", "4A29A60E5FBDAF410B7C22ECAEBDDBF29D1A874E"},
|
||||
{0, nullptr, false, {'\0'}, {'\0'}, {'\0'}},
|
||||
};
|
||||
|
||||
gList_t GameList[] = {
|
||||
{0x0005001010040000L, "Wii U Menu [JPN]", MCP_REGION_JAPAN},
|
||||
{0x0005001010040100L, "Wii U Menu [USA]", MCP_REGION_USA},
|
||||
{0x0005001010040200L, "Wii U Menu [PAL]", MCP_REGION_EUROPE},
|
||||
|
||||
{0x000500101004E000L, "Health and Safety Information [JPN]", MCP_REGION_JAPAN},
|
||||
{0x000500101004E100L, "Health and Safety Information [USA]", MCP_REGION_USA},
|
||||
{0x000500101004E200L, "Health and Safety Information [PAL]", MCP_REGION_EUROPE},
|
||||
|
||||
{0x0005000010179A00L, "Kawashima: Motto Nou wo Kitaeru Otona no DS Training [JPN]", MCP_REGION_JAPAN},
|
||||
{0x0005000010179B00L, "Brain Age: Train Your Brain in Minutes a Day! [USA]", MCP_REGION_USA},
|
||||
{0x0005000010179C00L, "Dr. Kawashima's Brain Training [PAL]", MCP_REGION_EUROPE},
|
||||
|
||||
{0x0005000010179D00L, "Catch! Touch! Yoshi! [JPN]", MCP_REGION_JAPAN},
|
||||
{0x0005000010179E00L, "Yoshi Touch & Go [USA]", MCP_REGION_USA},
|
||||
{0x0005000010179F00L, "Yoshi Touch & Go [PAL]", MCP_REGION_EUROPE},
|
||||
|
||||
{0x0005000010195600L, "Mario Kart DS [JPN]", MCP_REGION_JAPAN},
|
||||
{0x0005000010195700L, "Mario Kart DS [USA]", MCP_REGION_USA},
|
||||
{0x0005000010195800L, "Mario Kart DS [PAL]", MCP_REGION_EUROPE},
|
||||
|
||||
{0x0005000010195900L, "New Super Mario Bros. [JPN]", MCP_REGION_JAPAN},
|
||||
{0x0005000010195A00L, "New Super Mario Bros. [USA]", MCP_REGION_USA},
|
||||
{0x0005000010195B00L, "New Super Mario Bros. [PAL]", MCP_REGION_EUROPE},
|
||||
|
||||
{0x0005000010198800L, "Yoshi's Island DS [JPN]", MCP_REGION_JAPAN},
|
||||
{0x0005000010198900L, "Yoshi's Island DS [USA]", MCP_REGION_USA},
|
||||
{0x0005000010198A00L, "Yoshi's Island DS [PAL]", MCP_REGION_EUROPE},
|
||||
|
||||
{0x0005000010198B00L, "Yawaraka Atama Juku [JPN]", MCP_REGION_JAPAN},
|
||||
{0x0005000010198C00L, "Big Brain Academy [USA]", MCP_REGION_USA},
|
||||
{0x0005000010198D00L, "Big Brain Academy [PAL]", MCP_REGION_EUROPE},
|
||||
|
||||
{0x00050000101A1E00L, "Sawaru: Made in Wario [JPN]", MCP_REGION_JAPAN},
|
||||
{0x00050000101A1F00L, "WarioWare: Touched! [USA]", MCP_REGION_USA},
|
||||
{0x00050000101A2000L, "WarioWare: Touched! [PAL]", MCP_REGION_EUROPE},
|
||||
|
||||
{0x00050000101A2100L, "Mario & Luigi RPG 2x2 [JPN]", MCP_REGION_JAPAN},
|
||||
{0x00050000101A2200L, "Mario & Luigi: Partners in Time [USA]", MCP_REGION_USA},
|
||||
{0x00050000101A2300L, "Mario & Luigi: Partners in Time [PAL]", MCP_REGION_EUROPE},
|
||||
|
||||
{0x00050000101A5200L, "Donkey Kong: Jungle Climber [JPN]", MCP_REGION_JAPAN},
|
||||
{0x00050000101A5300L, "DK: Jungle Climber [USA]", MCP_REGION_USA},
|
||||
{0x00050000101A5400L, "Donkey Kong: Jungle Climber [PAL]", MCP_REGION_EUROPE},
|
||||
|
||||
{0x00050000101A5500L, "Hoshi no Kirby: Sanjou! Dorocche Dan [JPN]", MCP_REGION_JAPAN},
|
||||
{0x00050000101A5600L, "Kirby: Squeak Squad [USA]", MCP_REGION_USA},
|
||||
{0x00050000101A5700L, "Kirby: Mouse Attack [PAL]", MCP_REGION_EUROPE},
|
||||
|
||||
{0x00050000101ABD00L, "Kaitou Wario the Seven [JPN]", MCP_REGION_JAPAN},
|
||||
{0x00050000101ABE00L, "Wario: Master of Disguise [USA]", MCP_REGION_USA},
|
||||
{0x00050000101ABF00L, "Wario: Master of Disguise [PAL]", MCP_REGION_EUROPE},
|
||||
|
||||
{0x00050000101AC000L, "Star Fox Command [JPN]", MCP_REGION_JAPAN},
|
||||
{0x00050000101AC100L, "Star Fox Command [USA]", MCP_REGION_USA},
|
||||
{0x00050000101AC200L, "Star Fox Command [PAL]", MCP_REGION_EUROPE},
|
||||
|
||||
{0x00050000101B8800L, "Touch! Kirby's Magic Paintbrush [JPN]", MCP_REGION_JAPAN},
|
||||
{0x00050000101B8900L, "Kirby: Canvas Curse [USA]", MCP_REGION_USA},
|
||||
{0x00050000101B8A00L, "Kirby: Power Paintbrush [PAL]", MCP_REGION_EUROPE},
|
||||
|
||||
{0x00050000101B8B00L, "Zelda no Densetsu: Daichi no Kiteki [JPN]", MCP_REGION_JAPAN},
|
||||
{0x00050000101B8C00L, "The Legend of Zelda: Spirit Tracks [USA]", MCP_REGION_USA},
|
||||
{0x00050000101B8D00L, "The Legend of Zelda: Spirit Tracks [PAL]", MCP_REGION_EUROPE},
|
||||
|
||||
{0x00050000101C3300L, "Super Mario 64 DS [JPN]", MCP_REGION_JAPAN},
|
||||
{0x00050000101C3400L, "Super Mario 64 DS [USA]", MCP_REGION_USA},
|
||||
{0x00050000101C3500L, "Super Mario 64 DS [PAL]", MCP_REGION_EUROPE},
|
||||
|
||||
{0x00050000101C3600L, "Zelda no Densetsu: Mugen no Sunadokei [JPN]", MCP_REGION_JAPAN},
|
||||
{0x00050000101C3700L, "The Legend of Zelda: Phantom Hourglass [USA]", MCP_REGION_USA},
|
||||
{0x00050000101C3800L, "The Legend of Zelda: Phantom Hourglass [PAL]", MCP_REGION_EUROPE},
|
||||
|
||||
{0x00050000101C8600L, "Atsumete! Kirby [JPN]", MCP_REGION_JAPAN},
|
||||
{0x00050000101C8700L, "Kirby Mass Attack [USA]", MCP_REGION_USA},
|
||||
{0x00050000101C8800L, "Kirby Mass Attack [PAL]", MCP_REGION_EUROPE},
|
||||
|
||||
{0x00050000101CC200L, "Pokemon Ranger [JPN]", MCP_REGION_JAPAN},
|
||||
{0x00050000101CC300L, "Pokemon Ranger [USA]", MCP_REGION_USA},
|
||||
{0x00050000101CC400L, "Pokemon Ranger [PAL]", MCP_REGION_EUROPE},
|
||||
|
||||
{0x00050000101D1F00L, "Oideyo Doubutsu no Mori [JPN]", MCP_REGION_JAPAN},
|
||||
{0x00050000101D2000L, "Animal Crossing: Wild World [USA]", MCP_REGION_USA},
|
||||
{0x00050000101D2100L, "Animal Crossing: Wild World [PAL]", MCP_REGION_EUROPE},
|
||||
|
||||
{0x00050000101E0C00L, "Pokemon Fushigi no Dungeon: Sora no Tankentai [JPN]", MCP_REGION_JAPAN},
|
||||
{0x00050000101E0D00L, "Pokemon Mystery Dungeon: Explorers of Sky [USA]", MCP_REGION_USA},
|
||||
{0x00050000101E0E00L, "Pokemon Mystery Dungeon: Explorers of Sky [PAL]", MCP_REGION_EUROPE},
|
||||
|
||||
{0x00050000101E0F00L, "Pokemon Ranger: Batonnage [JPN]", MCP_REGION_JAPAN},
|
||||
{0x00050000101E1000L, "Pokemon Ranger: Shadows of Almia [USA]", MCP_REGION_USA},
|
||||
{0x00050000101E1100L, "Pokemon Ranger: Shadows of Almia [PAL]", MCP_REGION_EUROPE},
|
||||
|
||||
{0x00050000101E6F00L, "Pokemon Ranger: Hikari no Kiseki [JPN]", MCP_REGION_JAPAN},
|
||||
{0x00050000101E7000L, "Pokemon Ranger: Guardian Signs [USA]", MCP_REGION_USA},
|
||||
{0x00050000101E7100L, "Pokemon Ranger: Guardian Signs [PAL]", MCP_REGION_EUROPE},
|
||||
{0, "", MCP_REGION_JAPAN},
|
||||
};
|
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <coreinit/mcp.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -14,7 +15,8 @@ enum SYSTEM_XML_DEFAULT_TITLE_ID {
|
||||
WII_U_MENU_JAP,
|
||||
HEALTH_SAFETY_EUR,
|
||||
HEALTH_SAFETY_USA,
|
||||
HEALTH_SAFETY_JAP
|
||||
HEALTH_SAFETY_JPN,
|
||||
MAX_SYSTEM_XML_DEFAULT_TITLE_ID
|
||||
};
|
||||
|
||||
typedef struct systemXMLInformation {
|
||||
@ -31,8 +33,19 @@ typedef struct compatApps {
|
||||
char path[255];
|
||||
char fstHash[41];
|
||||
char cosHash[41];
|
||||
char tmdHash[41];
|
||||
} appInformation;
|
||||
|
||||
typedef struct _gList_t {
|
||||
uint64_t tid;
|
||||
char name[64];
|
||||
MCPRegion region;
|
||||
} gList_t;
|
||||
|
||||
extern systemXMLInformation systemXMLHashInformation[];
|
||||
extern appInformation supportedApps[];
|
||||
extern _gList_t GameList[];
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -1,4 +1,3 @@
|
||||
#include <coreinit/time.h>
|
||||
#include <coreinit/debug.h>
|
||||
|
||||
#include <whb/proc.h>
|
||||
@ -12,15 +11,15 @@
|
||||
#include "WiiUScreen.h"
|
||||
#include "InstallerService.h"
|
||||
|
||||
#include "../build/safe_payload.h"
|
||||
#include "ApplicationState.h"
|
||||
#include "VPADInput.h"
|
||||
#include "../build/safe_payload.h"
|
||||
|
||||
constexpr bool strings_equal(char const *a, char const *b) {
|
||||
return std::string_view(a) == b;
|
||||
}
|
||||
|
||||
static_assert(strings_equal(RPX_HASH, "2df9282cadcbe3fa86848ade9c67cbff12b72426"), "Built with an untested safe.rpx! Remove this check if you really know what you're doing.");
|
||||
static_assert(strings_equal(RPX_HASH, "116cff322148216f38b1eaaf296d1cffc6a3a98f"), "Built with an untested root.rpx! Remove this check if you really know what you're doing.");
|
||||
|
||||
void initIOSUHax();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user