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 "fsutil.h"
|
||||||
#include "fatmbr.h"
|
#include "fatmbr.h"
|
||||||
#include "game.h"
|
#include "game.h"
|
||||||
|
#include "chainload.h"
|
||||||
|
|
||||||
u32 IdentifyFileType(const char* path) {
|
u32 IdentifyFileType(const char* path) {
|
||||||
const u8 romfs_magic[] = { ROMFS_MAGIC };
|
const u8 romfs_magic[] = { ROMFS_MAGIC };
|
||||||
@ -9,9 +10,9 @@ u32 IdentifyFileType(const char* path) {
|
|||||||
u8 header[0x200] __attribute__((aligned(32))); // minimum required size
|
u8 header[0x200] __attribute__((aligned(32))); // minimum required size
|
||||||
size_t fsize = FileGetSize(path);
|
size_t fsize = FileGetSize(path);
|
||||||
char* fname = strrchr(path, '/');
|
char* fname = strrchr(path, '/');
|
||||||
if (fname == NULL) return 0; // not a proper path
|
char* ext = (fname) ? strrchr(++fname, '.') : NULL;
|
||||||
fname++;
|
if (ext) ext++;
|
||||||
if (FileGetData(path, header, 0x200, 0) < fsize) return 0;
|
if (FileGetData(path, header, 0x200, 0) < ((fsize > 0x200) ? 0x200 : fsize)) return 0;
|
||||||
|
|
||||||
if (fsize >= 0x200) {
|
if (fsize >= 0x200) {
|
||||||
if ((getbe32(header + 0x100) == 0x4E435344) && (getbe64(header + 0x110) == (u64) 0x0104030301000000) &&
|
if ((getbe32(header + 0x100) == 0x4E435344) && (getbe64(header + 0x110) == (u64) 0x0104030301000000) &&
|
||||||
@ -51,8 +52,12 @@ u32 IdentifyFileType(const char* path) {
|
|||||||
}
|
}
|
||||||
if ((fsize > sizeof(NcchInfoHeader)) &&
|
if ((fsize > sizeof(NcchInfoHeader)) &&
|
||||||
(GetNcchInfoVersion((NcchInfoHeader*) (void*) header)) &&
|
(GetNcchInfoVersion((NcchInfoHeader*) (void*) header)) &&
|
||||||
(strncasecmp(fname, NCCHINFO_NAME, 32) == 0)) {
|
fname && (strncasecmp(fname, NCCHINFO_NAME, 32) == 0)) {
|
||||||
return MISC_NINFO; // ncchinfo.bin file
|
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;
|
return 0;
|
||||||
|
@ -2,19 +2,17 @@
|
|||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
#define IMG_FAT (1<<0)
|
#define IMG_FAT (1<<0)
|
||||||
#define IMG_NAND (1<<1)
|
#define IMG_NAND (1<<1)
|
||||||
|
#define GAME_CIA (1<<2)
|
||||||
#define GAME_CIA (1<<2)
|
#define GAME_NCSD (1<<3)
|
||||||
#define GAME_NCSD (1<<3)
|
#define GAME_NCCH (1<<4)
|
||||||
#define GAME_NCCH (1<<4)
|
#define GAME_TMD (1<<5)
|
||||||
#define GAME_TMD (1<<5)
|
#define GAME_EXEFS (1<<6)
|
||||||
#define GAME_EXEFS (1<<6)
|
#define GAME_ROMFS (1<<7)
|
||||||
#define GAME_ROMFS (1<<7)
|
#define SYS_FIRM (1<<8)
|
||||||
|
#define BIN_NCCHNFO (1<<9)
|
||||||
#define SYS_FIRM (1<<8)
|
#define BIN_LAUNCH (1<<10)
|
||||||
|
|
||||||
#define MISC_NINFO (1<<9)
|
|
||||||
|
|
||||||
#define FTYPE_MOUNTABLE (IMG_FAT|IMG_NAND|GAME_CIA|GAME_NCSD|GAME_NCCH|GAME_EXEFS|GAME_ROMFS|SYS_FIRM)
|
#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)
|
#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 (GAME_NCSD|GAME_NCCH|GAME_TMD)
|
||||||
#define FTYPE_BUILDABLE_L (FTYPE_BUILDABLE&(GAME_TMD))
|
#define FTYPE_BUILDABLE_L (FTYPE_BUILDABLE&(GAME_TMD))
|
||||||
#define FTYPE_RESTORABLE (IMG_NAND)
|
#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);
|
u32 IdentifyFileType(const char* path);
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include "vcart.h"
|
#include "vcart.h"
|
||||||
#include "ncchinfo.h"
|
#include "ncchinfo.h"
|
||||||
#include "image.h"
|
#include "image.h"
|
||||||
|
#include "chainload.h"
|
||||||
|
|
||||||
#define N_PANES 2
|
#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 buildable_legit = (filetype & FTYPE_BUILDABLE_L);
|
||||||
bool restorable = (CheckA9lh() && (filetype & FTYPE_RESTORABLE) && !(drvtype & DRV_SYSNAND));
|
bool restorable = (CheckA9lh() && (filetype & FTYPE_RESTORABLE) && !(drvtype & DRV_SYSNAND));
|
||||||
bool xorpadable = (filetype & FTYPE_XORPAD);
|
bool xorpadable = (filetype & FTYPE_XORPAD);
|
||||||
|
bool launchable = ((filetype & FTYPE_PAYLOAD) && (drvtype & DRV_FAT));
|
||||||
bool special_opt = mountable || verificable || decryptable || decryptable_inplace ||
|
bool special_opt = mountable || verificable || decryptable || decryptable_inplace ||
|
||||||
buildable || buildable_legit || restorable || xorpadable;
|
buildable || buildable_legit || restorable || xorpadable || launchable;
|
||||||
|
|
||||||
char pathstr[32 + 1];
|
char pathstr[32 + 1];
|
||||||
TruncateString(pathstr, curr_entry->path, 32, 8);
|
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_ROMFS) ? "Mount as ROMFS image" :
|
||||||
(filetype == GAME_TMD) ? "TMD file options..." :
|
(filetype == GAME_TMD) ? "TMD file options..." :
|
||||||
(filetype == SYS_FIRM) ? "FIRM image 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[hexviewer-1] = "Show in Hexeditor";
|
||||||
optionstr[calcsha-1] = "Calculate SHA-256";
|
optionstr[calcsha-1] = "Calculate SHA-256";
|
||||||
if (copystd > 0) optionstr[copystd-1] = "Copy to " OUTPUT_PATH;
|
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 verify = (verificable) ? ++n_opt : -1;
|
||||||
int xorpad = (xorpadable) ? ++n_opt : -1;
|
int xorpad = (xorpadable) ? ++n_opt : -1;
|
||||||
int xorpad_inplace = (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 (mount > 0) optionstr[mount-1] = "Mount image to drive";
|
||||||
if (restore > 0) optionstr[restore-1] = "Restore SysNAND (safe)";
|
if (restore > 0) optionstr[restore-1] = "Restore SysNAND (safe)";
|
||||||
if (decrypt > 0) optionstr[decrypt-1] = "Decrypt file (SD output)";
|
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 (verify > 0) optionstr[verify-1] = "Verify file";
|
||||||
if (xorpad > 0) optionstr[xorpad-1] = "Build XORpads (SD output)";
|
if (xorpad > 0) optionstr[xorpad-1] = "Build XORpads (SD output)";
|
||||||
if (xorpad_inplace > 0) optionstr[xorpad_inplace-1] = "Build XORpads (inplace)";
|
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
|
// auto select when there is only one option
|
||||||
user_select = (n_opt > 1) ? (int) ShowSelectPrompt(n_opt, optionstr, pathstr) : n_opt;
|
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;
|
*scroll = 0;
|
||||||
*cursor = 1;
|
*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;
|
return 1;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user