#include #include #include #include #include #include #include #include "main.h" std::vector ioslist; int selectedIos = IOS_GetVersion(); int ios_pos = 0; int bootmii = 0; int nandemu = 0; int priiloader = 0; s32 NandReadFile(char *filepath, u8 **buffer, u32 *filesize) { s32 Fd; int ret; if (buffer == NULL) { printf("NULL Pointer\n"); return -1; } Fd = ISFS_Open(filepath, ISFS_OPEN_READ); if (Fd < 0) { printf("ISFS_Open %s failed %d\n", filepath, Fd); return Fd; } fstats *status; status = (fstats *)memalign(32, ((sizeof(fstats))+31)&(~31)); if (status == NULL) { printf("Out of memory for status\n"); return -1; } ret = ISFS_GetFileStats(Fd, status); if (ret < 0) { printf("ISFS_GetFileStats failed %d\n", ret); ISFS_Close(Fd); free(status); return -1; } *buffer = (u8 *)memalign(32, ((status->file_length)+31)&(~31)); if (*buffer == NULL) { printf("Out of memory for buffer\n"); ISFS_Close(Fd); free(status); return -1; } ret = ISFS_Read(Fd, *buffer, status->file_length); if (ret < 0) { printf("ISFS_Read failed %d\n", ret); ISFS_Close(Fd); free(status); free(*buffer); return ret; } ISFS_Close(Fd); *filesize = status->file_length; free(status); if (*filesize > 0) { DCFlushRange(*buffer, *filesize); ICInvalidateRange(*buffer, *filesize); } return 0; } s32 GetTMD(u64 TicketID, signed_blob **Output, u32 *Length) { signed_blob* TMD = NULL; u32 TMD_Length; s32 ret; /* Retrieve TMD length */ ret = ES_GetStoredTMDSize(TicketID, &TMD_Length); if (ret < 0) return ret; /* Allocate memory */ TMD = (signed_blob*)memalign(32, (TMD_Length+31)&(~31)); if (!TMD) return IPC_ENOMEM; /* Retrieve TMD */ ret = ES_GetStoredTMD(TicketID, TMD, TMD_Length); if (ret < 0) { free(TMD); return ret; } /* Set values */ *Output = TMD; *Length = TMD_Length; return 0; } int check_priiloader() { char filepath[ISFS_MAXPATH] ATTRIBUTE_ALIGN(0x20); static u64 titleId ATTRIBUTE_ALIGN(32) = 0x0000000100000002LL; int ret = 0; tmd *ptmd = NULL; u32 TMD_size = 0; signed_blob *stmd = NULL; u32 i = 0; u32 filesize = 0; u8 *buffer = NULL; const char *checkStr = "priiloader"; int retValue = -1; ret = GetTMD(titleId, &stmd, &TMD_size); if (ret < 0) goto end; if (!stmd) { ret = -1; goto end; } ptmd = (tmd*)SIGNATURE_PAYLOAD(stmd); for (i = 0; i < ptmd->num_contents; i++) { if (ptmd->contents[i].index == ptmd->boot_index) { sprintf(filepath, "/title/%08x/%08x/content/%08x.app" , 0x00000001, 0x00000002, ptmd->contents[i].cid); ret = NandReadFile(filepath, &buffer, &filesize); if (ret < 0 || filesize < 0) { retValue = -2; goto end; } break; } } for (i = 0; i < filesize - strlen(checkStr); i++) { if (!strncmp((char*)buffer + i, checkStr, strlen(checkStr))) { retValue = 1; break; } } end: free(buffer); free(stmd); ptmd = NULL; priiloader = retValue; return retValue; } // Check if this is an IOS stub (according to WiiBrew.org) bool IsKnownStub(u32 noIOS, s32 noRevision) { if (noIOS == 3 && noRevision == 65280) return true; if (noIOS == 4 && noRevision == 65280) return true; if (noIOS == 10 && noRevision == 768) return true; if (noIOS == 11 && noRevision == 256) return true; if (noIOS == 16 && noRevision == 512) return true; if (noIOS == 20 && noRevision == 256) return true; if (noIOS == 30 && noRevision == 2816) return true; if (noIOS == 40 && noRevision == 3072) return true; if (noIOS == 50 && noRevision == 5120) return true; if (noIOS == 51 && noRevision == 4864) return true; if (noIOS == 52 && noRevision == 5888) return true; if (noIOS == 60 && noRevision == 6400) return true; if (noIOS == 70 && noRevision == 6912) return true; if (noIOS == 222 && noRevision == 65280) return true; if (noIOS == 223 && noRevision == 65280) return true; if (noIOS == 249 && noRevision == 65280) return true; if (noIOS == 250 && noRevision == 65280) return true; if (noIOS == 254 && noRevision == 2) return true; if (noIOS == 254 && noRevision == 3) return true; if (noIOS == 254 && noRevision == 260) return true; // BootMii As IOS is installed on IOS254 rev 31338 if (noIOS == 254 && noRevision == 31338) return true; // NAND Emu if (noIOS == 253 && noRevision == 65535) return true; return false; } int getIosPos(int getios) { for(int i = 0; i < (signed)ioslist.size(); i++) { if(ioslist[i] == getios) { ios_pos = i; break; } } return ios_pos; } int nextIos() { if(ioslist.size() != 0) { ios_pos++; if(ios_pos > (signed)ioslist.size() -1) ios_pos = ioslist.size() -1; selectedIos= ioslist[ios_pos]; } return selectedIos; } int previousIos() { if(ioslist.size() != 0) { ios_pos--; if(ios_pos < 0) ios_pos = 0; selectedIos= ioslist[ios_pos]; } return selectedIos; } bool listIOS() { if(ios_pos > 0) return true; ioslist.clear(); u32 nbTitles; if (ES_GetNumTitles(&nbTitles) < 0) return false; // Allocate the memory for titles u64 *titles = (u64*)memalign(32, nbTitles*sizeof(u64)); if (titles == NULL) return false; if (ES_GetTitles(titles, nbTitles) < 0) return false; int i; u32 titleID; // For each titles found for (i = 0; i < (signed)nbTitles; i++) { // Skip non-system titles if (titles[i] >> 32 != 1) continue; // Skip the system menu titleID = titles[i] & 0xFFFFFFFF; if (titleID == 2) continue; // Skip BC, MIOS and possible other non-IOS titles if (titleID > 0xFF) continue; // Skip the running IOS if (titleID == 0) continue; // Skip NAND-Emu IOS if (titleID == 253) { nandemu = 1; continue; } // Skip bootmii IOS if (titleID == 254) { bootmii = 1; continue; } // Check if this title is an IOS stub u32 tmdSize; tmd *iosTMD ATTRIBUTE_ALIGN(32); // Get the stored TMD size for the title if (ES_GetStoredTMDSize(0x0000000100000000ULL | titleID, &tmdSize) < 0) return false; signed_blob *iosTMDBuffer = (signed_blob *)memalign(32, (tmdSize+32)&(~31)); memset(iosTMDBuffer, 0, tmdSize); // Get the stored TMD for the title if (ES_GetStoredTMD(0x0000000100000000ULL | titleID, iosTMDBuffer, tmdSize) < 0) return false; iosTMD = (tmd *)SIGNATURE_PAYLOAD(iosTMDBuffer); free(iosTMDBuffer); // Get the title version u8 noVersion = iosTMD->title_version; bool isStub = false; // Check if this is an IOS stub (according to WiiBrew.org) if (IsKnownStub(titleID, iosTMD->title_version)) isStub = true; else { // If the version is 00, it's probably a stub // // Stubs have these things in common: // - Title version is mostly 65280, or even better, the last 2 hexadecimal digits are 0; // - Stub have one app of their own (type 0x1) and 2 shared apps (type 0x8001). if (noVersion == 0) isStub = ((iosTMD->num_contents == 3) && (iosTMD->contents[0].type == 1 && iosTMD->contents[1].type == 0x8001 && iosTMD->contents[2].type == 0x8001)); else isStub = false; } if(!isStub) ioslist.push_back(titleID); } std::sort( ioslist.begin(), ioslist.end() ); // sortieren return true; } int SelectedIOS() { return selectedIos; } int SearchAppIOS(std::string foldername) { if(listIOS()) { bool found = false; for(int i = 0; i < (signed)appios.size(); i++) { if(appios[i].foldername == foldername) { selectedIos = appios[i].ios; found = true; break; } } if(!found) selectedIos = IOS_GetVersion(); getIosPos(selectedIos); } return selectedIos; } int GetAppIOS(std::string foldername) { if(listIOS()) { for(int i = 0; i < (signed)appios.size(); i++) { if(appios[i].foldername == foldername) return appios[i].ios; } } return selectedIos; } int get_priiloader() { return priiloader; } void set_priiloader(int choice) { priiloader = choice; } int get_bootmii() { return bootmii; } void set_bootmii(int choice) { bootmii = choice; } int get_nandemu() { return nandemu; } void set_nandemu(int choice) { nandemu = choice; }