static int fileOpen(IFile *file, FS_ArchiveID archiveId, const char *path, int flags) { FS_Path filePath = {PATH_ASCII, strnlen(path, PATH_MAX) + 1, path}, archivePath = {PATH_EMPTY, 1, (u8 *)""}; return IFile_Open(file, archiveId, archivePath, filePath, flags); }
Result inline downloadPageToSDCard(httpcContext* context, const short* filename, u32 size) { Result ret = 0; u32 pos = 0, sz = 0; IFile_Open(FILE_LOC, filename, FILE_W); *((int *)FILE_LOC + 1) = 0; svcSleepThread(0x400000LL); while(pos < size) { sz = size - pos; sz = sz > BUF_LEN ? BUF_LEN : sz; ret = httpcReceiveData(context, BUF_LOC, sz); if(ret == HTTPC_RESULTCODE_DOWNLOADPENDING) { ret = httpcGetDownloadSizeState(context, &pos, 0); if(ret) return ret; goto filewrite; } else if(ret) return ret; else { pos += sz; filewrite: IFile_Write(FILE_LOC, WRITTEN_LOC, BUF_LOC, sz); svcSleepThread(0x400000LL); } } return 0; }
int __attribute__ ((section (".text.a11.entry"))) _main() { svc_sleepThread(0x10000000); // Get framebuffer addresses uint32_t regs[10]; regs[0] = 0xDEADBABE; regs[1] = 0xBABEDADA; //FIXME where do these reg addresses come from? _GSPGPU_ReadHWRegs(gspHandle, 0x400468, ®s[0+2], 8); // framebuffer 1 top left & framebuffer 2 top left _GSPGPU_ReadHWRegs(gspHandle, 0x400494, ®s[2+2], 8); // framebuffer 1 top right & framebuffer 2 top right _GSPGPU_ReadHWRegs(gspHandle, 0x400568, ®s[4+2], 8); // framebuffer 1 bottom & framebuffer 2 bottom _GSPGPU_ReadHWRegs(gspHandle, 0x400478, ®s[6+2], 4); // framebuffer select top _GSPGPU_ReadHWRegs(gspHandle, 0x400578, ®s[7+2], 4); // framebuffer select bottom //patch gsp event handler addr to kill gsp thread ASAP, PA 0x267CF418 *((u32*)(0x003F8418+0x10+4*0x4))=0x002CA520; //svc 0x9 addr flashScreen(); svc_sleepThread(0x10000000); // Read the main payload to 0x17F00000(0x23F00000 pa) u32* buffer = (work_buffer + 0x10000/sizeof(u32)); IFILE file; unsigned int readBytes; _memset(&file, 0, sizeof(file)); IFile_Open(&file, L"dmc:/arm9.bin", 1); const uint32_t block_size = 0x10000; for(u32 i = 0; i < 0x20000u; i += block_size) { IFile_Read(&file, &readBytes, (void*)buffer, block_size); GSPGPU_FlushDataCache(buffer, block_size); GX_SetTextureCopy(buffer, (void *)(0x17F00000 + i), block_size, 0, 0, 0, 0, 8); if(readBytes != block_size) break; } // Copy the magic to 0x18410000 // Copy it twice to make it easier to find and avoid catching the wrong one buffer[0] = MAGIC_WORD; buffer[1] = MAGIC_WORD; if(regs[6+2]) { buffer[2] = regs[0+2]; buffer[3] = regs[2+2]; } else { buffer[2] = regs[1+2]; buffer[3] = regs[3+2]; } if(regs[7+2]) buffer[4] = regs[4+2]; else buffer[4] = regs[5+2]; // Grab access to PS Handle port; svc_connectToPort(&port, "srv:pm"); srv_RegisterClient(&port); u32 proc = 0; svc_getProcessId(&proc, 0xFFFF8001); srvUnregisterProcess(&port, proc); srvRegisterProcess(&port, proc, 0x18, (const void*)&access_bin[0]); Handle ps_handle = 0; srv_getServiceHandle(&port, &ps_handle, "ps:ps"); svc_sleepThread(0x10000000); // Perform the exploit Result res = PS_VerifyRsaSha256(&ps_handle); // We do not expect reaching here return 0; }