forked from Mirror/SafeB9SInstaller
Functional alpha state v0.0.2
Users, don't try this!
This commit is contained in:
parent
9ca9c135cc
commit
35ecd11bb8
@ -1,15 +1,19 @@
|
||||
#include "installer.h"
|
||||
#include "validator.h"
|
||||
#include "safewrite.h"
|
||||
#include "chainload.h"
|
||||
#include "nand.h"
|
||||
#include "ui.h"
|
||||
#include "qff.h"
|
||||
#include "hid.h"
|
||||
|
||||
#define COLOR_STATUS(s) ((s == STATUS_GREEN) ? COLOR_BRIGHTGREEN : (s == STATUS_YELLOW) ? COLOR_BRIGHTYELLOW : (s == STATUS_RED) ? COLOR_RED : COLOR_DARKGREY)
|
||||
|
||||
#define MIN_SD_FREE (16 * 1024 * 1024) // 16MB
|
||||
#define FIRM_NAND_OFFSET 0x0B130000
|
||||
#define FIRM_NAND_SIZE 0x800000
|
||||
#define FIRM0_NAND_OFFSET FIRM_NAND_OFFSET
|
||||
#define FIRM1_NAND_OFFSET (FIRM_NAND_OFFSET + (FIRM_NAND_SIZE/2))
|
||||
|
||||
#define NAME_SIGHAXFIRM (INPUT_PATH "/sighaxfirm.bin")
|
||||
#define NAME_SIGHAXFIRMSHA (INPUT_PATH "/sighaxfirm.bin.sha")
|
||||
@ -40,27 +44,28 @@ static char msgInstall[64] = "not started";
|
||||
u32 ShowInstallerStatus(void) {
|
||||
const u32 pos_xb = 10;
|
||||
const u32 pos_x0 = pos_xb;
|
||||
const u32 pos_x1 = pos_x0 + (16*FONT_WIDTH_EXT);
|
||||
const u32 pos_x1 = pos_x0 + (17*FONT_WIDTH_EXT);
|
||||
const u32 pos_yb = 10;
|
||||
const u32 pos_y0 = pos_yb + 20;
|
||||
const u32 stp = 12;
|
||||
|
||||
DrawStringF(BOT_SCREEN, pos_xb, pos_yb, COLOR_STD_FONT, COLOR_STD_BG, "SafeSigHaxInstaller v" VERSION);
|
||||
|
||||
DrawStringF(BOT_SCREEN, pos_x0, pos_y0 + 0, COLOR_STD_FONT, COLOR_STD_BG, "ARM9LoaderHax :");
|
||||
DrawStringF(BOT_SCREEN, pos_x0, pos_y0 + 10, COLOR_STD_FONT, COLOR_STD_BG, "MicroSD Card :");
|
||||
DrawStringF(BOT_SCREEN, pos_x0, pos_y0 + 20, COLOR_STD_FONT, COLOR_STD_BG, "Sighaxed FIRM :");
|
||||
DrawStringF(BOT_SCREEN, pos_x0, pos_y0 + 30, COLOR_STD_FONT, COLOR_STD_BG, "Secret Sector :");
|
||||
DrawStringF(BOT_SCREEN, pos_x0, pos_y0 + 40, COLOR_STD_FONT, COLOR_STD_BG, "Crypto Status :");
|
||||
DrawStringF(BOT_SCREEN, pos_x0, pos_y0 + 50, COLOR_STD_FONT, COLOR_STD_BG, "Backup Status :");
|
||||
DrawStringF(BOT_SCREEN, pos_x0, pos_y0 + 60, COLOR_STD_FONT, COLOR_STD_BG, "Install Status:");
|
||||
DrawStringF(BOT_SCREEN, pos_x0, pos_y0 + (0*stp), COLOR_STD_FONT, COLOR_STD_BG, "ARM9LoaderHax -");
|
||||
DrawStringF(BOT_SCREEN, pos_x0, pos_y0 + (1*stp), COLOR_STD_FONT, COLOR_STD_BG, "MicroSD Card -");
|
||||
DrawStringF(BOT_SCREEN, pos_x0, pos_y0 + (2*stp), COLOR_STD_FONT, COLOR_STD_BG, "Sighaxed FIRM -");
|
||||
DrawStringF(BOT_SCREEN, pos_x0, pos_y0 + (3*stp), COLOR_STD_FONT, COLOR_STD_BG, "Secret Sector -");
|
||||
DrawStringF(BOT_SCREEN, pos_x0, pos_y0 + (4*stp), COLOR_STD_FONT, COLOR_STD_BG, "Crypto Status -");
|
||||
DrawStringF(BOT_SCREEN, pos_x0, pos_y0 + (5*stp), COLOR_STD_FONT, COLOR_STD_BG, "Backup Status -");
|
||||
DrawStringF(BOT_SCREEN, pos_x0, pos_y0 + (6*stp), COLOR_STD_FONT, COLOR_STD_BG, "Install Status -");
|
||||
|
||||
DrawStringF(BOT_SCREEN, pos_x1, pos_y0 + 0, COLOR_STATUS(statusA9lh) , COLOR_STD_BG, "%-22.22s", msgA9lh );
|
||||
DrawStringF(BOT_SCREEN, pos_x1, pos_y0 + 10, COLOR_STATUS(statusSdCard) , COLOR_STD_BG, "%-22.22s", msgSdCard );
|
||||
DrawStringF(BOT_SCREEN, pos_x1, pos_y0 + 20, COLOR_STATUS(statusFirm) , COLOR_STD_BG, "%-22.22s", msgFirm );
|
||||
DrawStringF(BOT_SCREEN, pos_x1, pos_y0 + 30, COLOR_STATUS(statusSector) , COLOR_STD_BG, "%-22.22s", msgSector );
|
||||
DrawStringF(BOT_SCREEN, pos_x1, pos_y0 + 40, COLOR_STATUS(statusCrypto) , COLOR_STD_BG, "%-22.22s", msgCrypto );
|
||||
DrawStringF(BOT_SCREEN, pos_x1, pos_y0 + 50, COLOR_STATUS(statusBackup) , COLOR_STD_BG, "%-22.22s", msgBackup );
|
||||
DrawStringF(BOT_SCREEN, pos_x1, pos_y0 + 60, COLOR_STATUS(statusInstall), COLOR_STD_BG, "%-22.22s", msgInstall);
|
||||
DrawStringF(BOT_SCREEN, pos_x1, pos_y0 + (0*stp), COLOR_STATUS(statusA9lh) , COLOR_STD_BG, "%-21.21s", msgA9lh );
|
||||
DrawStringF(BOT_SCREEN, pos_x1, pos_y0 + (1*stp), COLOR_STATUS(statusSdCard) , COLOR_STD_BG, "%-21.21s", msgSdCard );
|
||||
DrawStringF(BOT_SCREEN, pos_x1, pos_y0 + (2*stp), COLOR_STATUS(statusFirm) , COLOR_STD_BG, "%-21.21s", msgFirm );
|
||||
DrawStringF(BOT_SCREEN, pos_x1, pos_y0 + (3*stp), COLOR_STATUS(statusSector) , COLOR_STD_BG, "%-21.21s", msgSector );
|
||||
DrawStringF(BOT_SCREEN, pos_x1, pos_y0 + (4*stp), COLOR_STATUS(statusCrypto) , COLOR_STD_BG, "%-21.21s", msgCrypto );
|
||||
DrawStringF(BOT_SCREEN, pos_x1, pos_y0 + (5*stp), COLOR_STATUS(statusBackup) , COLOR_STD_BG, "%-21.21s", msgBackup );
|
||||
DrawStringF(BOT_SCREEN, pos_x1, pos_y0 + (6*stp), COLOR_STATUS(statusInstall), COLOR_STD_BG, "%-21.21s", msgInstall);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -132,7 +137,7 @@ u32 SafeSigHaxInstaller(void) {
|
||||
|
||||
|
||||
// step #3 - check secret_sector.bin file
|
||||
u8 secret_sector[0x20];
|
||||
u8 secret_sector[0x200];
|
||||
if (CheckA9lh()) {
|
||||
snprintf(msgSector, 64, "checking...");
|
||||
statusSector = STATUS_YELLOW;
|
||||
@ -232,8 +237,68 @@ u32 SafeSigHaxInstaller(void) {
|
||||
// backups done
|
||||
|
||||
// step #6 - install sighaxed FIRM
|
||||
ShowPrompt(false, "Install not finished - this is only a preview");
|
||||
// ShowPrompt(false, "Install not finished - this is only a preview");
|
||||
snprintf(msgInstall, 64, "FIRM install...");
|
||||
statusInstall = STATUS_YELLOW;
|
||||
ShowInstallerStatus();
|
||||
ShowProgress(0, 0, "FIRM install");
|
||||
do {
|
||||
ret = SafeWriteNand(FIRM_BUFFER, FIRM0_NAND_OFFSET, firm_size, 0x06);
|
||||
if (ret != 0) break;
|
||||
ShowProgress(1, 2, "FIRM install (1/2)");
|
||||
snprintf(msgInstall, 64, "FIRM install (1/2)");
|
||||
ShowInstallerStatus();
|
||||
ret = SafeWriteNand(FIRM_BUFFER, FIRM1_NAND_OFFSET, firm_size, 0x06);
|
||||
if (ret != 0) break;
|
||||
ShowProgress(1, 2, "FIRM install (2/2)");
|
||||
snprintf(msgInstall, 64, "FIRM install (2/2)");
|
||||
ShowInstallerStatus();
|
||||
if (CheckA9lh()) {
|
||||
snprintf(msgInstall, 64, "0x96 revert...");
|
||||
ShowInstallerStatus();
|
||||
ret = SafeWriteNand(secret_sector, 0x96, 0x200, 0x06);
|
||||
if (ret == 0) snprintf(msgA9lh, 64, "uninstalled");
|
||||
}
|
||||
} while (false);
|
||||
if (ret == 0) {
|
||||
snprintf(msgInstall, 64, "install success!");
|
||||
statusInstall = STATUS_GREEN;
|
||||
return 0;
|
||||
} else {
|
||||
snprintf(msgInstall, 64, "install failed");
|
||||
statusInstall = STATUS_RED;
|
||||
if (CheckA9lh()) {
|
||||
snprintf(msgA9lh, 64, "fucked up");
|
||||
statusA9lh = STATUS_RED;
|
||||
}
|
||||
}
|
||||
|
||||
// if we end up here: uhoh
|
||||
ShowPrompt(false, "SafeSigHaxInstaller failed!\nThis really should not have happened :/.");
|
||||
ShowPrompt(false, "You can now load an external payload\nto try and fix up your system.\n \nThis may be your LAST CHANCE!\nUse it wisely.");
|
||||
const char* optionstr[2] = { "Unmount SD card", "Launch " INPUT_PATH "/payload.bin" };
|
||||
while (true) {
|
||||
u32 user_select = ShowSelectPrompt(2, optionstr, "Make your choice.");
|
||||
if (user_select == 1) {
|
||||
fs_deinit();
|
||||
ShowString("SD card unmounted, you can eject now.\n \n<A> to remount SD card");
|
||||
while (true) {
|
||||
u32 pad_choice = InputWait();
|
||||
if (!(pad_choice & BUTTON_A)) continue;
|
||||
if (fs_init() == FR_OK) break;
|
||||
ShowString("Reinitialising SD card failed!\n \n<A> to retry");
|
||||
}
|
||||
} else if (user_select == 2) {
|
||||
UINT payload_size;
|
||||
if ((f_qread(INPUT_PATH "/payload.bin", WORK_BUFFER, 0, WORK_BUFFER_SIZE, &payload_size) != FR_OK) ||
|
||||
!payload_size || (payload_size > PAYLOAD_MAX_SIZE))
|
||||
continue;
|
||||
if (ShowUnlockSequence(3, "payload.bin (%dkB)\nLaunch as arm9 payload?", payload_size / 1024)) {
|
||||
Chainload(WORK_BUFFER, payload_size);
|
||||
while(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "installer.h"
|
||||
#include "ui.h"
|
||||
#include "i2c.h"
|
||||
#include "qff.h"
|
||||
|
||||
void Reboot()
|
||||
{
|
||||
@ -14,7 +15,9 @@ int main()
|
||||
u32 ret = SafeSigHaxInstaller();
|
||||
ShowInstallerStatus(); // update installer status one last time
|
||||
if (ret) ShowPrompt(false, "SigHaxed FIRM was not installed!\nCheck lower screen for info.");
|
||||
else ShowPrompt(false, "SigHaxed FIRM install success!");
|
||||
ClearScreenF(true, true, COLOR_STD_BG);
|
||||
fs_deinit();
|
||||
Reboot();
|
||||
return 0;
|
||||
}
|
||||
|
@ -172,12 +172,12 @@ bool CheckSector0x96Crypto(void)
|
||||
bool CheckFirmCrypto(void)
|
||||
{
|
||||
// check the FIRM magic
|
||||
const u8 magic[8] = {'F', 'I', 'R', 'M', '\0', '\0', '\0', '\0'};
|
||||
const u8 magic[8] = {'F', 'I', 'R', 'M'};
|
||||
const u32 sectors[] = { SECTOR_FIRM0, SECTOR_FIRM1 };
|
||||
u8 buffer[0x200];
|
||||
for (u32 i = 0; i < sizeof(sectors) / sizeof(u32); i++) {
|
||||
ReadNandSectors(buffer, sectors[i], 1, 0x06);
|
||||
if (memcmp(buffer, magic, 8) != 0) return false;
|
||||
if (memcmp(buffer, magic, sizeof(magic)) != 0) return false;
|
||||
}
|
||||
|
||||
// success if we arrive here
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "validator.h"
|
||||
#include "sha.h"
|
||||
|
||||
#define FIRM_MAGIC 'F', 'I', 'R', 'M', '\0', '\0', '\0', '\0'
|
||||
#define FIRM_MAGIC 'F', 'I', 'R', 'M'
|
||||
#define FIRM_MAX_SIZE 0x400000 // 4MB, due to FIRM partition size
|
||||
|
||||
// see: https://www.3dbrew.org/wiki/FIRM#Firmware_Section_Headers
|
||||
@ -15,7 +15,8 @@ typedef struct {
|
||||
|
||||
// see: https://www.3dbrew.org/wiki/FIRM#FIRM_Header
|
||||
typedef struct {
|
||||
u8 magic[8];
|
||||
u8 magic[4];
|
||||
u8 priority[4];
|
||||
u32 entry_arm11;
|
||||
u32 entry_arm9;
|
||||
u8 reserved1[0x30];
|
||||
@ -56,6 +57,8 @@ u32 ValidateFirmHeader(FirmHeader* header, u32 data_size) {
|
||||
|
||||
u32 ValidateFirm(void* firm, u8* firm_sha, u32 firm_size, char* output) {
|
||||
FirmHeader* header = (FirmHeader*) firm;
|
||||
int section_arm11 = -1;
|
||||
int section_arm9 = -1;
|
||||
|
||||
// validate firm header
|
||||
if (ValidateFirmHeader(header, firm_size) != 0)
|
||||
@ -69,6 +72,18 @@ u32 ValidateFirm(void* firm, u8* firm_sha, u32 firm_size, char* output) {
|
||||
if (output) snprintf(output, 64, "Section %lu hash mismatch", i);
|
||||
return 1;
|
||||
}
|
||||
if ((header->entry_arm11 >= section->address) &&
|
||||
(header->entry_arm11 < section->address + section->size))
|
||||
section_arm11 = i;
|
||||
if ((header->entry_arm9 >= section->address) &&
|
||||
(header->entry_arm9 < section->address + section->size))
|
||||
section_arm9 = i;
|
||||
}
|
||||
|
||||
// sections for arm11 / arm9 entrypoints not found?
|
||||
if ((section_arm11 < 0) || (section_arm9 < 0)) {
|
||||
if (output) snprintf(output, 64, "ARM11/ARM9 entrypoints not found");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// check provided .SHA
|
||||
@ -77,9 +92,6 @@ u32 ValidateFirm(void* firm, u8* firm_sha, u32 firm_size, char* output) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ARM9 / ARM11 area check (?)
|
||||
// more (?)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -88,7 +100,7 @@ u32 ValidateSector(void* sector) {
|
||||
}
|
||||
|
||||
u32 CheckFirmSigHax(void* firm) {
|
||||
return 0; // not like we can check that already
|
||||
return 0; // not like we can check that already (!!!)
|
||||
FirmHeader* header = (FirmHeader*) firm;
|
||||
return (sha_cmp(sighaxHash, header->signature, 0x100, SHA256_MODE) == 0) ? 0 : 1;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user