Skip to content

Commit

Permalink
Merge branch 'prsh' into allmerge
Browse files Browse the repository at this point in the history
  • Loading branch information
jan-hofmeier committed Aug 30, 2023
2 parents 92b75d8 + 035bb7f commit c0f7a26
Show file tree
Hide file tree
Showing 4 changed files with 179 additions and 0 deletions.
1 change: 1 addition & 0 deletions ios_mcp/source/imports.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ typedef struct __attribute__((__packed__)) {

// thumb functions can't just be provided to the linker
#define setDefaultTitleId ((int (*)(uint64_t tid)) (0x0510d984 | 1))
#define encryptPrsh ((int (*)(uint32_t, uint32_t, void *, uint32_t)) (0x0500a610 | 1))

typedef enum BSPHardwareVersions {
BSP_HARDWARE_VERSION_UNKNOWN = 0x00000000,
Expand Down
160 changes: 160 additions & 0 deletions ios_mcp/source/menu.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ static void option_DumpOtpAndSeeprom(void);
static void option_LoadNetConf(void);
static void option_EditParental(void);
static void option_SetInitialLaunch(void);
static void option_LoadBoot1Payload(void);
static void option_Shutdown(void);
static void option_checkMLC(void);
static void option_checkSLC(void);
Expand Down Expand Up @@ -83,6 +84,7 @@ static const Menu mainMenuOptions[] = {
{"Debug System Region", {.callback = option_DebugSystemRegion}},
{"System Information", {.callback = option_SystemInformation}},
{"Submit System Data", {.callback = option_SubmitSystemData}},
{"Load BOOT1 payload", {.callback = option_LoadBoot1Payload}},
{"Shutdown", {.callback = option_Shutdown}},
};

Expand Down Expand Up @@ -894,6 +896,164 @@ int read_otp_seeprom(void *buf, int index)
return 0;
}

static int preparePrshHax(void)
{
// RAM vars
uint32_t ram_start_addr = 0x10000000;
uint32_t ram_test_buf_size = 0x400;

// PRSH vars
uint32_t prsh_hdr_offset = ram_start_addr + ram_test_buf_size + 0x5654;
uint32_t prsh_hdr_size = 0x1C;

// boot_info vars
uint32_t boot_info_name_addr = prsh_hdr_offset + prsh_hdr_size;
uint32_t boot_info_name_size = 0x100;
uint32_t boot_info_ptr_addr = boot_info_name_addr + boot_info_name_size;

// Calculate PRSH checksum
uint32_t checksum_old = 0;
uint32_t word_counter = 0;

while (word_counter < 0x20D) {
checksum_old ^= *(uint32_t *) (prsh_hdr_offset + 0x04 + word_counter * 0x04);
word_counter++;
}

// Change boot_info to point inside boot1 memory
*(uint32_t *) boot_info_ptr_addr = 0x0D40AC6D;

// Re-calculate PRSH checksum
uint32_t checksum = 0;
word_counter = 0;

while (word_counter < 0x20D) {
checksum ^= *(uint32_t *) (prsh_hdr_offset + 0x04 + word_counter * 0x04);
word_counter++;
}

// Update checksum
*(uint32_t *) prsh_hdr_offset = checksum;

// Copy PRSH IV from IOS-MCP
void *prsh_iv_buf = IOS_HeapAlloc(CROSS_PROCESS_HEAP_ID, 0x10);
if (!prsh_iv_buf) {
return -1;
}

memcpy(prsh_iv_buf, (void*) 0x050677C0, 0x10);

// Encrypt PRSH
int res = encryptPrsh(0x10000400, 0x7C00, prsh_iv_buf, 0x10);

// Free PRSH IV buffer
IOS_HeapFree(CROSS_PROCESS_HEAP_ID, prsh_iv_buf);

// Flush cache
IOS_FlushDCache((void*) 0x10000400, 0x7C00);

return res;
}

static void option_LoadBoot1Payload(void)
{
static const Menu boot1ControlOptions[] = {
{"Back", {0} },
{"Load", {0} },
};

gfx_clear(COLOR_BACKGROUND);

uint32_t index = 16 + 8 + 2 + 8;
gfx_set_font_color(COLOR_PRIMARY);

index = gfx_printf(16, index, GfxPrintFlag_ClearBG, "This will load a payload from within boot1\n"
"from the SD Card named boot1.img.\n\n"
"Do you want to continue?\n\n\n");

int selected = drawMenu("Load BOOT1 Payload",
boot1ControlOptions, ARRAY_SIZE(boot1ControlOptions), 0,
MenuFlag_NoClearScreen, 16, index);
index += (CHAR_SIZE_DRC_Y + 4) * (ARRAY_SIZE(boot1ControlOptions) + 1);

if (selected == 0)
return;

int fileHandle;
int res = FSA_OpenFile(fsaHandle, "/vol/storage_recovsd/boot1.img", "r", &fileHandle);
if (res < 0) {
gfx_set_font_color(COLOR_ERROR);
gfx_printf(16, index, 0, "Failed to open boot1.img: %x", res);
waitButtonInput();
return;
}

uint32_t* dataBuffer = (uint32_t*) IOS_HeapAllocAligned(CROSS_PROCESS_HEAP_ID, 0x40, 0x40);
if (!dataBuffer) {
gfx_set_font_color(COLOR_ERROR);
gfx_printf(16, index, 0, "Failed to allocate data buffer!");
waitButtonInput();
FSA_CloseFile(fsaHandle, fileHandle);
return;
}

// // skip the ancast header
// res = FSA_SetPosFile(fsaHandle, fileHandle, 0x200);
// if (res < 0) {
// gfx_set_font_color(COLOR_ERROR);
// gfx_printf(16, index, 0, "Failed to set boot1.img pos: %x", res);
// waitButtonInput();
// IOS_HeapFree(CROSS_PROCESS_HEAP_ID, dataBuffer);
// FSA_CloseFile(fsaHandle, fileHandle);
// return;
// }

// TODO verify that this is actually a valid ancast image, maybe do that before writing it to MEM1 actually
// read ancast header first and then the rest

// read and write payload to mem1
uint32_t payloadOffset = 0x00000050;
int bytesRead = 0;
while ((res = FSA_ReadFile(fsaHandle, dataBuffer, 1, 0x40, fileHandle, 0)) > 0) {
bytesRead += res;
for (int i = 0; i < res; i += 4) {
kernWrite32(payloadOffset, dataBuffer[i/4]);
payloadOffset += 4;
}
}

gfx_printf(16, index, 0, "Read %d bytes", bytesRead);

IOS_HeapFree(CROSS_PROCESS_HEAP_ID, dataBuffer);
FSA_CloseFile(fsaHandle, fileHandle);

if (res < 0) {
gfx_set_font_color(COLOR_ERROR);
gfx_printf(16, index, 0, "Failed to read boot1.img: %x", res);
waitButtonInput();
return;
}

res = preparePrshHax();
if (res < 0) {
gfx_set_font_color(COLOR_ERROR);
gfx_printf(16, index, 0, "Failed to prepare prshhax: %x", res);
waitButtonInput();
return;
}

// Setup branch to MEM1 payload (skip ancast + loader header) TODO we probably won't have to skip the loader header, boot1 usually doesn't come with one
kernWrite32(0x00000000, 0xEA000096); // b #0x260
//kernWrite32(0x00000000, 0xEA000012); // b #0x50
kernWrite32(0x00000004, 0xDEADC0DE);
kernWrite32(0x00000008, 0xDEADC0DE);

IOS_Shutdown(1);

// we're at the point of no return
while(1);
}

static void option_SetInitialLaunch(void)
{
static const Menu initialLaunchOptions[] = {
Expand Down
15 changes: 15 additions & 0 deletions ios_mcp/source/pm.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#include "pm.h"
#include "imports.h"

int PM_Restart(void)
{
int fd = IOS_Open("/dev/pm",0);
if (fd < 0) {
return fd;
}

int res = IOS_Ioctl(fd, 0xe3, NULL, 0, NULL, 0);
IOS_Close(fd);

return res;
}
3 changes: 3 additions & 0 deletions ios_mcp/source/pm.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#pragma once

int PM_Restart(void);

0 comments on commit c0f7a26

Please sign in to comment.