mirror of
https://github.com/wiiu-env/PayloadLoaderInstaller.git
synced 2024-11-14 22:25:05 +01:00
WIP
This commit is contained in:
parent
170a5a1860
commit
d688565491
@ -1,7 +1,12 @@
|
||||
#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();
|
||||
|
||||
void ApplicationState::render() {
|
||||
WiiUScreen::clearScreen();
|
||||
@ -108,6 +113,10 @@ void ApplicationState::render() {
|
||||
WiiUScreen::drawLine("... patching system.xml");
|
||||
} else if (this->state == STATE_INSTALL_RPX) {
|
||||
WiiUScreen::drawLine("... install safe.rpx");
|
||||
} else if (this->state == STATE_INSTALL_SUCCESS) {
|
||||
WiiUScreen::drawLine("Aroma was successfully installed");
|
||||
WiiUScreen::drawLine();
|
||||
WiiUScreen::drawLine("Press A to reboot the console");
|
||||
}
|
||||
printFooter();
|
||||
WiiUScreen::flipBuffers();
|
||||
@ -115,6 +124,7 @@ void ApplicationState::render() {
|
||||
|
||||
void ApplicationState::update(Input *input) {
|
||||
if (this->state == STATE_ERROR) {
|
||||
OSEnableHomeButtonMenu(true);
|
||||
if (entrySelected(input)) {
|
||||
SYSLaunchMenu();
|
||||
}
|
||||
@ -186,24 +196,52 @@ void ApplicationState::update(Input *input) {
|
||||
} else if (this->state == STATE_INSTALL_FST) {
|
||||
auto result = InstallerService::patchFST(this->appInfo->path, this->appInfo->fstHash);
|
||||
if (result != InstallerService::SUCCESS) {
|
||||
this->error = ERROR_INSTALLER_ERROR;
|
||||
setError(ERROR_INSTALLER_ERROR);
|
||||
this->installerError = result;
|
||||
this->state = STATE_ERROR;
|
||||
} else {
|
||||
this->state = STATE_INSTALL_COS;
|
||||
}
|
||||
} else if (this->state == STATE_INSTALL_COS) {
|
||||
auto result = InstallerService::patchCOS(this->appInfo->path, this->appInfo->cosHash);
|
||||
if (result != InstallerService::SUCCESS) {
|
||||
this->error = ERROR_INSTALLER_ERROR;
|
||||
setError(ERROR_INSTALLER_ERROR);
|
||||
this->installerError = result;
|
||||
this->state = STATE_ERROR;
|
||||
} else {
|
||||
this->state = STATE_INSTALL_RPX;
|
||||
}
|
||||
} else if (this->state == STATE_INSTALL_RPX) {
|
||||
auto result = InstallerService::copyRPX(this->appInfo->path, safe_rpx, safe_rpx_size, RPX_HASH);
|
||||
if (result != InstallerService::SUCCESS) {
|
||||
setError(ERROR_INSTALLER_ERROR);
|
||||
this->installerError = result;
|
||||
} else {
|
||||
if (this->installColdboot) {
|
||||
this->state = STATE_INSTALL_SYSTEM_XML;
|
||||
} else {
|
||||
this->state = STATE_INSTALL_SUCCESS;
|
||||
}
|
||||
}
|
||||
} else if (this->state == STATE_INSTALL_SYSTEM_XML) {
|
||||
auto result = InstallerService::patchSystemXML("storage_slc_installer:/config", this->appInfo->titleId);
|
||||
if (result != InstallerService::SUCCESS) {
|
||||
setError(ERROR_INSTALLER_ERROR);
|
||||
this->installerError = result;
|
||||
} else {
|
||||
auto fsaFd = IOSUHAX_FSA_Open();
|
||||
if (fsaFd >= 0) {
|
||||
if (IOSUHAX_FSA_FlushVolume(fsaFd, "/vol/storage_mlc01") == 0) {
|
||||
DEBUG_FUNCTION_LINE("Flushed mlc");
|
||||
}
|
||||
IOSUHAX_FSA_Close(fsaFd);
|
||||
} else {
|
||||
DEBUG_FUNCTION_LINE("Failed to open fsa");
|
||||
}
|
||||
this->state = STATE_INSTALL_SUCCESS;
|
||||
}
|
||||
} else if (this->state == STATE_INSTALL_SUCCESS) {
|
||||
if (entrySelected(input)) {
|
||||
this->state = STATE_WELCOME_SCREEN;
|
||||
OSForceFullRelaunch();
|
||||
SYSLaunchMenu();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -280,9 +318,10 @@ std::string ApplicationState::ErrorDescription() {
|
||||
return "UNKNOWN_ERROR";
|
||||
}
|
||||
|
||||
void ApplicationState::setError(eErrorState error) {
|
||||
void ApplicationState::setError(eErrorState err) {
|
||||
this->state = STATE_ERROR;
|
||||
this->error = error;
|
||||
this->error = err;
|
||||
OSEnableHomeButtonMenu(true);
|
||||
}
|
||||
|
||||
void ApplicationState::handleError() {
|
||||
|
@ -26,9 +26,10 @@ public:
|
||||
STATE_INSTALL_CONFIRM_DIALOG,
|
||||
STATE_INSTALL_STARTED,
|
||||
STATE_INSTALL_FST,
|
||||
STATE_INSTALL_SYSTEM_XML,
|
||||
STATE_INSTALL_COS,
|
||||
STATE_INSTALL_RPX
|
||||
STATE_INSTALL_RPX,
|
||||
STATE_INSTALL_SYSTEM_XML,
|
||||
STATE_INSTALL_SUCCESS
|
||||
};
|
||||
|
||||
ApplicationState();
|
||||
@ -57,7 +58,7 @@ public:
|
||||
|
||||
void proccessMenuNavigation(Input *input, int maxOptionValue);
|
||||
|
||||
bool entrySelected(Input *input);
|
||||
static bool entrySelected(Input *input);
|
||||
|
||||
bool installColdboot = false;
|
||||
InstallerService::eResults installerError = InstallerService::eResults::SUCCESS;
|
||||
|
@ -15,21 +15,20 @@
|
||||
#include <sstream>
|
||||
|
||||
systemXMLInformation systemXMLHashInformation[] = {
|
||||
{WII_U_MENU_JAP, 0x0005001010040000, "2645065A42D18D390C78543E3C4FE7E1D1957A63"},
|
||||
{WII_U_MENU_USA, 0x0005001010040100, "124562D41A02C7112DDD5F9A8F0EE5DF97E23471"},
|
||||
{WII_U_MENU_EUR, 0x0005001010040200, "F06041A4E5B3F899E748F1BAEB524DE058809F1D"},
|
||||
{HEALTH_SAFETY_JAP, 0x000500101004E000, "066D672824128713F0A7D156142A68B998080148"},
|
||||
{HEALTH_SAFETY_USA, 0x000500101004E100, "0EBCA1DFC0AB7A6A7FE8FB5EAF23179621B726A1"},
|
||||
{HEALTH_SAFETY_EUR, 0x000500101004E200, "DE46EC3E9B823ABA6CB0638D0C4CDEEF9C793BDD"}
|
||||
{WII_U_MENU_JAP, 0x0005001010040000L, "2645065A42D18D390C78543E3C4FE7E1D1957A63"},
|
||||
{WII_U_MENU_USA, 0x0005001010040100L, "124562D41A02C7112DDD5F9A8F0EE5DF97E23471"},
|
||||
{WII_U_MENU_EUR, 0x0005001010040200L, "F06041A4E5B3F899E748F1BAEB524DE058809F1D"},
|
||||
{HEALTH_SAFETY_JAP, 0x000500101004E000L, "066D672824128713F0A7D156142A68B998080148"},
|
||||
{HEALTH_SAFETY_USA, 0x000500101004E100L, "0EBCA1DFC0AB7A6A7FE8FB5EAF23179621B726A1"},
|
||||
{HEALTH_SAFETY_EUR, 0x000500101004E200L, "DE46EC3E9B823ABA6CB0638D0C4CDEEF9C793BDD"}
|
||||
};
|
||||
|
||||
appInformation supportedApps[] = {
|
||||
{0x000500101004E000, "Health and Safety Information [JPN]", false, {'\0'}, "9D34DDD91604D781FDB0727AC75021833304964C", "0"},
|
||||
{0x000500101004E100, "Health and Safety Information [USA]", false, {'\0'}, "045734666A36C7EF0258A740855886EBDB20D59B", "0"},
|
||||
{0x000500101004E200, "Health and Safety Information [EUR]", false, {'\0'}, "130A76F8B36B36D43B88BBC74393D9AFD9CFD2A4", "F6EBF7BC8AE3AF3BB8A42E0CF3FDA051278AEB03"},
|
||||
{0x000500101004E000L, "Health and Safety Information [JPN]", false, {'\0'}, "9D34DDD91604D781FDB0727AC75021833304964C", "0"},
|
||||
{0x000500101004E100L, "Health and Safety Information [USA]", false, {'\0'}, "045734666A36C7EF0258A740855886EBDB20D59B", "0"},
|
||||
{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());
|
||||
@ -329,7 +328,7 @@ std::string InstallerService::ErrorMessage(InstallerService::eResults error) {
|
||||
InstallerService::eResults InstallerService::patchFST(const std::string &path, const char *fstHash) {
|
||||
std::string fstFilePath = path + "/code/title.fst";
|
||||
std::string fstBackupFilePath = path + "/code/backup.fst";
|
||||
std::string fstTargetFilePath = path + "/code/titla.fst";
|
||||
std::string fstTargetFilePath = path + "/code/title.fst";
|
||||
|
||||
if (!FSUtils::copyFile(fstFilePath, fstBackupFilePath)) {
|
||||
DEBUG_FUNCTION_LINE("Failed to copy files");
|
||||
@ -440,3 +439,123 @@ 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";
|
||||
std::string rpxTargetFilePath = path + "/code/safe.rpx";
|
||||
|
||||
if (!FSUtils::copyFile(rpxSourceFilePath, rpxBackupFilePath)) {
|
||||
DEBUG_CONSOLE_LOG("Failed to copy files");
|
||||
return FAILED_TO_COPY_FILES;
|
||||
}
|
||||
|
||||
std::string srcHash = Utils::hashFile(rpxSourceFilePath);
|
||||
std::string dstHash = Utils::hashFile(rpxBackupFilePath);
|
||||
|
||||
if (srcHash != dstHash) {
|
||||
::remove(rpxBackupFilePath.c_str());
|
||||
DEBUG_CONSOLE_LOG("Hashes do not match. %s %s", srcHash.c_str(), dstHash.c_str());
|
||||
return FAILED_TO_CHECK_HASH_COPIED_FILES;
|
||||
}
|
||||
|
||||
if (FSUtils::saveBufferToFile(rpxTargetFilePath.c_str(), (void *) rpx_data, size) < 0) {
|
||||
DEBUG_CONSOLE_LOG("Cannot save rpx to file %s", rpxTargetFilePath.c_str());
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
std::string newHash = Utils::hashFile(rpxTargetFilePath);
|
||||
|
||||
if (StringTools::strCompareIC(rpx_hash, newHash)) {
|
||||
::remove(rpxBackupFilePath.c_str());
|
||||
DEBUG_CONSOLE_LOG("Successfully patched the safe.rpx");
|
||||
return SUCCESS;
|
||||
} else {
|
||||
DEBUG_CONSOLE_LOG("Hash mismatch! Expected %s but got %s while patching safe.rpx", rpx_hash.c_str(), newHash.c_str());
|
||||
}
|
||||
|
||||
FSUtils::copyFile(rpxBackupFilePath, rpxTargetFilePath);
|
||||
|
||||
std::string srcHash2 = Utils::hashFile(rpxTargetFilePath);
|
||||
|
||||
if (srcHash != srcHash2) {
|
||||
DEBUG_CONSOLE_LOG("Something went wrong. Failed to restore the safe.rpx. DO NOT RESTART THE SYSTEM until you manually restored the safe.rpx");
|
||||
return RPX_HASH_MISMATCH_RESTORE_FAILED;
|
||||
}
|
||||
::remove(rpxBackupFilePath.c_str());
|
||||
|
||||
return RPX_HASH_MISMATCH;
|
||||
}
|
||||
|
||||
InstallerService::eResults InstallerService::patchSystemXML(const std::string &path, uint64_t titleId) {
|
||||
std::string inputFile = std::string(path + "/system.xml");
|
||||
std::string backupFile = std::string(path + "/sbackup.xml");
|
||||
std::string finalFile = std::string(path + "/system.xml");
|
||||
|
||||
if (!FSUtils::copyFile(inputFile, backupFile)) {
|
||||
DEBUG_CONSOLE_LOG("Failed to copy files");
|
||||
return FAILED_TO_COPY_FILES;
|
||||
}
|
||||
|
||||
std::string srcHash = Utils::hashFile(inputFile);
|
||||
std::string dstHash = Utils::hashFile(backupFile);
|
||||
|
||||
if (srcHash != dstHash) {
|
||||
::remove(backupFile.c_str());
|
||||
DEBUG_CONSOLE_LOG("Hashes do not match. %s %s", srcHash.c_str(), dstHash.c_str());
|
||||
return FAILED_TO_CHECK_HASH_COPIED_FILES;
|
||||
}
|
||||
|
||||
systemXMLInformation *data = nullptr;
|
||||
int arrayLength = (sizeof(systemXMLHashInformation) / sizeof(*systemXMLHashInformation));
|
||||
for (int i = 0; i < arrayLength; i++) {
|
||||
if (systemXMLHashInformation[i].titleId == titleId) {
|
||||
data = &systemXMLHashInformation[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (data == nullptr) {
|
||||
::remove(backupFile.c_str());
|
||||
DEBUG_FUNCTION_LINE("Data was NULL");
|
||||
return SYSTEM_XML_INFORMATION_NOT_FOUND;
|
||||
}
|
||||
|
||||
pugi::xml_document doc;
|
||||
pugi::xml_parse_result resultSystem = doc.load_file(inputFile.c_str());
|
||||
if (!resultSystem) {
|
||||
::remove(backupFile.c_str());
|
||||
DEBUG_FUNCTION_LINE("Error while parsing %s: %s", inputFile.c_str(), resultSystem.description());
|
||||
return SYSTEM_XML_PARSING_FAILED;
|
||||
}
|
||||
|
||||
char tmp[18];
|
||||
snprintf(tmp, 17, "%016llX", data->titleId);
|
||||
|
||||
doc.child("system").child("default_title_id").first_child().set_value(tmp);
|
||||
doc.save_file(finalFile.c_str(), " ", pugi::format_default, pugi::encoding_utf8);
|
||||
|
||||
std::string newHash = Utils::hashFile(finalFile);
|
||||
|
||||
if (std::string(data->hash) == newHash) {
|
||||
::remove(backupFile.c_str());
|
||||
DEBUG_FUNCTION_LINE("Successfully patched the system.xml");
|
||||
return SUCCESS;
|
||||
} else {
|
||||
DEBUG_FUNCTION_LINE("Hash mismatch! Expected %s but got %s while setting default titleID to %s", data->hash, newHash.c_str(), data->titleId);
|
||||
}
|
||||
|
||||
FSUtils::copyFile(backupFile, finalFile);
|
||||
|
||||
std::string srcHash2 = Utils::hashFile(finalFile);
|
||||
|
||||
if (srcHash != srcHash2) {
|
||||
DEBUG_FUNCTION_LINE("Something went wrong. Failed to restore the system.xml. DO NOT RESTART THE SYSTEM until you manually restored the system.xml");
|
||||
return SYSTEM_XML_HASH_MISMATCH_RESTORE_FAILED;
|
||||
}
|
||||
|
||||
::remove(backupFile.c_str());
|
||||
|
||||
return SYSTEM_XML_HASH_MISMATCH;
|
||||
}
|
||||
|
@ -43,6 +43,10 @@ public:
|
||||
|
||||
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);
|
||||
|
||||
private:
|
||||
static eResults patchFSTData(uint8_t *fstData, uint32_t size);
|
||||
|
@ -10,7 +10,6 @@
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
#include "WiiUScreen.h"
|
||||
#include "utils/logger.h"
|
||||
#include "InstallerService.h"
|
||||
|
||||
#include "../build/safe_payload.h"
|
||||
|
Loading…
Reference in New Issue
Block a user