void _start() { asm( "lis %r1, 0x1ab5 ;" "ori %r1, %r1, 0xd138 ;" ); unsigned int coreinit_handle; OSDynLoad_Acquire("coreinit", &coreinit_handle); unsigned int(*MEMGetTotalFreeSizeForExpHeap)(void*expHeap); OSDynLoad_FindExport(coreinit_handle, 0, "MEMGetTotalFreeSizeForExpHeap", &MEMGetTotalFreeSizeForExpHeap); unsigned char *str; void *expHeap = (void*)0; float expSize = 0.f; /* this area appears semi-safe to search through */ for(str = (unsigned char*)0x15000000; str < (unsigned char*)0x25000000; str+=4) { if(*(unsigned int*)str == 0x45585048) { void *tmpHeap = str; float tmpSize = (float)MEMGetTotalFreeSizeForExpHeap(tmpHeap); if(tmpSize > expSize) { expHeap = tmpHeap; expSize = tmpSize; } } } if(expHeap != (void*)0) { char buf[64]; __os_snprintf(buf,64,"Biggest ExpHeap is %08x with %.2fMB left", expHeap, expSize/1024/1024); OSFatal(buf); } OSFatal("No Heaps found!"); }
void start() { asm("stwu %r1,-0x2000(%r1)"); unsigned int * start = (unsigned int*)BUFFER_ADDR; int i; for (i = 0; i < 150; start += 1) { if (*start == CODE_START) i++; } memcpy((void *)BUFFER_ADDR, (void *)BUFFER_ADDR + 0x800, 0x600); unsigned int * code_addr = (unsigned int *)(BUFFER_ADDR + 0x2C); unsigned int * code_addr_2 = (unsigned int *)(BUFFER_ADDR + 0x44); *code_addr = (int)start; *code_addr_2 = (int)start; asm( "lis %r1, 0x1dd7 ;" "ori %r1, %r1, 0xb814 ;" ); rop(); /* Debug printing */ char msg[255]; __os_snprintf(msg, 255, "0x%08x 0x%08x", *code_addr, start); OSFatal(msg); }
void start() { /* Set up a different stack */ asm("stwu %r1,-0x2000(%r1)"); /* Remove the OSPanic() callback */ unsigned int *ospanic_cb = (unsigned int*)OSPANIC_CB; ospanic_cb[0] = ospanic_cb[1] = 0; /* Copy another version of the ROP buffer over the original */ unsigned int *ropbuf = (unsigned int*)BUFFER_ADDR; memcpy(ropbuf, (void*)BUFFER_ADDR + 0x1000, 0x5c0); /* Look for the code buffer (checking the start, middle, and end) */ unsigned int *codebuf = (unsigned int*)BUFFER_ADDR; while (codebuf < (unsigned int*)0x20000000) { if (*codebuf == CODE_START && codebuf[0x4000/4] == ropbuf[0x190/4] && codebuf[0x7FFC/4] == ropbuf[0x194/4]) break; codebuf++; } if (codebuf == 0x20000000) OSFatal("Code not found"); /* Modify the ROP buffer to copy the code spray into the JIT */ ropbuf[0x318/4] = &ropbuf[0xa0/4]; ropbuf[0xdc/4] = codebuf + 1; ropbuf[0xe0/4] = 0x8000; /* Perform ROP again */ rop(BUFFER_ADDR + 0x30c); }
/* Start of our code */ void _start() { /* Load a good stack */ asm( "lis %r1, 0x1ab5 ;" "ori %r1, %r1, 0xd138 ;" ); /* Get a handle to coreinit.rpl */ unsigned int coreinit_handle; OSDynLoad_Acquire("coreinit.rpl", &coreinit_handle); /* OS memory allocation functions */ void* (*OSAllocFromSystem)(uint32_t size, int align); /* OS thread functions */ bool (*OSCreateThread)(void *thread, void *entry, int argc, void *args, uint32_t stack, uint32_t stack_size, int32_t priority, uint16_t attr); int32_t (*OSResumeThread)(void *thread); /* Exit function */ void (*_Exit)(); /* Read the addresses of the functions */ OSDynLoad_FindExport(coreinit_handle, 0, "OSAllocFromSystem", &OSAllocFromSystem); OSDynLoad_FindExport(coreinit_handle, 0, "OSCreateThread", &OSCreateThread); OSDynLoad_FindExport(coreinit_handle, 0, "OSResumeThread", &OSResumeThread); OSDynLoad_FindExport(coreinit_handle, 0, "_Exit", &_Exit); /* Create a string argument */ char *str = OSAllocFromSystem(6, 1); str[0] = 'H'; str[1] = 'e'; str[2] = 'l'; str[3] = 'l'; str[4] = 'o'; str[5] = 0; /* Allocate a stack for the thread */ uint32_t stack = (uint32_t) OSAllocFromSystem(0x1000, 0x10); stack += 0x1000; /* Create the thread */ void *thread = OSAllocFromSystem(OSTHREAD_SIZE, 8); bool ret = OSCreateThread(thread, OSFatal, (int)str, null, stack, 0x1000, 0, 1); if (ret == false) { OSFatal("Failed to create thread"); } /* Schedule it for execution */ OSResumeThread(thread); /* Infinite loop */ while(1); }
void _start() { /* Load a good stack */ asm( "lis %r1, 0x1ab5 ;" "ori %r1, %r1, 0xd138 ;" ); /* Get a handle to coreinit.rpl */ uint32_t coreinit_h; OSDynLoad_Acquire("coreinit.rpl", &coreinit_h); /* Memory allocation and FS functions */ void* (*OSAllocFromSystem)(uint32_t size, int align); int (*FSInit)(); int (*FSAddClient)(void *client, int unk1); int (*FSInitCmdBlock)(void *cmd); int (*FSOpenDir)(void *client, void *cmd, char *path, uint32_t *dir_handle, int unk1); int (*FSReadDir)(void *client, void *cmd, uint32_t dir_handle, void *buffer, int unk1); int (*FSGetMountSource)(void *client, void *cmd, int type, mount_source *source, int unk1); int (*FSMount)(void *client, void *cmd, mount_source *source, char *mountpath, uint32_t pathlength, int unk1); int (*FSOpenFile)(void *client, void *cmd, char *filepath, char *amode, uint32_t *file_handle, int unk1); int (*FSReadFile)(void *client, void *cmd, void *buffer, uint32_t size, uint32_t length, uint32_t file_handle, int unk1, int unk2); OSDynLoad_FindExport(coreinit_h, 0, "OSAllocFromSystem", &OSAllocFromSystem); OSDynLoad_FindExport(coreinit_h, 0, "FSInit", &FSInit); OSDynLoad_FindExport(coreinit_h, 0, "FSAddClient", &FSAddClient); OSDynLoad_FindExport(coreinit_h, 0, "FSInitCmdBlock", &FSInitCmdBlock); OSDynLoad_FindExport(coreinit_h, 0, "FSOpenDir", &FSOpenDir); OSDynLoad_FindExport(coreinit_h, 0, "FSReadDir", &FSReadDir); OSDynLoad_FindExport(coreinit_h, 0, "FSGetMountSource", &FSGetMountSource); OSDynLoad_FindExport(coreinit_h, 0, "FSMount", &FSMount); OSDynLoad_FindExport(coreinit_h, 0, "FSOpenFile", &FSOpenFile); OSDynLoad_FindExport(coreinit_h, 0, "FSReadFile", &FSReadFile); FSInit(); /* Set up the client and command blocks */ void *client = OSAllocFromSystem(0x1700, 0x20); void *cmd = OSAllocFromSystem(0xA80, 0x20); if (!(client && cmd)) OSFatal("Failed to allocate client and command block"); FSAddClient(client, 0); FSInitCmdBlock(cmd); // todo: check permissions and throw exception if no mounting permissions available // OSLockMutex - Probably not. It's a single thread, nothing else can access this, Cross-F does this here mount_source m_source; // allocate mount source int ms_result = FSGetMountSource(client, cmd, 0, &m_source, 0); // type 0 = external device if(ms_result != 0) { char buf[256]; __os_snprintf(buf, 256, "FSGetMountSource returned error code %d", ms_result); OSFatal(buf); } char mountPath[128]; // usually /vol/external01 int m_result = FSMount(client, cmd, &m_source, mountPath, sizeof(mountPath), -1); if(m_result != 0) { char buf[256]; __os_snprintf(buf, 256, "FSMount returned error code %d", m_result); OSFatal(buf); } // OSUnlockMutex char defaultMountPath[] = "/vol/external01"; if(!strcmp(mountPath, defaultMountPath)) { char buf[256]; __os_snprintf(buf, 256, "FSMount returned nonstandard mount path: %s", mountPath); OSFatal(buf); } uint32_t file_handle; int open_result = FSOpenFile(client, cmd, "/vol/external01/SMASHD.txt", "r", &file_handle, 0); if(open_result != 0) { char buf[256]; __os_snprintf(buf, 256, "FSOpenFile returned error code %d", open_result); OSFatal(buf); } uint32_t *file_buffer = OSAllocFromSystem(0x200, 0x20); int read_result = FSReadFile(client, cmd, file_buffer, 1, 25, file_handle, 0, -1); // todo: is size correct? one char one byte; read whole file, not just a few bytes if(read_result != 0) { char buf[256]; __os_snprintf(buf, 256, "FSReadFile returned error code %d", read_result); OSFatal(buf); } char *message = (char*)&file_buffer[25]; OSFatal(message); }
void _start() { /* Load a good stack */ asm( "lis %r1, 0x1ab5 ;" "ori %r1, %r1, 0xd138 ;" ); /* Get a handle to coreinit.rpl, dmae.rpl, and nsysnet.rpl */ unsigned int coreinit_handle, dmae_handle, nsysnet_handle; OSDynLoad_Acquire("coreinit.rpl", &coreinit_handle); OSDynLoad_Acquire("dmae.rpl", &dmae_handle); OSDynLoad_Acquire("nsysnet.rpl", &nsysnet_handle); /* Cache, DMA, and socket functions */ void (*DCFlushRange)(void *addr, unsigned int length); void (*DCInvalidateRange)(void *addr, unsigned int length); unsigned long long (*DMAECopyMem)(void *dst, void *src, unsigned int nwords, int endian); int (*DMAEWaitDone)(unsigned long long ret); int (*socket)(int family, int type, int proto); int (*connect)(int fd, struct sockaddr *addr, int addrlen); int (*send)(int fd, const void *buffer, int len, int flags); /* Read the addresses of the functions */ OSDynLoad_FindExport(coreinit_handle, 0, "DCFlushRange", &DCFlushRange); OSDynLoad_FindExport(coreinit_handle, 0, "DCInvalidateRange", &DCInvalidateRange); OSDynLoad_FindExport(dmae_handle, 0, "DMAECopyMem", &DMAECopyMem); OSDynLoad_FindExport(dmae_handle, 0, "DMAEWaitDone", &DMAEWaitDone); OSDynLoad_FindExport(nsysnet_handle, 0, "socket", &socket); OSDynLoad_FindExport(nsysnet_handle, 0, "connect", &connect); OSDynLoad_FindExport(nsysnet_handle, 0, "send", &send); /* Set up our socket address structure */ struct sockaddr sin; sin.sin_family = AF_INET; sin.sin_port = 12345; sin.sin_addr.s_addr = PC_IP; int i; for (i = 0; i < 8; i++) { sin.sin_zero[i] = 0; } /* Connect to the PC */ int pc = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); int status = connect(pc, &sin, 0x10); if (status) OSFatal("Error connecting to PC server"); /* Cache stuff */ DCFlushRange(0x01000000, 0x20); DCInvalidateRange(0x1dd7b820, 0x20); /* Do the copy */ int success = DMAEWaitDone(DMAECopyMem(0x1dd7b820, 0x01000000, 2, 0)); if (success) { send(pc, "Success", 8, 0); } else { send(pc, "Fail", 5, 0); } while(1); }
void _start() { /* Get a handle to coreinit.rpl */ unsigned int coreinit_handle; OSDynLoad_Acquire("coreinit.rpl", &coreinit_handle); //OS memory functions void* (*memcpy)(void *dest, void *src, uint32_t length); void* (*memset)(void * dest, uint32_t value, uint32_t bytes); void* (*OSAllocFromSystem)(uint32_t size, int align); void (*OSFreeToSystem)(void *ptr); OSDynLoad_FindExport(coreinit_handle, 0, "memcpy", &memcpy); OSDynLoad_FindExport(coreinit_handle, 0, "memset", &memset); OSDynLoad_FindExport(coreinit_handle, 0, "OSAllocFromSystem", &OSAllocFromSystem); OSDynLoad_FindExport(coreinit_handle, 0, "OSFreeToSystem", &OSFreeToSystem); void (*OSCoherencyBarrier)(); OSDynLoad_FindExport(coreinit_handle, 0, "OSCoherencyBarrier", &OSCoherencyBarrier); void (*_Exit)(); OSDynLoad_FindExport(coreinit_handle, 0, "_Exit", &_Exit); //DC memory functions void (*DCFlushRangeNoSync)(void *buffer, uint32_t length); void (*DCInvalidateRange)(void *buffer, uint32_t length); OSDynLoad_FindExport(coreinit_handle, 0, "DCFlushRangeNoSync", &DCFlushRangeNoSync); OSDynLoad_FindExport(coreinit_handle, 0, "DCInvalidateRange", &DCInvalidateRange); //LC memory functions void* (*LCAlloc)( uint32_t bytes ); void (*LCDealloc)(); uint32_t (*LCHardwareIsAvailable)(); uint32_t (*LCIsDMAEnabled)(); void (*LCEnableDMA)(); void (*LCDisableDMA)(); void (*LCLoadDMABlocks)(void* lc_addr, void* src_addr, uint32_t blocks); void (*LCStoreDMABlocks)(void* dest_addr, void* lc_addr, uint32_t blocks); void (*LCWaitDMAQueue)( uint32_t length ); OSDynLoad_FindExport(coreinit_handle, 0, "LCAlloc", &LCAlloc); OSDynLoad_FindExport(coreinit_handle, 0, "LCDealloc", &LCDealloc); OSDynLoad_FindExport(coreinit_handle, 0, "LCHardwareIsAvailable", &LCHardwareIsAvailable); OSDynLoad_FindExport(coreinit_handle, 0, "LCIsDMAEnabled", &LCIsDMAEnabled); OSDynLoad_FindExport(coreinit_handle, 0, "LCEnableDMA", &LCEnableDMA); OSDynLoad_FindExport(coreinit_handle, 0, "LCDisableDMA", &LCDisableDMA); OSDynLoad_FindExport(coreinit_handle, 0, "LCLoadDMABlocks", &LCLoadDMABlocks); OSDynLoad_FindExport(coreinit_handle, 0, "LCStoreDMABlocks", &LCStoreDMABlocks); OSDynLoad_FindExport(coreinit_handle, 0, "LCWaitDMAQueue", &LCWaitDMAQueue); //Used for keeping track of vairables to print to screen char output[1000]; //Alloc 64 byte alligned space void* src_addr=OSAllocFromSystem(512,64); void* dest_addr=OSAllocFromSystem(512,64); //Store some debug values __os_snprintf(output, 1000, "src_addr:%02x,",(uint32_t)src_addr); __os_snprintf(output+strlen(output), 255, "dest_addr: %02x,", (uint32_t)dest_addr); //Number of 32bit blocks to copy. Must be multiple of 2 between [0,127] uint32_t blocks=2; //2 32bit blocks //Do something to the source memset(src_addr,1,64); //Grab values for debug uint32_t * src_val=src_addr; uint32_t * dest_val=dest_addr; __os_snprintf(output+strlen(output), 255, "Old src_val: %02x\n",src_val[0]); __os_snprintf(output+strlen(output), 255, "Old dest_val: %02x,",dest_val[0]); //Get some locked cache address space void *lc_addr=LCAlloc(512); //512 Minmum. Must be multiple of 512. //Calculate size from blocks to flush/invalidate range properly uint32_t size; //If blocks is set to 0, the transaction will default to 128 blocks if(blocks==0) { size=32*128; } else { size=32*blocks; } //Flush the range at the source to ensure cache gets written back to memory. DCFlushRangeNoSync(src_addr,size); //Invalidate the range at the destination DCInvalidateRange(dest_addr,size); //Sync OSCoherencyBarrier(); //Check to see of DMA hardware is avaliable if(LCHardwareIsAvailable()!=1) { OSFatal("Hardware is not avaliable."); } //Gets the current state of DMA, so we can restore it after our copy uint32_t dmaState=LCIsDMAEnabled(); //Checks to see if DMA is enabled, if not it will try to enable it. if(dmaState!=1) { LCEnableDMA(); dmaState=LCIsDMAEnabled(); if(dmaState!=1) { OSFatal("Can't enable DMA"); } } //Load memory to locked cache LCLoadDMABlocks(lc_addr,src_addr,blocks); LCWaitDMAQueue(0); //Store memory from locked cache LCStoreDMABlocks(dest_addr,lc_addr,blocks); LCWaitDMAQueue(0); //If DMA was not previously enabled, then disable it to restore state. if(dmaState!=1) { LCDisableDMA(); dmaState=LCIsDMAEnabled(); //If DMA failed to disable, return error code if(dmaState!=1) { OSFatal("Couldn't Disable DMA"); } } __os_snprintf(output+strlen(output), 255, "New src_val: %02x,",src_val[0]); __os_snprintf(output+strlen(output), 255, "New dest_val: %02x,",dest_val[0]); //Cleanup LCDealloc(lc_addr); OSFreeToSystem(dest_addr); OSFreeToSystem(src_addr); OSFatal(output); }
int main(int argc, char **argv) { OSFatal("my first rpx"); return 0; }
extern "C" int32_t Menu_Main(int32_t argc, char **argv) { if(gAppStatus == 2) { //"No, we don't want to patch stuff again."); return EXIT_RELAUNCH_ON_LOAD; } InitOSFunctionPointers(); InitSocketFunctionPointers(); //For logging InitSysFunctionPointers(); InitFSFunctionPointers(); InitGX2FunctionPointers(); InitSysFunctionPointers(); InitVPadFunctionPointers(); InitPadScoreFunctionPointers(); InitAXFunctionPointers(); InitProcUIFunctionPointers(); log_init(); DEBUG_FUNCTION_LINE("We have %d kb for plugins.\n",(PLUGIN_LOCATION_END_ADDRESS-getApplicationEndAddr())/1024); //setup_os_exceptions(); DEBUG_FUNCTION_LINE("Wii U Plugin System Loader %s\n",APP_VERSION); DEBUG_FUNCTION_LINE("Sizeof dyn_linking_relocation_data_t %d\n",sizeof(dyn_linking_relocation_data_t)); Init(); init_kernel_syscalls(); wups_init_kernel_syscalls(); gGameTitleID = OSGetTitleID(); int32_t result = 0; //Reset everything when were going back to the Mii Maker if(isInMiiMakerHBL()) { CallHook(WUPS_LOADER_HOOK_DEINIT_PLUGIN); // Restore patches as the patched functions could change. RestorePatches(); DynamicLinkingHelper::getInstance()->clearAll(); //PluginLoader * pluginLoader = PluginLoader::getInstance(); //std::vector<PluginInformation *> pluginList = pluginLoader->getPluginInformation("sd:/wiiu/plugins/"); //pluginLoader->loadAndLinkPlugins(pluginList); //pluginLoader->clearPluginInformation(pluginList); //!******************************************************************* //! Initialize heap memory * //!******************************************************************* DEBUG_FUNCTION_LINE("Initialize memory management\n"); memoryInitialize(); DEBUG_FUNCTION_LINE("Start main application\n"); result = Application::instance()->exec(); DEBUG_FUNCTION_LINE("Main application stopped result: %d\n",result); DEBUG_FUNCTION_LINE("Application::destroyInstance\n"); Application::destroyInstance(); DEBUG_FUNCTION_LINE("Release memory\n"); memoryRelease(); CSettings::destroyInstance(); PluginLoader::destroyInstance(); } if(result == APPLICATION_CLOSE_APPLY_MEMORY) { if(!MemoryMapping::isMemoryMapped()) { MemoryMapping::setupMemoryMapping(); } } DEBUG_FUNCTION_LINE("Do relocations\n"); std::vector<dyn_linking_relocation_entry_t *> relocations = DynamicLinkingHelper::getInstance()->getAllValidDynamicLinkingRelocations(); DEBUG_FUNCTION_LINE("Found relocation information for %d functions\n",relocations.size()); if(!DynamicLinkingHelper::getInstance()->fillRelocations(relocations)) { OSFatal("fillRelocations failed."); } if(!isInMiiMakerHBL()) { DEBUG_FUNCTION_LINE("Apply patches.\n"); ApplyPatchesAndCallHookStartingApp(); ConfigUtils::loadConfigFromSD(); if(MemoryMapping::isMemoryMapped()) { DEBUG_FUNCTION_LINE("Mapping was already done. Running %016llX\n",gGameTitleID); readAndPrintSegmentRegister(NULL,NULL); MemoryMapping::readTestValuesFromMemory(); } else { DEBUG_FUNCTION_LINE("<-----------------------------------------------------> \n"); DEBUG_FUNCTION_LINE("<---------------- COPY PASTE ME START-----------------> \n"); DEBUG_FUNCTION_LINE("<-----------------------------------------------------> \n"); DEBUG_FUNCTION_LINE("Mapping was't done. Running %016llX\n",gGameTitleID); readAndPrintSegmentRegister(NULL,NULL); DEBUG_FUNCTION_LINE("<-----------------------------------------------------> \n"); DEBUG_FUNCTION_LINE("<----------------- COPY PASTE ME END -----------------> \n"); DEBUG_FUNCTION_LINE("<-----------------------------------------------------> \n"); } return EXIT_RELAUNCH_ON_LOAD; } if(result == APPLICATION_CLOSE_APPLY || result == APPLICATION_CLOSE_APPLY_MEMORY) { CallHook(WUPS_LOADER_HOOK_INIT_KERNEL); CallHook(WUPS_LOADER_HOOK_INIT_FS); CallHook(WUPS_LOADER_HOOK_INIT_OVERLAY); CallHook(WUPS_LOADER_HOOK_INIT_PLUGIN); DEBUG_FUNCTION_LINE("Loading the system menu.\n"); DeInit(); SYSLaunchMenu(); return EXIT_RELAUNCH_ON_LOAD; } DEBUG_FUNCTION_LINE("Let's go to back to the Homebrew Launcher\n"); DEBUG_FUNCTION_LINE("Restoring the patched functions\n"); RestorePatches(); DEBUG_FUNCTION_LINE("Calling the plugin deinit hook\n"); CallHook(WUPS_LOADER_HOOK_DEINIT_PLUGIN); DEBUG_FUNCTION_LINE("Unmounting SD/USB devices\n"); DeInit(); DEBUG_FUNCTION_LINE("Bye bye!\n"); return EXIT_SUCCESS; }
/* Install an exception handler */ int _start(int argc, char **argv) { /* Get a handle to coreinit.rpl and nsysnet.rpl */ unsigned int coreinit_handle, nsysnet_handle; OSDynLoad_Acquire("coreinit.rpl", &coreinit_handle); OSDynLoad_Acquire("nsysnet.rpl", &nsysnet_handle); /* Memory and cache functions */ unsigned int (*OSEffectiveToPhysical)(void *ptr); void (*DCFlushRange)(void *addr, unsigned int len); void (*DCInvalidateRange)(void *addr, unsigned int len); OSDynLoad_FindExport(coreinit_handle, 0, "OSEffectiveToPhysical", &OSEffectiveToPhysical); OSDynLoad_FindExport(coreinit_handle, 0, "DCFlushRange", &DCFlushRange); OSDynLoad_FindExport(coreinit_handle, 0, "DCInvalidateRange", &DCInvalidateRange); /* Kernel is mapped */ if (OSEffectiveToPhysical((void*)0xA0000000) == 0xC0000000) { /* Patches installed */ if (*((unsigned int*)(0xA0000000 + (0xFFF00B40 - 0xC0000000))) == 1) { /* Socket functions */ int (*socket_lib_init)(); int (*get_socket_rm_fd)(); int (*socket)(int family, int type, int proto); int (*connect)(int fd, struct sockaddr *addr, int addrlen); OSDynLoad_FindExport(nsysnet_handle, 0, "socket_lib_init", &socket_lib_init); OSDynLoad_FindExport(nsysnet_handle, 0, "get_socket_rm_fd", &get_socket_rm_fd); OSDynLoad_FindExport(nsysnet_handle, 0, "socket", &socket); OSDynLoad_FindExport(nsysnet_handle, 0, "connect", &connect); /* Init the sockets library */ socket_lib_init(); /* Set up our socket address structure */ struct sockaddr sin; sin.sin_family = AF_INET; sin.sin_port = 12345; sin.sin_addr.s_addr = PC_IP; int i; for (i = 0; i < 8; i++) { sin.sin_zero[i] = 0; } /* Connect to the PC */ int pc = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); int status = connect(pc, &sin, 0x10); if (status) OSFatal("Error connecting to PC"); /* Store the socket info in a place the kernel can access */ unsigned int sock_info[4] = {1, (unsigned int)get_socket_rm_fd(), (unsigned int)pc, 0}; memcpy((void*)(0xA0000000 + (0xFFF00B40 - 0xC0000000)), sock_info, 0x10); DCFlushRange((void*)(0xA0000000 + (0xFFF00B40 - 0xC0000000)), 0x20); DCInvalidateRange((void*)(0xA0000000 + (0xFFF00B40 - 0xC0000000)), 0x20); } /* Patches not yet installed, but they will be next time */ else { /* Signify patches installed, socket data still invalid, spinlock 0 */ *((unsigned int*)(0xA0000000 + (0xFFF00B40 - 0xC0000000))) = 1; *((unsigned int*)(0xA0000000 + (0xFFF00B44 - 0xC0000000))) = -1; *((unsigned int*)(0xA0000000 + (0xFFF00B48 - 0xC0000000))) = -1; *((unsigned int*)(0xA0000000 + (0xFFF00B4C - 0xC0000000))) = 0; DCFlushRange((void*)(0xA0000000 + (0xFFF00B40 - 0xC0000000)), 0x20); DCInvalidateRange((void*)(0xA0000000 + (0xFFF00B40 - 0xC0000000)), 0x20); } } /* Return to main() */ #if VER == 532 int (*main)(int argc, char **argv) = (int (*)(int,char**)) (*((unsigned int*)0x1005D180)); #elif VER == 550 int (*main)(int argc, char **argv) = (int (*)(int,char**)) (*((unsigned int*)0x1005E040)); #else int (*main)(int argc, char **argv) = (int (*)(int,char**)) (*((unsigned int*)0x0)); #endif return main(argc, argv); }
/* Callback for UHS event wait */ static void uhs_event_cb(int status, void *context) { OSFatal("Event"); }
void InitOSFunctionPointers(void) { unsigned int *funcPointer = 0; //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- //! Lib handle functions //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- EXPORT_FUNC_WRITE(OSDynLoad_Acquire, (int (*)(const char*, unsigned *))OS_SPECIFICS->addr_OSDynLoad_Acquire); EXPORT_FUNC_WRITE(OSDynLoad_FindExport, (int (*)(u32, int, const char *, void *))OS_SPECIFICS->addr_OSDynLoad_FindExport); OSDynLoad_Acquire("coreinit.rpl", &coreinit_handle); //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- //! System functions //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- OS_FIND_EXPORT(coreinit_handle, OSFatal); OS_FIND_EXPORT(coreinit_handle, OSGetTitleID); OS_FIND_EXPORT(coreinit_handle, OSSetExceptionCallback); OS_FIND_EXPORT(coreinit_handle, DCFlushRange); OS_FIND_EXPORT(coreinit_handle, ICInvalidateRange); OS_FIND_EXPORT(coreinit_handle, OSEffectiveToPhysical); OS_FIND_EXPORT(coreinit_handle, __os_snprintf); OS_FIND_EXPORT(coreinit_handle, __gh_errno_ptr); OSDynLoad_FindExport(coreinit_handle, 0, "_Exit", &__Exit); //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- //! Thread functions //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- OS_FIND_EXPORT(coreinit_handle, OSCreateThread); OS_FIND_EXPORT(coreinit_handle, OSResumeThread); OS_FIND_EXPORT(coreinit_handle, OSSuspendThread); OS_FIND_EXPORT(coreinit_handle, OSIsThreadTerminated); OS_FIND_EXPORT(coreinit_handle, OSIsThreadSuspended); OS_FIND_EXPORT(coreinit_handle, OSJoinThread); OS_FIND_EXPORT(coreinit_handle, OSSetThreadPriority); OS_FIND_EXPORT(coreinit_handle, OSDetachThread); OS_FIND_EXPORT(coreinit_handle, OSSleepTicks); //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- //! Mutex functions //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- OS_FIND_EXPORT(coreinit_handle, OSInitMutex); OS_FIND_EXPORT(coreinit_handle, OSLockMutex); OS_FIND_EXPORT(coreinit_handle, OSUnlockMutex); OS_FIND_EXPORT(coreinit_handle, OSTryLockMutex); //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- //! Memory functions //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- OSDynLoad_FindExport(coreinit_handle, 1, "MEMAllocFromDefaultHeapEx", &pMEMAllocFromDefaultHeapEx); OSDynLoad_FindExport(coreinit_handle, 1, "MEMAllocFromDefaultHeap", &pMEMAllocFromDefaultHeap); OSDynLoad_FindExport(coreinit_handle, 1, "MEMFreeToDefaultHeap", &pMEMFreeToDefaultHeap); OS_FIND_EXPORT(coreinit_handle, MEMGetBaseHeapHandle); OS_FIND_EXPORT(coreinit_handle, MEMGetAllocatableSizeForFrmHeapEx); OS_FIND_EXPORT(coreinit_handle, MEMAllocFromFrmHeapEx); OS_FIND_EXPORT(coreinit_handle, MEMFreeToFrmHeap); OS_FIND_EXPORT(coreinit_handle, MEMAllocFromExpHeapEx); OS_FIND_EXPORT(coreinit_handle, MEMCreateExpHeapEx); OS_FIND_EXPORT(coreinit_handle, MEMDestroyExpHeap); OS_FIND_EXPORT(coreinit_handle, MEMFreeToExpHeap); //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- //! Special non library functions //!---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- if(OS_FIRMWARE == 550) { EXPORT_FUNC_WRITE(LiWaitIopComplete, (int (*)(int, int *))0x01010180); EXPORT_FUNC_WRITE(LiWaitIopCompleteWithInterrupts, (int (*)(int, int *))0x0101006C); EXPORT_FUNC_WRITE(addr_LiWaitOneChunk, (int (*)(int, int *))0x0100080C); EXPORT_FUNC_WRITE(addr_PrepareTitle_hook, (int (*)(int, int *))0xFFF184E4); } else if(OS_FIRMWARE == 532 || OS_FIRMWARE == 540) { EXPORT_FUNC_WRITE(LiWaitIopComplete, (int (*)(int, int *))0x0100FFA4); // loader.elf EXPORT_FUNC_WRITE(LiWaitIopCompleteWithInterrupts, (int (*)(int, int *))0x0100FE90); // loader.elf EXPORT_FUNC_WRITE(addr_LiWaitOneChunk, (int (*)(int, int *))0x010007EC); // loader.elf EXPORT_FUNC_WRITE(addr_PrepareTitle_hook, (int (*)(int, int *))0xFFF18558); // kernel.elf EXPORT_FUNC_WRITE(addr_sgIsLoadingBuffer, (int (*)(int, int *))0xEFE19D00); // loader.elf EXPORT_FUNC_WRITE(addr_gDynloadInitialized, (int (*)(int, int *))0xEFE13C3C); // loader.elf } else if(OS_FIRMWARE == 500 || OS_FIRMWARE == 510) { EXPORT_FUNC_WRITE(LiWaitIopComplete, (int (*)(int, int *))0x0100FBC4); EXPORT_FUNC_WRITE(LiWaitIopCompleteWithInterrupts, (int (*)(int, int *))0x0100FAB0); EXPORT_FUNC_WRITE(addr_LiWaitOneChunk, (int (*)(int, int *))0x010007EC); EXPORT_FUNC_WRITE(addr_PrepareTitle_hook, (int (*)(int, int *))0xFFF18534); EXPORT_FUNC_WRITE(addr_sgIsLoadingBuffer, (int (*)(int, int *))0xEFE19D00); EXPORT_FUNC_WRITE(addr_gDynloadInitialized, (int (*)(int, int *))0xEFE13C3C); } else if(OS_FIRMWARE == 410) { EXPORT_FUNC_WRITE(LiWaitIopComplete, (int (*)(int, int *))0x0100F78C); EXPORT_FUNC_WRITE(LiWaitIopCompleteWithInterrupts, (int (*)(int, int *))0x0100F678); EXPORT_FUNC_WRITE(addr_LiWaitOneChunk, (int (*)(int, int *))0x010007F8); EXPORT_FUNC_WRITE(addr_PrepareTitle_hook, (int (*)(int, int *))0xFFF166DC); EXPORT_FUNC_WRITE(addr_sgIsLoadingBuffer, (int (*)(int, int *))0xEFE19CC0); EXPORT_FUNC_WRITE(addr_gDynloadInitialized, (int (*)(int, int *))0xEFE13BFC); } else if(OS_FIRMWARE == 400) // same for 4.0.2 and 4.0.3 { EXPORT_FUNC_WRITE(LiWaitIopComplete, (int (*)(int, int *))0x0100F78C); EXPORT_FUNC_WRITE(LiWaitIopCompleteWithInterrupts, (int (*)(int, int *))0x0100F678); EXPORT_FUNC_WRITE(addr_LiWaitOneChunk, (int (*)(int, int *))0x010007F8); EXPORT_FUNC_WRITE(addr_PrepareTitle_hook, (int (*)(int, int *))0xFFF15E70); EXPORT_FUNC_WRITE(addr_sgIsLoadingBuffer, (int (*)(int, int *))0xEFE19CC0); EXPORT_FUNC_WRITE(addr_gDynloadInitialized, (int (*)(int, int *))0xEFE13BFC); } else if(OS_FIRMWARE == 310) { EXPORT_FUNC_WRITE(LiWaitIopComplete, (int (*)(int, int *))0x0100C4E4); EXPORT_FUNC_WRITE(LiWaitIopCompleteWithInterrupts, (int (*)(int, int *))0x0100C3D4); EXPORT_FUNC_WRITE(addr_LiWaitOneChunk, (int (*)(int, int *))0x010004D8); EXPORT_FUNC_WRITE(addr_PrepareTitle_hook, (int (*)(int, int *))0xFFF15A0C); EXPORT_FUNC_WRITE(addr_sgIsLoadingBuffer, (int (*)(int, int *))0xEFE19340); EXPORT_FUNC_WRITE(addr_gDynloadInitialized, (int (*)(int, int *))0xEFE1329C); } else if(OS_FIRMWARE == 300 || OS_FIRMWARE == 301) { EXPORT_FUNC_WRITE(LiWaitIopComplete, (int (*)(int, int *))0x0100C4E4); EXPORT_FUNC_WRITE(LiWaitIopCompleteWithInterrupts, (int (*)(int, int *))0x0100C3D4); EXPORT_FUNC_WRITE(addr_LiWaitOneChunk, (int (*)(int, int *))0x010004D8); EXPORT_FUNC_WRITE(addr_PrepareTitle_hook, (int (*)(int, int *))0xFFF15974); EXPORT_FUNC_WRITE(addr_sgIsLoadingBuffer, (int (*)(int, int *))0xEFE19340); EXPORT_FUNC_WRITE(addr_gDynloadInitialized, (int (*)(int, int *))0xEFE1329C); } else { OSFatal("Missing all OS specific addresses."); } }
void _start() { asm( "lis %r1, 0x1ab5 ;" "ori %r1, %r1, 0xd138 ;" ); unsigned int coreinit_handle, gx2_handle; OSDynLoad_Acquire("coreinit", &coreinit_handle); OSDynLoad_Acquire("gx2", &gx2_handle); //OS Memory functions void*(*memset)(void * dest, unsigned int value, unsigned int bytes); void*(*OSAllocFromSystem)(unsigned int size, int align); void(*OSFreeToSystem)(void *ptr); //IM functions int(*IM_Open)(); int(*IM_Close)(int fd); int(*IM_SetDeviceState)(int fd, void *mem, int state, int a, int b); //OS Memory functions OSDynLoad_FindExport(coreinit_handle, 0, "memset", &memset); OSDynLoad_FindExport(coreinit_handle, 0, "OSAllocFromSystem", &OSAllocFromSystem); OSDynLoad_FindExport(coreinit_handle, 0, "OSFreeToSystem", &OSFreeToSystem); //IM functions OSDynLoad_FindExport(coreinit_handle, 0, "IM_Open", &IM_Open); OSDynLoad_FindExport(coreinit_handle, 0, "IM_Close", &IM_Close); OSDynLoad_FindExport(coreinit_handle, 0, "IM_SetDeviceState", &IM_SetDeviceState); //Restart system to get lib access int fd = IM_Open(); void *mem = OSAllocFromSystem(0x100, 64); memset(mem, 0, 0x100); //set restart flag to force quit browser IM_SetDeviceState(fd, mem, 3, 0, 0); IM_Close(fd); OSFreeToSystem(mem); //wait a bit for browser end unsigned int t1 = 0x1FFFFFFF; while(t1--) ; /* Get the framebuffer of the TV or DRC */ void(*GX2SwapScanBuffers)(); OSDynLoad_FindExport(gx2_handle, 0, "GX2SwapScanBuffers", &GX2SwapScanBuffers); unsigned char *abuseFunc = (unsigned char*)GX2SwapScanBuffers; unsigned short f_hi = *(unsigned short*)(abuseFunc+0x12); unsigned short f_lo = *(unsigned short*)(abuseFunc+0x16); unsigned int gx2settingBase = (((f_lo & 0x8000) ? (f_hi-1) : f_hi) << 16) | f_lo; unsigned int args[2]; args[0] = *((unsigned int*)(gx2settingBase + 0x304)); args[1] = *((unsigned int*)(gx2settingBase + 0x304 + 0x20)); int(*OSGetCoreId)(); OSDynLoad_FindExport(coreinit_handle, 0, "OSGetCoreId", &OSGetCoreId); void(*OSTestThreadCancel)(); OSDynLoad_FindExport(coreinit_handle, 0, "OSTestThreadCancel", &OSTestThreadCancel); void(*GX2Shutdown)(); OSDynLoad_FindExport(gx2_handle, 0, "GX2Shutdown", &GX2Shutdown); int(*GX2GetMainCoreId)(); OSDynLoad_FindExport(gx2_handle, 0, "GX2GetMainCoreId", &GX2GetMainCoreId); /* Prepare for our own death */ void*(*OSGetCurrentThread)(); OSDynLoad_FindExport(coreinit_handle, 0, "OSGetCurrentThread", &OSGetCurrentThread); void *myBorkedThread = OSGetCurrentThread(); int (*OSSuspendThread)(void *thread); OSDynLoad_FindExport(coreinit_handle, 0, "OSSuspendThread", &OSSuspendThread); /* Prepare for thread startups */ int (*OSCreateThread)(void *thread, void *entry, int argc, void *args, unsigned int stack, unsigned int stack_size, int priority, unsigned short attr); int (*OSResumeThread)(void *thread); int (*OSIsThreadTerminated)(void *thread); OSDynLoad_FindExport(coreinit_handle, 0, "OSCreateThread", &OSCreateThread); OSDynLoad_FindExport(coreinit_handle, 0, "OSResumeThread", &OSResumeThread); OSDynLoad_FindExport(coreinit_handle, 0, "OSIsThreadTerminated", &OSIsThreadTerminated); /* Allocate a stack for the thread */ unsigned int stack = (unsigned int) OSAllocFromSystem(0x1000, 0x10); stack += 0x1000; /* Create the thread */ void *thread = OSAllocFromSystem(OSTHREAD_SIZE, 8); if(OSGetCoreId() != GX2GetMainCoreId()) //needed for access without crashing { int ret = OSCreateThread(thread, GX2Shutdown, 0, (void*)0, stack, 0x1000, 0, 0x10 | (1<<GX2GetMainCoreId())); if (ret == 0) OSFatal("Failed to create thread"); /* Schedule it for execution */ OSResumeThread(thread); while(OSIsThreadTerminated(thread) == 0) ; } else //same core, easy GX2Shutdown(); //current thread is broken, switch to a working one in core 1 int ret = OSCreateThread(thread, myGXthread, 2, args, stack, 0x1000, 0, 0xA); if (ret == 0) OSFatal("Failed to create thread"); /* Schedule it for execution */ OSResumeThread(thread); /* SO UGLY but it works magically */ while(1) ; //would be better but again, crashes 5.3.2 //OSSuspendThread(myBorkedThread); //OSFatal("I am still not dead!"); }
void myGXthread(int argc, int *argv) { if(argc != 2) OSFatal("GX Thread did not start proper!"); unsigned int *tv_fb = (unsigned int*)argv[0]; unsigned int *drc_fb = (unsigned int*)argv[1]; unsigned int coreinit_handle, gx2_handle; OSDynLoad_Acquire("coreinit", &coreinit_handle); OSDynLoad_Acquire("gx2", &gx2_handle); void(*GX2Init)(void *args); OSDynLoad_FindExport(gx2_handle, 0, "GX2Init", &GX2Init); GX2Init((void*)0); int(*OSGetCoreId)(); OSDynLoad_FindExport(coreinit_handle, 0, "OSGetCoreId", &OSGetCoreId); void(*GX2SwapScanBuffers)(); OSDynLoad_FindExport(gx2_handle, 0, "GX2SwapScanBuffers", &GX2SwapScanBuffers); void(*GX2Shutdown)(); OSDynLoad_FindExport(gx2_handle, 0, "GX2Shutdown", &GX2Shutdown); int(*GX2GetMainCoreId)(); OSDynLoad_FindExport(gx2_handle, 0, "GX2GetMainCoreId", &GX2GetMainCoreId); if(OSGetCoreId() != GX2GetMainCoreId()) OSFatal("GX Not switched!"); void(*GX2DrawDone)(); OSDynLoad_FindExport(gx2_handle, 0, "GX2DrawDone", &GX2DrawDone); void(*GX2Flush)(); OSDynLoad_FindExport(gx2_handle, 0, "GX2Flush", &GX2Flush); //void(*GX2SwapScanBuffers)(); //OSDynLoad_FindExport(gx2_handle, 0, "GX2SwapScanBuffers", &GX2SwapScanBuffers); void(*GX2WaitForVsync)(); OSDynLoad_FindExport(gx2_handle, 0, "GX2WaitForVsync", &GX2WaitForVsync); //Make sure buffer is usable for GX void(*GX2Invalidate)(unsigned int flags,void *buffer,unsigned int size); OSDynLoad_FindExport(gx2_handle, 0, "GX2Invalidate", &GX2Invalidate); GX2Invalidate(0x40,tv_fb,(1280*720*4)*2); GX2Invalidate(0x40,drc_fb,(854*480*4)*2); //set it! int(*GX2SetTVBuffer)(void *buffer,unsigned int size,unsigned int flag1,unsigned int flag2,unsigned int flag3); OSDynLoad_FindExport(gx2_handle, 0, "GX2SetTVBuffer", &GX2SetTVBuffer); int(*GX2SetDRCBuffer)(void *buffer,unsigned int size,unsigned int flag1,unsigned int flag2,unsigned int flag3); OSDynLoad_FindExport(gx2_handle, 0, "GX2SetDRCBuffer", &GX2SetDRCBuffer); GX2SetTVBuffer(tv_fb,(1280*720*4)*2,3,0x1A,2); //test gradient demo setup for show GX2SetDRCBuffer(drc_fb,(854*480*4)*2,1,0x1A,2); //will look broken, no color buffer setup yet /* Draw is far from complete */ /*void(*GX2DrawEx)(int type, int count, int start, int instances); OSDynLoad_FindExport(gx2_handle, 0, "GX2DrawEx", &GX2DrawEx); void(*GX2SetAttribBuffer)(int index, int size, int vtxStride, void *buf); OSDynLoad_FindExport(gx2_handle, 0, "GX2SetAttribBuffer", &GX2SetAttribBuffer); float myclearer[8] = { 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f }; GX2Invalidate(0x40, myclearer, sizeof(myclearer));*/ GX2ColorBuffer myCBuf; setupColorBuffer(&myCBuf, gx2_handle); void(*GX2ClearColor)(GX2ColorBuffer *buffer, float r, float g, float b, float a); OSDynLoad_FindExport(gx2_handle, 0, "GX2ClearColor", &GX2ClearColor); void(*GX2SwapBuffers)(GX2ColorBuffer *buffer); OSDynLoad_FindExport(gx2_handle, 0, "GX2SwapBuffers", &GX2SwapBuffers); void(*GX2CopyColorBufferToScanBuffer)(GX2ColorBuffer *buffer, unsigned int target); OSDynLoad_FindExport(gx2_handle, 0, "GX2CopyColorBufferToScanBuffer", &GX2CopyColorBufferToScanBuffer); float val = 1; float valInc = -0.005; val += valInc; while(val < 1) { val += valInc; //GX2SetAttribBuffer(0,sizeof(mybuf),8,mybuf); //GX2DrawEx(6,4,0,1); GX2ClearColor(&myCBuf, val, val, val, 1); GX2Invalidate(0x40, myCBuf.surface.imagePtr,myCBuf.surface.imageSize); GX2DrawDone(); GX2Flush(); GX2CopyColorBufferToScanBuffer(&myCBuf,1); GX2SwapScanBuffers(); GX2Flush(); GX2WaitForVsync(); if(val <= 0) valInc = 0.005; } //clear for browser (needed?) GX2Shutdown(); void(*_Exit)(); OSDynLoad_FindExport(coreinit_handle, 0, "_Exit", &_Exit); _Exit(); }