Functional alpha state v0.0.2

Users, don't try this!
This commit is contained in:
d0k3 2017-02-02 15:42:39 +01:00
parent 9ca9c135cc
commit 35ecd11bb8
4 changed files with 105 additions and 25 deletions

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}