random wip

This commit is contained in:
Maschell 2019-11-22 12:44:03 +01:00
parent a949308aee
commit 54779a371d
20 changed files with 878 additions and 7 deletions

2
.gitignore vendored
View File

@ -32,3 +32,5 @@
/ios_acp/*.elf
/ios_acp/ios_acp_syms.h
*.rpx
MochaLite.cscope_file_list
MochaLite.layout

View File

@ -120,7 +120,7 @@ $(BUILD): $(CURDIR)/ios_kernel/ios_kernel.bin.h
@[ -d $@ ] || mkdir -p $@
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
$(CURDIR)/ios_kernel/ios_kernel.bin.h: $(CURDIR)/ios_usb/ios_usb.bin.h $(CURDIR)/ios_mcp/ios_mcp.bin.h
$(CURDIR)/ios_kernel/ios_kernel.bin.h: $(CURDIR)/ios_usb/ios_usb.bin.h $(CURDIR)/ios_mcp/ios_mcp.bin.h $(CURDIR)/ios_acp/ios_acp.bin.h
@$(MAKE) --no-print-directory -C $(CURDIR)/ios_kernel -f $(CURDIR)/ios_kernel/Makefile
$(CURDIR)/ios_usb/ios_usb.bin.h:
@ -128,6 +128,9 @@ $(CURDIR)/ios_usb/ios_usb.bin.h:
$(CURDIR)/ios_mcp/ios_mcp.bin.h:
@$(MAKE) --no-print-directory -C $(CURDIR)/ios_mcp -f $(CURDIR)/ios_mcp/Makefile
$(CURDIR)/ios_acp/ios_acp.bin.h:
@$(MAKE) --no-print-directory -C $(CURDIR)/ios_acp -f $(CURDIR)/ios_acp/Makefile
#---------------------------------------------------------------------------------
clean:
@ -136,6 +139,7 @@ clean:
@$(MAKE) --no-print-directory -C $(CURDIR)/ios_kernel -f $(CURDIR)/ios_kernel/Makefile clean
@$(MAKE) --no-print-directory -C $(CURDIR)/ios_usb -f $(CURDIR)/ios_usb/Makefile clean
@$(MAKE) --no-print-directory -C $(CURDIR)/ios_mcp -f $(CURDIR)/ios_mcp/Makefile clean
@$(MAKE) --no-print-directory -C $(CURDIR)/ios_acp -f $(CURDIR)/ios_acp/Makefile clean
#---------------------------------------------------------------------------------

85
ios_acp/Makefile Normal file
View File

@ -0,0 +1,85 @@
ifeq ($(strip $(DEVKITARM)),)
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
endif
ifeq ($(filter $(DEVKITARM)/bin,$(PATH)),)
export PATH:=$(DEVKITARM)/bin:$(PATH)
endif
LOG_IP = 0xc0a80090
ifneq ($(LOG_IP),)
CFLAGS += -DLOG_IP=$(LOG_IP)
endif
CC = arm-none-eabi-gcc
LINK = arm-none-eabi-gcc
AS = arm-none-eabi-as
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
LIBS += -lgcc
CFILES = $(wildcard source/*.c)
BINFILES = $(wildcard data/*.bin)
OFILES = $(BINFILES:data/%.bin=build/%.bin.o)
OFILES += $(CFILES:source/%.c=build/%.o)
DFILES = $(CFILES:source/%.c=build/%.d)
SFILES = $(wildcard source/*.s)
OFILES += $(SFILES:source/%.s=build/%.o)
PROJECTNAME = ${shell basename "$(CURDIR)"}
CWD = "$(CURDIR)""
#---------------------------------------------------------------------------------
# canned command sequence for binary data, taken from devkitARM
#---------------------------------------------------------------------------------
define bin2o
bin2s $< | $(AS) -EB -o $(@)
endef
.PHONY:=all dirs
all: dirs $(PROJECTNAME).bin $(PROJECTNAME)_syms.h $(PROJECTNAME).bin $(PROJECTNAME).bin.h
dirs:
@mkdir -p build
$(PROJECTNAME).elf: $(OFILES)
@echo "LD $@"
@$(LINK) $(LDFLAGS) -o $(PROJECTNAME).elf $(sort $(filter-out build/crt0.o, $(OFILES))) $(LIBDIRS) $(LIBS)
$(PROJECTNAME).bin: $(PROJECTNAME).elf
@echo "OBJCOPY $@\n"
@$(OBJCOPY) -j .text -j .rodata -j .data -O binary $(PROJECTNAME).elf $@
$(PROJECTNAME).bin.h: $(PROJECTNAME).bin
@xxd -i $< | sed "s/unsigned/static const unsigned/g;s/$(PROJECTNAME)$*/$(PROJECTNAME)/g" > $@
$(PROJECTNAME)_syms.h:
@echo "#ifndef $(PROJECTNAME)_SYMS_H" > $@
@echo "#define $(PROJECTNAME)_SYMS_H" >> $@
@$(OBJDUMP) -EB -t -marm $(PROJECTNAME).elf | grep 'g F .text' | grep -v '.hidden' | awk '{print "#define " $$6 " 0x" $$1}' >> $@
@$(OBJDUMP) -EB -t -marm $(PROJECTNAME).elf | grep -e 'g .text' -e '_bss_' | awk '{print "#define " $$5 " 0x" $$1}' >> $@
@echo "#endif" >> $@
clean:
@rm -f build/*.o build/*.d
@rm -f $(PROJECTNAME).elf $(PROJECTNAME).bin $(PROJECTNAME)_syms.h $(PROJECTNAME).bin $(PROJECTNAME).bin.h
@echo "all cleaned up !"
-include $(DFILES)
build/%.o: source/%.c
@echo "CC $(notdir $<)"
@$(CC) $(CFLAGS) -c $< -o $@
@$(CC) -MM $< > build/$*.d
build/%.o: source/%.s
@echo "CC $(notdir $<)"
@$(CC) $(CFLAGS) -xassembler-with-cpp -c $< -o $@
@$(CC) -MM $< > build/$*.d
build/%.bin.o: data/%.bin
@echo "BIN $(notdir $<)"
@$(bin2o)

22
ios_acp/link.ld Normal file
View File

@ -0,0 +1,22 @@
OUTPUT_ARCH(arm)
SECTIONS
{
.text 0xE00DB660 : {
_text_start = .;
*(.text*)
*(.rodata*)
}
_text_end = .;
.bss 0xE0261F10 : {
_bss_start = .;
*(.bss*);
*(.data*);
}
_bss_end = .;
/DISCARD/ : {
*(*);
}
}

52
ios_acp/source/imports.c Normal file
View File

@ -0,0 +1,52 @@
#include "imports.h"
#include <stddef.h>
#include <stdint.h>
#include <stdarg.h>
void usleep(uint32_t time)
{
((void (*const)(uint32_t))0xe00d7ed4)(time);
}
void* memset(void* dst, int val, size_t size)
{
char* _dst = dst;
int i;
for(i = 0; i < size; i++) _dst[i] = val;
return dst;
}
void* (*const _memcpy)(void* dst, void* src, int size) = (void*)0xe00d6b78;
void* memcpy(void* dst, const void* src, size_t size)
{
return _memcpy(dst, (void*)src, size);
}
int strlen(const char* str)
{
unsigned int i = 0;
while (str[i]) {
i++;
}
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 vsnprintf(char * s, size_t n, const char * format, va_list arg)
{
return ((int (*const)(char*, size_t, const char *, va_list))0xe00d75f0)(s, n, format, arg);
}

7
ios_acp/source/imports.h Normal file
View File

@ -0,0 +1,7 @@
#ifndef _IMPORTS_H_
#define _IMPORTS_H_
#define ACP_SYSLOG_OUTPUT ((void (*)(const char *format, ...))0xE00C4D54)
#endif

View File

@ -0,0 +1,83 @@
#ifndef _IPC_TYPES_H_
#define _IPC_TYPES_H_
#include "types.h"
#define IOS_COMMAND_INVALID 0x00
#define IOS_OPEN 0x01
#define IOS_CLOSE 0x02
#define IOS_READ 0x03
#define IOS_WRITE 0x04
#define IOS_SEEK 0x05
#define IOS_IOCTL 0x06
#define IOS_IOCTLV 0x07
#define IOS_REPLY 0x08
#define IOS_IPC_MSG0 0x09
#define IOS_IPC_MSG1 0x0A
#define IOS_IPC_MSG2 0x0B
#define IOS_SUSPEND 0x0C
#define IOS_RESUME 0x0D
#define IOS_SVCMSG 0x0E
/* IPC message */
typedef struct ipcmessage
{
u32 command;
u32 result;
u32 fd;
u32 flags;
u32 client_cpu;
u32 client_pid;
u64 client_gid;
u32 server_handle;
union
{
u32 args[5];
struct
{
char *device;
u32 mode;
u32 resultfd;
} open;
struct
{
void *data;
u32 length;
} read, write;
struct
{
s32 offset;
s32 origin;
} seek;
struct
{
u32 command;
u32 *buffer_in;
u32 length_in;
u32 *buffer_io;
u32 length_io;
} ioctl;
struct _ioctlv
{
u32 command;
u32 num_in;
u32 num_io;
struct _ioctlv *vector;
} ioctlv;
};
u32 prev_command;
u32 prev_fd;
u32 virt0;
u32 virt1;
} __attribute__((packed)) ipcmessage;
#endif

188
ios_acp/source/main.c Normal file
View File

@ -0,0 +1,188 @@
/***************************************************************************
* Copyright (C) 2016
* by Dimok
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any
* damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any
* purpose, including commercial applications, and to alter it and
* redistribute it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you
* must not claim that you wrote the original software. If you use
* this software in a product, an acknowledgment in the product
* documentation would be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and
* must not be misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
***************************************************************************/
#include "types.h"
#include "imports.h"
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include "../../common/ipc_defs.h"
#include "svc.h"
#define DEBUG_FUNCTION_LINE(FMT, ARGS...)do { \
log_printf("[%23s]%30s@L%04d: " FMT "",__FILE__,__FUNCTION__, __LINE__, ## ARGS); \
} while (0)
static void* allocIobuf(int size) {
void* ptr = svcAlloc(0xCAFF, size);
memset(ptr, 0x00, size);
return ptr;
}
static void freeIobuf(void* ptr) {
svcFree(0xCAFF, ptr);
}
// probably painfully inefficient, but enough for debugging.
void log_printf(const char * format, ...) {
int fd = svcOpen("/dev/mcp", 0);
if(fd >= 0) {
u8* iobuf = allocIobuf(0x100 + 0x04 + 0x04); // str + command + out
if(iobuf != NULL) {
u32* inbuf = (u32*)iobuf;
u32* outbuf = (u32*)&iobuf[(0x100 + 0x04)]; // str + command
va_list args;
va_start(args, format);
inbuf[0] = IPC_CUSTOM_LOG_STRING; // set command
int len = vsnprintf((char *) &inbuf[0x04 / 0x04], 0x100, format, args);
if(len > 0) {
inbuf[len] = 0; // null terminator
svcIoctl(fd, 0x64, inbuf, 0x100 + 0x04, outbuf, 4);
}
va_end(args);
freeIobuf(iobuf);
}
svcClose(fd);
}
return;
}
bool isSwapRequired() {
int fd = svcOpen("/dev/mcp", 0);
int res = false;
if(fd >= 0) {
u8* iobuf = allocIobuf(0x08);
if(iobuf != NULL) {
u32* inbuf = (u32*)iobuf;
u32* outbuf = (u32*)&iobuf[0x04]; // command
inbuf[0] = IPC_CUSTOM_META_XML_SWAP_REQUIRED; // set command
svcIoctl(fd, 0x64, inbuf, 0x04, outbuf, 4);
if(outbuf[0] == 10) {
res = true;
}
freeIobuf(iobuf);
}
svcClose(fd);
}
return res;
}
bool getMetaXML(ACPMetaXml * ptr) {
int fd = svcOpen("/dev/mcp", 0);
int res = false;
if(fd >= 0) {
u8* iobuf = allocIobuf(0x04 + sizeof(ACPMetaXml));
if(iobuf != NULL) {
u32* inbuf = (u32*)iobuf;
u32* outbuf = (u32*)&iobuf[0x04]; // command
inbuf[0] = IPC_CUSTOM_META_XML_READ; // set command
memcpy(outbuf, ptr, sizeof(ACPMetaXml));
svcIoctl(fd, 0x64, inbuf, 0x04, outbuf, sizeof(ACPMetaXml));
memcpy(ptr,outbuf, sizeof(ACPMetaXml));
freeIobuf(iobuf);
}
svcClose(fd);
}
return res;
}
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);
}
}
}
}
int ACP_ParseMetaXML(ACPMetaXml *param_1,char *data,int filesize) {
int (*real_ACP_ParseMetaXML)(ACPMetaXml *param_1,char *data,int filesize) = (void*)0xe0012e38;
int res = real_ACP_ParseMetaXML(param_1,data,filesize);
return res;
}
int ACP_LoadMetaXmlFromPath(char * param_1,uint32_t param_2) {
int (*real_ACP_LoadMetaXmlFromPath)(char * param_1,uint32_t param_2) = (void*)0xe0029f1c;
int res = real_ACP_LoadMetaXmlFromPath(param_1,param_2);
ACPMetaXml *xml_data = (ACPMetaXml *) ((uint32_t)param_1 + 0xe8);
//DEBUG_FUNCTION_LINE("%08X %08X \n", param_1, param_2);
if(param_1 != NULL){
if(isSwapRequired()) {
getMetaXML(xml_data);
xml_data->e_manual = 0;
//DEBUG_FUNCTION_LINE("Do swap %s \n", xml_data->longname_en);
} else {
DEBUG_FUNCTION_LINE("We want no swap! %s\n", xml_data->longname_en);
}
}
return res;
}

32
ios_acp/source/svc.h Normal file
View File

@ -0,0 +1,32 @@
#ifndef SVC_H
#define SVC_H
#include "ipc_types.h"
typedef struct
{
void* ptr;
u32 len;
u32 unk;
}iovec_s;
void* svcAlloc(u32 heapid, u32 size);
void* svcAllocAlign(u32 heapid, u32 size, u32 align);
void svcFree(u32 heapid, void* ptr);
int svcOpen(char* name, int mode);
int svcClose(int fd);
int svcIoctl(int fd, u32 request, void* input_buffer, u32 input_buffer_len, void* output_buffer, u32 output_buffer_len);
int svcIoctlv(int fd, u32 request, u32 vector_count_in, u32 vector_count_out, iovec_s* vector);
int svcInvalidateDCache(void* address, u32 size);
int svcFlushDCache(void* address, u32 size);
int svcCreateThread(int (*callback)(void* arg), void* arg, u32* stack_top, u32 stacksize, int priority, int detached);
int svcStartThread(int threadId);
int svcCreateMessageQueue(u32 *ptr, u32 n_msgs);
int svcDestroyMessageQueue(int queueid);
int svcRegisterResourceManager(const char* device, int queueid);
int svcReceiveMessage(int queueid, ipcmessage ** ipc_buf, u32 flags);
int svcResourceReply(ipcmessage * ipc_message, u32 result);
int svcCustomKernelCommand(u32 command, ...);
#endif

105
ios_acp/source/svc.s Normal file
View File

@ -0,0 +1,105 @@
.section ".text"
.arm
.align 4
.global svcCreateThread
.type svcCreateThread, %function
svcCreateThread:
.word 0xE7F000F0
bx lr
.global svcStartThread
.type svcStartThread, %function
svcStartThread:
.word 0xE7F007F0
bx lr
.global svcCreateMessageQueue
.type svcCreateMessageQueue, %function
svcCreateMessageQueue:
.word 0xE7F00CF0
bx lr
.global svcDestroyMessageQueue
.type svcDestroyMessageQueue, %function
svcDestroyMessageQueue:
.word 0xE7F00DF0
bx lr
.global svcReceiveMessage
.type svcReceiveMessage, %function
svcReceiveMessage:
.word 0xE7F010F0
bx lr
.global svcAlloc
.type svcAlloc, %function
svcAlloc:
.word 0xE7F027F0
bx lr
.global svcAllocAlign
.type svcAllocAlign, %function
svcAllocAlign:
.word 0xE7F028F0
bx lr
.global svcFree
.type svcFree, %function
svcFree:
.word 0xE7F029F0
bx lr
.global svcRegisterResourceManager
.type svcRegisterResourceManager, %function
svcRegisterResourceManager:
.word 0xE7F02CF0
bx lr
.global svcOpen
.type svcOpen, %function
svcOpen:
.word 0xE7F033F0
bx lr
.global svcClose
.type svcClose, %function
svcClose:
.word 0xE7F034F0
bx lr
.global svcIoctl
.type svcIoctl, %function
svcIoctl:
.word 0xE7F038F0
bx lr
.global svcIoctlv
.type svcIoctlv, %function
svcIoctlv:
.word 0xE7F039F0
bx lr
.global svcResourceReply
.type svcResourceReply, %function
svcResourceReply:
.word 0xE7F049F0
bx lr
.global svcInvalidateDCache
.type svcInvalidateDCache, %function
svcInvalidateDCache:
.word 0xE7F051F0
bx lr
.global svcFlushDCache
.type svcFlushDCache, %function
svcFlushDCache:
.word 0xE7F052F0
bx lr
.global svcCustomKernelCommand
.type svcCustomKernelCommand, %function
svcCustomKernelCommand:
.word 0xE7F081F0
bx lr

29
ios_acp/source/types.h Normal file
View File

@ -0,0 +1,29 @@
#ifndef TYPES_H
#define TYPES_H
#include <stdint.h>
#include <stdbool.h>
#define U64_MAX UINT64_MAX
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;
typedef int8_t s8;
typedef int16_t s16;
typedef int32_t s32;
typedef int64_t s64;
typedef volatile u8 vu8;
typedef volatile u16 vu16;
typedef volatile u32 vu32;
typedef volatile u64 vu64;
typedef volatile s8 vs8;
typedef volatile s16 vs16;
typedef volatile s32 vs32;
typedef volatile s64 vs64;
#endif

View File

@ -0,0 +1,59 @@
/***************************************************************************
* Copyright (C) 2016
* by Dimok
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any
* damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any
* purpose, including commercial applications, and to alter it and
* redistribute it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you
* must not claim that you wrote the original software. If you use
* this software in a product, an acknowledgment in the product
* documentation would be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and
* must not be misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
***************************************************************************/
#include "types.h"
#include "elf_patcher.h"
#include "ios_acp_patches.h"
#include "../../ios_acp/ios_acp.bin.h"
#include "../../ios_acp/ios_acp_syms.h"
#define ACP_CODE_BASE_PHYS_ADDR (-0xE0000000 + 0x12900000)
extern const patch_table_t acp_patches_table[];
extern const patch_table_t acp_patches_table_end[];
u32 acp_get_phys_code_base(void) {
return _text_start + ACP_CODE_BASE_PHYS_ADDR;
}
void acp_run_patches(u32 ios_elf_start) {
section_write_bss(ios_elf_start, _bss_start, _bss_end - _bss_start);
section_write(ios_elf_start, _text_start, (void*)acp_get_phys_code_base(), _text_end - _text_start);
// hook main entry
//section_write_word(ios_elf_start, 0xe000fb98, ARM_BL(0xe000fb98, _mainHook));
// hook acp parse metafunction
//section_write_word(ios_elf_start, 0xe0013dec, ARM_BL(0xe0013dec, ACP_ParseMetaXML));
//section_write_word(ios_elf_start, 0xe0020234, ARM_BL(0xe0020234, ACP_ParseMetaXML));
//section_write_word(ios_elf_start, 0xe0015864, ARM_BL(0xe0015864, ACP_LoadMetaXmlFromPath));
//section_write_word(ios_elf_start, 0xe00159f8, ARM_BL(0xe00159f8, ACP_LoadMetaXmlFromPath));
//section_write_word(ios_elf_start, 0xe001a100, ARM_BL(0xe001a100, ACP_LoadMetaXmlFromPath));
//section_write_word(ios_elf_start, 0xe001cc68, ARM_BL(0xe001cc68, ACP_LoadMetaXmlFromPath));
//section_write_word(ios_elf_start, 0xe002a658, ARM_BL(0xe002a658, ACP_LoadMetaXmlFromPath));
//section_write_word(ios_elf_start, 0xe0032680, ARM_BL(0xe0032680, ACP_LoadMetaXmlFromPath));
//u32 patch_count = (u32)(((u8*)acp_patches_table_end) - ((u8*)acp_patches_table)) / sizeof(patch_table_t);
//patch_table_entries(ios_elf_start, acp_patches_table, patch_count);
}

View File

@ -0,0 +1,30 @@
/***************************************************************************
* Copyright (C) 2016
* by Dimok
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any
* damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any
* purpose, including commercial applications, and to alter it and
* redistribute it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you
* must not claim that you wrote the original software. If you use
* this software in a product, an acknowledgment in the product
* documentation would be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and
* must not be misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
***************************************************************************/
#ifndef _ACP_PATCHES_H_
#define _ACP_PATCHES_H_
u32 acp_get_phys_code_base(void);
void acp_run_patches(u32 ios_elf_start);
#endif

View File

@ -0,0 +1,11 @@
.arm
patch_wfs_partition_check:
mov r0, #0
.globl acp_patches_table, acp_patches_table_end
acp_patches_table:
# origin data size
#.word 0xE00605D0, patch_wfs_partition_check, 4
acp_patches_table_end:

View File

@ -44,7 +44,7 @@ void mcp_run_patches(u32 ios_elf_start)
section_write(ios_elf_start, _text_start, (void*)mcp_get_phys_code_base(), _text_end - _text_start);
section_write_word(ios_elf_start, 0x05056718, ARM_BL(0x05056718, _text_start));
section_write_word(ios_elf_start, 0x05002BBE, THUMB_BL(0x05002BBE, patch_SD_access_check));
u32 patch_count = (u32)(((u8*)mcp_patches_table_end) - ((u8*)mcp_patches_table)) / sizeof(patch_table_t);
@ -52,9 +52,21 @@ void mcp_run_patches(u32 ios_elf_start)
section_write_word(ios_elf_start, 0x050254D6, THUMB_BL(0x050254D6, MCP_LoadFile_patch));
section_write_word(ios_elf_start, 0x05025242, THUMB_BL(0x05025242, MCP_ioctl100_patch));
//section_write_word(ios_elf_start, 0x05025412, THUMB_BL(0x05025412, MCP_0x51_mcpSwitchTitle));
//section_write_word(ios_elf_start, 0x0502543e, THUMB_BL(0x0502543e, MCP_0x49_0x52_PrepareTitle)); // IOCTL 0x49
//section_write_word(ios_elf_start, 0x05025428, THUMB_BL(0x05025428, MCP_0x49_0x52_PrepareTitle)); // IOCTL 0x52
//section_write_word(ios_elf_start, 0x05028448, THUMB_BL(0x05028448, MCP_ioctl_proccess));
//section_write_word(ios_elf_start, 0x0501dd78, THUMB_BL(0x0501dd78, MCP_ReadCOSXml_patch));
//section_write_word(ios_elf_start, 0x051105ce, THUMB_BL(0x051105ce, MCP_ReadCOSXml_patch));
//section_write_word(ios_elf_start, 0x05101e3c, THUMB_BL(0x05101e3c, MCP_ReadAPPXml_patch));
//section_write_word(ios_elf_start, 0x0502b994, THUMB_BL(0x0502b994, MCP_ReadAPPXml_patch));
//section_write_word(ios_elf_start, 0x0502ba56, THUMB_BL(0x0502ba56, MCP_ReadAPPXml_patch));
//section_write_word(ios_elf_start, 0x05002520, THUMB_BL(0x05002520, MCP_ReadCOSXml2_patch));
// patch MCP syslogs
//section_write_word(ios_elf_start, 0x05055438, ARM_B(0x05055438, 0x0503DCF8));
//section_write_word(ios_elf_start, 0x05056C2C, ARM_B(0x05056C2C, 0x0503DCF8));
//section_write_word(ios_elf_start, 0x0500A4D2, THUMB_BL(0x0500A4D2, mcpThumb2ArmLog));
}

View File

@ -25,6 +25,7 @@
#include "../../common/kernel_commands.h"
#include "elf_patcher.h"
#include "ios_mcp_patches.h"
#include "ios_acp_patches.h"
#include "kernel_patches.h"
#include "exception_handler.h"
#include "fsa.h"
@ -95,7 +96,8 @@ void kernel_launch_ios(u32 launch_address, u32 L, u32 C, u32 H)
//! try to keep the order of virt. addresses to reduce the memmove amount
mcp_run_patches(ios_elf_start);
kernel_run_patches(ios_elf_start);
kernel_run_patches(ios_elf_start);
acp_run_patches(ios_elf_start);
restore_mmu(control_register);
enable_interrupts(level);

View File

@ -24,6 +24,7 @@
#include "types.h"
#include "utils.h"
#include "ios_mcp_patches.h"
#include "ios_acp_patches.h"
#include "instant_patches.h"
#define USB_PHYS_CODE_BASE 0x101312D0
@ -88,6 +89,8 @@ int _main()
payload_info_t *payloads = (payload_info_t*)0x00148000;
kernel_memcpy((void*)USB_PHYS_CODE_BASE, payloads->data, payloads->size);
payloads = (payload_info_t*)0x0014C000;
kernel_memcpy((void*)acp_get_phys_code_base(), payloads->data, payloads->size);
payloads = (payload_info_t*)0x00160000;
kernel_memcpy((void*)mcp_get_phys_code_base(), payloads->data, payloads->size);

View File

@ -30,7 +30,9 @@ int (*const MCP_UnknownStuff)(const char* path, uint32_t pos, void* outputBuffer
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 bool doWantReplaceXML = false;
static bool doWantReplaceRPX = false;
static bool skipNextCOSReplacement = false;
static bool replace_target_device = 0;
static bool rep_filesize = 0;
static bool rep_fileoffset = 0;
@ -86,7 +88,7 @@ int _MCP_LoadFile_patch(ipcmessage* msg) {
if(!doWantReplaceRPX) {
replace_path = "wiiu/apps/homebrew_launcher/homebrew_launcher.rpx";
replace_target = LOAD_FILE_TARGET_SD_CARD;
//doWantReplaceXML = false;
doWantReplaceXML = false;
doWantReplaceRPX = true;
replace_filesize = 0; // unknown
replace_fileoffset = 0;
@ -105,6 +107,7 @@ int _MCP_LoadFile_patch(ipcmessage* msg) {
return result;
} else {
// TODO, what happens if we already replaced the app/cos xml files and then the loading fails?
doWantReplaceXML = false; //if loading failed disabled meta loading.
}
}
}
@ -167,6 +170,93 @@ static int MCP_LoadCustomFile(int target, char* path, int filesize, int fileoffs
}
int _MCP_0x51_mcpSwitchTitle(ipcmessage* msg) {
int (*const real_0x51_mcpSwitchTitle)(ipcmessage* msg) = (void*)0x0501ce18 + 1; //+1 for thumb
if(msg->ioctl.buffer_in != NULL) {
if(msg->ioctl.length_in >= 0x74 + 0x08) {
uint64_t titleId = *((uint64_t*)&(msg->ioctl.buffer_in[0x74/0x04]));
//DEBUG_FUNCTION_LINE("Starting: %016llX\n",titleId);
if(titleId == 0x0005001010040200L || titleId == 0x0005001010040000L || titleId == 0x0005001010040100L) {
DEBUG_FUNCTION_LINE("Starting Wii U Menu, we don't replace XML files anymore.\n");
doWantReplaceXML = false;
}
}
}
int res = real_0x51_mcpSwitchTitle(msg);
return res;
}
int _MCP_ReadCOSXml_patch(uint32_t u1, uint32_t u2, MCPPPrepareTitleInfo * xmlData) {
int (*const real_MCP_ReadCOSXml_patch)(uint32_t u1, uint32_t u2, MCPPPrepareTitleInfo * xmlData) = (void*)0x050024ec + 1; //+1 for thumb
int res = real_MCP_ReadCOSXml_patch(u1,u2,xmlData);
if(doWantReplaceXML) {
DEBUG_FUNCTION_LINE("We would replace COS xml\n");
} else {
DEBUG_FUNCTION_LINE("We would NOT replace COS xml\n");
}
return res;
}
// 0x52 is calling the function with type = 1
// 0x49 is calling the function with type = 0
int _MCP_0x49_0x52_PrepareTitle(ipcmessage * ipc, uint32_t type) {
int (*const real_MCP_0x49_PrepareTitle)(ipcmessage * ipc, uint32_t type) = (void*)0x0501d9ec + 1; //+1 for thumb
int res = real_MCP_0x49_PrepareTitle(ipc,type);
if(doWantReplaceXML) {
DEBUG_FUNCTION_LINE("We would replace APP xml %d\n",type);
} else {
DEBUG_FUNCTION_LINE("We would NOT replace APP xml %d\n",type);
}
return res;
}
int _MCP_ioctl_proccess(ipcmessage * ipc) {
int (*const real_MCP_ioctl_proccess)(ipcmessage * ipc) = (void*)0x05024bf0 + 1; //+1 for thumb
int cmd = ipc->ioctl.command;
if(cmd!= 0x64 && cmd != 0x4C && cmd != 0x58) {
DEBUG_FUNCTION_LINE("Calling IOCTL_%04X \n", ipc->ioctl.command);
}
int res = real_MCP_ioctl_proccess(ipc);
if(cmd!= 0x64 && cmd != 0x4C && cmd != 0x58) {
DEBUG_FUNCTION_LINE("Calling IOCTL_%04X done \n", ipc->ioctl.command);
}
return res;
}
int _MCP_ReadAPPXml_patch(uint32_t u1,uint32_t u2,uint32_t u3) {
int (*const real_MCP_ReadAPPXml_patch)(uint32_t u1,uint32_t u2,uint32_t u3) = (void*)0x050021bc + 1; //+1 for thumb
//DEBUG_FUNCTION_LINE("%08X %08X %08X\n",u1,u2,u3);
int res = real_MCP_ReadAPPXml_patch(u1,u2,u3);
if(u3 != NULL) {
//dumpHex(u3, 0x100);
}
if(doWantReplaceXML) {
DEBUG_FUNCTION_LINE("We would replace APP xml\n");
} else {
DEBUG_FUNCTION_LINE("We would NOT replace APP xml\n");
}
return res;
}
/* 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) {
@ -193,12 +283,12 @@ int _MCP_ioctl100_patch(ipcmessage* msg) {
}
case IPC_CUSTOM_META_XML_SWAP_REQUIRED: {
//DEBUG_FUNCTION_LINE("IPC_CUSTOM_META_XML_SWAP_REQUIRED\n");
/*if(doWantReplaceXML) {
if(doWantReplaceXML) {
msg->ioctl.buffer_io[0] = 10;
} else {
msg->ioctl.buffer_io[0] = 11;
}
return 1;*/
return 1;
}
case IPC_CUSTOM_MEN_RPX_HOOK_COMPLETED: {
DEBUG_FUNCTION_LINE("IPC_CUSTOM_MEN_RPX_HOOK_COMPLETED\n");
@ -230,7 +320,7 @@ int _MCP_ioctl100_patch(ipcmessage* msg) {
rep_fileoffset = fileoffset;
didrpxfirstchunk = false;
doWantReplaceRPX = true;
//doWantReplaceXML = 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);
}

View File

@ -8,6 +8,56 @@ MCP_LoadFile_patch:
ldr r12, =_MCP_LoadFile_patch
bx r12
.extern _MCP_0x51_mcpSwitchTitle
.global MCP_0x51_mcpSwitchTitle
MCP_0x51_mcpSwitchTitle:
.thumb
bx pc
nop
.arm
ldr r12, =_MCP_0x51_mcpSwitchTitle
bx r12
.extern _MCP_ReadCOSXml_patch
.global MCP_ReadCOSXml_patch
MCP_ReadCOSXml_patch:
.thumb
bx pc
nop
.arm
ldr r12, =_MCP_ReadCOSXml_patch
bx r12
.extern _MCP_ReadAPPXml_patch
.global MCP_ReadAPPXml_patch
MCP_ReadAPPXml_patch:
.thumb
bx pc
nop
.arm
ldr r12, =_MCP_ReadAPPXml_patch
bx r12
.extern _MCP_ioctl_proccess
.global MCP_ioctl_proccess
MCP_ioctl_proccess:
.thumb
bx pc
nop
.arm
ldr r12, =_MCP_ioctl_proccess
bx r12
.extern _MCP_0x49_0x52_PrepareTitle
.global MCP_0x49_0x52_PrepareTitle
MCP_0x49_0x52_PrepareTitle:
.thumb
bx pc
nop
.arm
ldr r12, = _MCP_0x49_0x52_PrepareTitle
bx r12
.extern _MCP_ioctl100_patch
.global MCP_ioctl100_patch
MCP_ioctl100_patch:

View File

@ -33,6 +33,7 @@ typedef struct __attribute__((packed)) {
#include "../ios_kernel/ios_kernel.bin.h"
#include "../ios_usb/ios_usb.bin.h"
#include "../ios_mcp/ios_mcp.bin.h"
#include "../ios_acp/ios_acp.bin.h"
/* ROP CHAIN STARTS HERE (0x1015BD78) */
static const int final_chain[] = {
@ -321,6 +322,10 @@ static void uhs_exploit_init(int dev_uhs_0_handle) {
payloads->size = sizeof(ios_usb_bin);
memcpy(payloads->data, ios_usb_bin, payloads->size);
payloads = (payload_info_t*)0xF414C000;
payloads->size = sizeof(ios_acp_bin);
memcpy(payloads->data, ios_acp_bin, payloads->size);
payloads = (payload_info_t*)0xF4160000;
payloads->size = sizeof(ios_mcp_bin);
memcpy(payloads->data, ios_mcp_bin, payloads->size);