mirror of
https://github.com/d0k3/GodMode9.git
synced 2025-06-26 13:42:47 +00:00
Added ARM9 payload launching
This commit is contained in:
parent
d9dbf14f8b
commit
af32ca3ac5
7
source/common/chainload.h
Normal file
7
source/common/chainload.h
Normal file
@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#define PAYLOAD_MAX_SIZE 0xFFFE0
|
||||
|
||||
void Chainload(u8 *source, size_t size);
|
52
source/common/chainload.s
Normal file
52
source/common/chainload.s
Normal file
@ -0,0 +1,52 @@
|
||||
@ Wolfvak - 25/01/2017
|
||||
|
||||
@ TODO: ELF launcher
|
||||
@ void Chainload(u8 *source, size_t size)
|
||||
@ Wrapper around chainload_itcm
|
||||
|
||||
.arm
|
||||
.global Chainload
|
||||
.type Chainload, %function
|
||||
Chainload:
|
||||
ldr r2, =0x1FF8100 @ ITCM + 0x100 bytes
|
||||
mov r3, r2
|
||||
ldr r4, =chainload_itcm
|
||||
ldr r5, =chainload_itcm_end
|
||||
|
||||
.copy_chainloader:
|
||||
cmp r4, r5
|
||||
ldrlt r6, [r4], #4
|
||||
strlt r6, [r3], #4
|
||||
blt .copy_chainloader
|
||||
|
||||
bx r2 @ Branch to the real chainloader in ITCM
|
||||
|
||||
|
||||
@ void chainload_itcm(void)
|
||||
@ Note: Uses unprotected bootrom functions
|
||||
.arm
|
||||
.type chainload_itcm, %function
|
||||
.align 4
|
||||
chainload_itcm:
|
||||
mov r2, r1
|
||||
ldr r1, =0x23F00000
|
||||
|
||||
mov r4, r1 @ memcpy256 and clean_flush_cache mess with the registers
|
||||
|
||||
ldr r3, =0xFFFF03F0 @ memcpy256(u32 *src, u32 *ddest, size_t size)
|
||||
blx r3
|
||||
|
||||
ldr r3, =0xFFFF0830 @ void clean_flush_cache(void)
|
||||
blx r3
|
||||
|
||||
mov r3, r4
|
||||
|
||||
mov r0, #0 @ Clear argc
|
||||
mov r1, #0 @ Same for argv
|
||||
mov r2, #0
|
||||
mov lr, #0
|
||||
bx r3
|
||||
|
||||
.pool
|
||||
|
||||
chainload_itcm_end:
|
@ -2,6 +2,7 @@
|
||||
#include "fsutil.h"
|
||||
#include "fatmbr.h"
|
||||
#include "game.h"
|
||||
#include "chainload.h"
|
||||
|
||||
u32 IdentifyFileType(const char* path) {
|
||||
const u8 romfs_magic[] = { ROMFS_MAGIC };
|
||||
@ -9,9 +10,9 @@ u32 IdentifyFileType(const char* path) {
|
||||
u8 header[0x200] __attribute__((aligned(32))); // minimum required size
|
||||
size_t fsize = FileGetSize(path);
|
||||
char* fname = strrchr(path, '/');
|
||||
if (fname == NULL) return 0; // not a proper path
|
||||
fname++;
|
||||
if (FileGetData(path, header, 0x200, 0) < fsize) return 0;
|
||||
char* ext = (fname) ? strrchr(++fname, '.') : NULL;
|
||||
if (ext) ext++;
|
||||
if (FileGetData(path, header, 0x200, 0) < ((fsize > 0x200) ? 0x200 : fsize)) return 0;
|
||||
|
||||
if (fsize >= 0x200) {
|
||||
if ((getbe32(header + 0x100) == 0x4E435344) && (getbe64(header + 0x110) == (u64) 0x0104030301000000) &&
|
||||
@ -51,8 +52,12 @@ u32 IdentifyFileType(const char* path) {
|
||||
}
|
||||
if ((fsize > sizeof(NcchInfoHeader)) &&
|
||||
(GetNcchInfoVersion((NcchInfoHeader*) (void*) header)) &&
|
||||
(strncasecmp(fname, NCCHINFO_NAME, 32) == 0)) {
|
||||
return MISC_NINFO; // ncchinfo.bin file
|
||||
fname && (strncasecmp(fname, NCCHINFO_NAME, 32) == 0)) {
|
||||
return BIN_NCCHNFO; // ncchinfo.bin file
|
||||
#if PAYLOAD_MAX_SIZE <= TEMP_BUFFER_SIZE
|
||||
} else if ((fsize <= PAYLOAD_MAX_SIZE) && (strncasecmp(ext, "bin", 4) == 0)) {
|
||||
return BIN_LAUNCH; // assume it's an ARM9 payload
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -2,19 +2,17 @@
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#define IMG_FAT (1<<0)
|
||||
#define IMG_NAND (1<<1)
|
||||
|
||||
#define GAME_CIA (1<<2)
|
||||
#define GAME_NCSD (1<<3)
|
||||
#define GAME_NCCH (1<<4)
|
||||
#define GAME_TMD (1<<5)
|
||||
#define GAME_EXEFS (1<<6)
|
||||
#define GAME_ROMFS (1<<7)
|
||||
|
||||
#define SYS_FIRM (1<<8)
|
||||
|
||||
#define MISC_NINFO (1<<9)
|
||||
#define IMG_FAT (1<<0)
|
||||
#define IMG_NAND (1<<1)
|
||||
#define GAME_CIA (1<<2)
|
||||
#define GAME_NCSD (1<<3)
|
||||
#define GAME_NCCH (1<<4)
|
||||
#define GAME_TMD (1<<5)
|
||||
#define GAME_EXEFS (1<<6)
|
||||
#define GAME_ROMFS (1<<7)
|
||||
#define SYS_FIRM (1<<8)
|
||||
#define BIN_NCCHNFO (1<<9)
|
||||
#define BIN_LAUNCH (1<<10)
|
||||
|
||||
#define FTYPE_MOUNTABLE (IMG_FAT|IMG_NAND|GAME_CIA|GAME_NCSD|GAME_NCCH|GAME_EXEFS|GAME_ROMFS|SYS_FIRM)
|
||||
#define FYTPE_VERIFICABLE (IMG_NAND|GAME_CIA|GAME_NCSD|GAME_NCCH|GAME_TMD|SYS_FIRM)
|
||||
@ -22,6 +20,7 @@
|
||||
#define FTYPE_BUILDABLE (GAME_NCSD|GAME_NCCH|GAME_TMD)
|
||||
#define FTYPE_BUILDABLE_L (FTYPE_BUILDABLE&(GAME_TMD))
|
||||
#define FTYPE_RESTORABLE (IMG_NAND)
|
||||
#define FTYPE_XORPAD (MISC_NINFO)
|
||||
#define FTYPE_XORPAD (BIN_NCCHNFO)
|
||||
#define FTYPE_PAYLOAD (BIN_LAUNCH)
|
||||
|
||||
u32 IdentifyFileType(const char* path);
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "vcart.h"
|
||||
#include "ncchinfo.h"
|
||||
#include "image.h"
|
||||
#include "chainload.h"
|
||||
|
||||
#define N_PANES 2
|
||||
|
||||
@ -589,8 +590,9 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, DirStruct* cur
|
||||
bool buildable_legit = (filetype & FTYPE_BUILDABLE_L);
|
||||
bool restorable = (CheckA9lh() && (filetype & FTYPE_RESTORABLE) && !(drvtype & DRV_SYSNAND));
|
||||
bool xorpadable = (filetype & FTYPE_XORPAD);
|
||||
bool launchable = ((filetype & FTYPE_PAYLOAD) && (drvtype & DRV_FAT));
|
||||
bool special_opt = mountable || verificable || decryptable || decryptable_inplace ||
|
||||
buildable || buildable_legit || restorable || xorpadable;
|
||||
buildable || buildable_legit || restorable || xorpadable || launchable;
|
||||
|
||||
char pathstr[32 + 1];
|
||||
TruncateString(pathstr, curr_entry->path, 32, 8);
|
||||
@ -623,7 +625,8 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, DirStruct* cur
|
||||
(filetype == GAME_ROMFS) ? "Mount as ROMFS image" :
|
||||
(filetype == GAME_TMD) ? "TMD file options..." :
|
||||
(filetype == SYS_FIRM) ? "FIRM image options..." :
|
||||
(filetype == MISC_NINFO) ? "NCCHinfo options..." : "???";
|
||||
(filetype == BIN_NCCHNFO) ? "NCCHinfo options..." :
|
||||
(filetype == BIN_LAUNCH) ? "Launch as arm9 payload" : "???";
|
||||
optionstr[hexviewer-1] = "Show in Hexeditor";
|
||||
optionstr[calcsha-1] = "Calculate SHA-256";
|
||||
if (copystd > 0) optionstr[copystd-1] = "Copy to " OUTPUT_PATH;
|
||||
@ -698,6 +701,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, DirStruct* cur
|
||||
int verify = (verificable) ? ++n_opt : -1;
|
||||
int xorpad = (xorpadable) ? ++n_opt : -1;
|
||||
int xorpad_inplace = (xorpadable) ? ++n_opt : -1;
|
||||
int launch = (launchable) ? ++n_opt : -1;
|
||||
if (mount > 0) optionstr[mount-1] = "Mount image to drive";
|
||||
if (restore > 0) optionstr[restore-1] = "Restore SysNAND (safe)";
|
||||
if (decrypt > 0) optionstr[decrypt-1] = "Decrypt file (SD output)";
|
||||
@ -707,6 +711,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, DirStruct* cur
|
||||
if (verify > 0) optionstr[verify-1] = "Verify file";
|
||||
if (xorpad > 0) optionstr[xorpad-1] = "Build XORpads (SD output)";
|
||||
if (xorpad_inplace > 0) optionstr[xorpad_inplace-1] = "Build XORpads (inplace)";
|
||||
if (launch > 0) optionstr[launch-1] = "Launch as ARM9 payload";
|
||||
|
||||
// auto select when there is only one option
|
||||
user_select = (n_opt > 1) ? (int) ShowSelectPrompt(n_opt, optionstr, pathstr) : n_opt;
|
||||
@ -858,6 +863,14 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, DirStruct* cur
|
||||
*scroll = 0;
|
||||
*cursor = 1;
|
||||
}
|
||||
} else if ((user_select == launch)) {
|
||||
size_t payload_size = FileGetSize(curr_entry->path);
|
||||
if (ShowPrompt(true, "%s (%dkB)\nLaunch as arm9 payload?", pathstr, payload_size / 1024)) {
|
||||
if (FileGetData(curr_entry->path, TEMP_BUFFER, payload_size, 0) == payload_size) {
|
||||
Chainload(TEMP_BUFFER, payload_size);
|
||||
while(1);
|
||||
} // failed load is basically impossible here
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
Loading…
x
Reference in New Issue
Block a user