void ResetWakeup_Timestamp() { s32 fd; unsigned char *miscbuf; printf("Resetting wakeup time...\n"); fd = ISFS_Open("/shared2/wc24/misc.bin", ISFS_OPEN_RW); if(fd<0) { printf("Failed to open misc.bin: %d\n", fd); } else { miscbuf = (unsigned char*)memalign(32, 0x400); memset(miscbuf, 0, 0x400); ISFS_Read(fd, miscbuf, 0x400); ISFS_Seek(fd, 0, SEEK_SET); time_t curtime = (time_t)*((u32*)&miscbuf[0x3c]); struct tm *misc_time = gmtime(&curtime); if(curtime)printf("Wakeup timestamp time: %s\n", asctime(misc_time)); if(curtime==0)printf("Current wakeup timestamp time is zero.\n"); *((u32*)&miscbuf[0x38]) = 0; *((u32*)&miscbuf[0x3c]) = 0; ISFS_Write(fd, miscbuf, 0x400); free(miscbuf); ISFS_Close(fd); } }
bool LoadPostloaderFromISFS (void) { char path[ISFS_MAXPATH] ATTRIBUTE_ALIGN(32); ISFS_Initialize(); strcpy (path, "/apps/postLoader/boot.dol"); s32 fd = ISFS_Open (path, ISFS_OPEN_READ); if (fd < 0) goto fail; s32 filesize = ISFS_Seek(fd, 0, 2); if (filesize == 0) goto fail; ISFS_Seek (fd, 0, 0); // exeBuffer is already 32bit aligned... should work fine s32 readed = ISFS_Read (fd, exeBuffer, filesize); ISFS_Close (fd); if (readed != filesize) goto fail; return TRUE; fail: ISFS_Deinitialize (); return FALSE; }
s8 VerifyNandBootInfo ( void ) { // path : /shared2/sys/NANDBOOTINFO NANDBootInfo *Boot_Info = (NANDBootInfo *)mem_align( 32, sizeof(NANDBootInfo) ); memset( Boot_Info, 0, sizeof(NANDBootInfo) ); s32 fd = ISFS_Open("/shared2/sys/NANDBOOTINFO", 1 ); if(fd < 0) { mem_free( Boot_Info ); return -1; } s32 ret = ISFS_Read(fd, Boot_Info, sizeof(NANDBootInfo)); if(ret != sizeof(NANDBootInfo)) { ISFS_Close(fd); mem_free( Boot_Info ); return -2 ; } ISFS_Close(fd); u8 r = Boot_Info->titletype; mem_free( Boot_Info ); if (r == 8) { SetBootState(4,132,0,0); return 1; } else return 0; }
bool readch (s_channelConfig *cc) { s32 ret; char path[ISFS_MAXPATH] ATTRIBUTE_ALIGN(32); Debug ("neek_PLNandInfo [begin]"); ISFS_Initialize (); sprintf (path, "/sneek/nandcfg.ch"); s32 fd; fd = ISFS_Open( path, ISFS_OPEN_READ); ret = -1; if (fd > 0) { ret = ISFS_Read(fd, cc, sizeof(s_channelConfig)); ISFS_Close(fd); } ISFS_Deinitialize (); if (ret >= 0) return true; return false; }
int fileBrowser_WiiFS_readFile(fileBrowser_file* file, void* buffer, unsigned int length){ // Make sure everything is aligned (address and length) int isUnaligned = ((int)buffer)%32 | length%32; int alignedLen = (length+31)&0xffffffe0; char* alignedBuf; if(isUnaligned) alignedBuf = memalign(32, alignedLen); else alignedBuf = buffer; // Make sure the filename is 8.3 and open the short filename shrinkFilename( &file->name ); int f = ISFS_Open( getAlignedName(&file->name), 1 ); if(f < 0) return FILE_BROWSER_ERROR; // Do the actual read, into the aligned buffer if we need to ISFS_Seek(f, file->offset, 0); int bytes_read = ISFS_Read(f, alignedBuf, alignedLen); if(bytes_read > 0) file->offset += bytes_read; // If it was unaligned, you have to copy it and clean up if(isUnaligned){ memcpy(buffer, alignedBuf, length); free(alignedBuf); } ISFS_Close(f); return bytes_read; }
s32 read_file(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("\n * ISFS_Open %s failed %d", filepath, Fd); //Pad_WaitButtons(); return Fd; } fstats *status; status = allocate_memory(sizeof(fstats)); 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 = allocate_memory(status->file_length); 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); return 0; }
int NandTitle::LoadFileFromNand(const char *filepath, u8 **outbuffer, u32 *outfilesize) { if(!filepath) return -1; fstats *stats = (fstats *) memalign(32, ALIGN32(sizeof(fstats))); if(!stats) return IPC_ENOMEM; int fd = ISFS_Open(filepath, ISFS_OPEN_READ); if(fd < 0) { free(stats); return fd; } int ret = ISFS_GetFileStats(fd, stats); if (ret < 0) { free(stats); ISFS_Close(fd); return ret; } u32 filesize = stats->file_length; free(stats); u8 *buffer = (u8 *) memalign(32, ALIGN32(filesize)); if(!buffer) { ISFS_Close(fd); return IPC_ENOMEM; } ret = ISFS_Read(fd, buffer, filesize); ISFS_Close(fd); if (ret < 0) { free(buffer); return ret; } *outbuffer = buffer; *outfilesize = filesize; return 0; }
s32 SetBootState( u8 type , u8 flags , u8 returnto , u8 discstate ) { StateFlags *sf = (StateFlags *)mem_align( 32, sizeof(StateFlags) ); memset( sf, 0, sizeof(StateFlags) ); s32 fd = ISFS_Open("/title/00000001/00000002/data/state.dat", 1|2 ); if(fd < 0) { mem_free( sf ); ISFS_Close(fd); return -1; } s32 ret = ISFS_Read(fd, sf, sizeof(StateFlags)); if(ret != sizeof(StateFlags)) { mem_free( sf ); ISFS_Close(fd); return -2 ; } sf->type = type; sf->returnto = returnto; sf->flags = flags; sf->discstate = discstate; sf->checksum= __CalcChecksum((u32*)sf, sizeof(StateFlags)); if(ISFS_Seek( fd, 0, 0 )<0) { mem_free( sf ); ISFS_Close(fd); return -3; } if(ISFS_Write(fd, sf, sizeof(StateFlags))!=sizeof(StateFlags)) { mem_free( sf ); ISFS_Close(fd); return -4; } ISFS_Close(fd); mem_free( sf ); return 1; }
s32 CheckBootState( void ) { StateFlags *sf = (StateFlags *)mem_align( 32, sizeof(StateFlags) ); memset( sf, 0, sizeof(StateFlags) ); s32 fd = ISFS_Open("/title/00000001/00000002/data/state.dat", 1); if(fd < 0) { mem_free(sf); return 0; } s32 ret = ISFS_Read(fd, sf, sizeof(StateFlags)); ISFS_Close(fd); if(ret != sizeof(StateFlags)) { mem_free(sf); return 0; } u8 r = sf->type; mem_free( sf ); return r; }
StateFlags GetStateFlags( void ) { StateFlags *sf = (StateFlags *)mem_align( 32, sizeof(StateFlags) ); StateFlags State; memset( sf, 0, sizeof(StateFlags) ); s32 fd = ISFS_Open("/title/00000001/00000002/data/state.dat", 1); if(fd < 0) { mem_free(sf); return State; } s32 ret = ISFS_Read(fd, sf, sizeof(StateFlags)); ISFS_Close(fd); if(ret != sizeof(StateFlags)) { mem_free(sf); return State; } memcpy((StateFlags*)&State,sf,sizeof(StateFlags)); mem_free( sf ); return State; }
u8 *ISFS_GetFile(u8 *path, u32 *size, s32 length) { *size = 0; s32 fd = ISFS_Open((const char *) path, ISFS_OPEN_READ); u8 *buf = NULL; static fstats stats ATTRIBUTE_ALIGN(32); if(fd >= 0) { if(ISFS_GetFileStats(fd, &stats) >= 0) { if(length <= 0) length = stats.file_length; if(length > 0) buf = (u8 *)MEM2_memalign(32, length); if(buf) { *size = stats.file_length; if(ISFS_Read(fd, (char*)buf, length) != length) { *size = 0; MEM2_free(buf); } } } ISFS_Close(fd); } if(*size > 0) { DCFlushRange(buf, *size); ICInvalidateRange(buf, *size); } return buf; }
static int _ISFS_read_r(struct _reent *r, int fd, char *buf, size_t len) { FILE_STRUCT *file = (FILE_STRUCT *)fd; if (file->fd < 0) { r->_errno = EBADF; return -1; } char *buf32 = (char *) memalign(32, SECTOR_SIZE); if(!buf32) { r->_errno = ENOMEM; return -1; } s32 ret = 0; s32 read = 0; while(len > 0) { ret = ISFS_Read(file->fd, buf32, len > SECTOR_SIZE ? SECTOR_SIZE : len); if (ret < 0) { r->_errno = -ret; read = ret; break; } if(ret == 0) break; memcpy(buf + read, buf32, ret); read += ret; len -= ret; } free(buf32); return read; }
s32 extractChannelContents(u64 titleID, char* location) { u32 TitleIDH=TITLE_UPPER(titleID); u32 TitleIDL=TITLE_LOWER(titleID); if(ES_SetUID(titleID)<0) return ERR_UID; u32 tmd_size ATTRIBUTE_ALIGN(32); if(ES_GetStoredTMDSize(titleID, &tmd_size)<0) return ERR_TMDSIZE; signed_blob *TMD = (signed_blob *)memalign( 32, tmd_size ); memset(TMD, 0, tmd_size); if(ES_GetStoredTMD(titleID, TMD, tmd_size)<0) { free(TMD); return ERR_TMD; } u32 cnt ATTRIBUTE_ALIGN(32); if(ES_GetNumTicketViews(titleID, &cnt)<0) { free(TMD); return ERR_TIKCOUNT; } if( cnt <= 0 ) { free(TMD); return ERR_TIKCOUNT; } tikview *views = (tikview *)memalign( 32, sizeof(tikview)*cnt ); if(ES_GetTicketViews(titleID, views, cnt)<0) { free(views); free(TMD); return ERR_TIK; } printf("Allocated and filled views.\n"); sleep(3); Identify_SU(); int z; tmd_content *TMDc = TMD_CONTENTS(((tmd*)(SIGNATURE_PAYLOAD(TMD)))); // OH GOD CREDIAR, WTF WAS THAT MESS! // List format is "XXXXXXXX = YYYYYYYY" where X is index, and Y is cid. char *lookup_list=calloc(21,((tmd*)(SIGNATURE_PAYLOAD(TMD)))->num_contents); ClearScreen(); printf("\nNumber of contents: %d\n",((tmd*)(SIGNATURE_PAYLOAD(TMD)))->num_contents); sleep(1); for(z=0; z < ((tmd*)(SIGNATURE_PAYLOAD(TMD)))->num_contents; z++) { /* Get Content */ char nameDirectory[80]; sprintf(nameDirectory,"/title/%08x/%08x/content/%08x.app",TitleIDH,TitleIDL,TMDc[z].cid); s32 contentFd=ISFS_Open(nameDirectory,ISFS_OPEN_READ); u8 *data=calloc(TMDc[z].size,1); if(contentFd<0) { switch(contentFd) { case ISFS_EINVAL: printf("FAILED! (Invalid Argument %s)\n\tQuitting...\n",nameDirectory); sleep(5); Finish(1); break; case ISFS_ENOMEM: printf("FAILED! (Out of memory %s)\n\tQuitting...\n",nameDirectory); sleep(5); Finish(1); break; default: goto skip; // Finish(1); break; } } int isUnaligned = ((int)data)%32 | TMDc[z].size%32; int alignedLen = (TMDc[z].size+31)&0xffffffe0; unsigned char* alignedBuf; if(isUnaligned) alignedBuf = memalign(32, alignedLen); else alignedBuf = data; ISFS_Seek(contentFd,0,0); ISFS_Read(contentFd, alignedBuf, alignedLen); // If it was unaligned, you have to copy it and clean up if(isUnaligned){ memcpy(data, alignedBuf, TMDc[z].size); free(alignedBuf); } ISFS_Close(contentFd); // Do copying here. // data is the actual content data (use fwrite with it :P). // Copy the file with it's index as it's filename char* destination=calloc(sizeof(location)+14, 1); char lookup_entry[21]; sprintf(destination, "%s/%08x.app",location,TMDc[z].index); sprintf(lookup_entry, "%08x = %08x\n",TMDc[z].index,TMDc[z].cid); strcat(lookup_list, lookup_entry); printf("Got destination as: %s\n", destination); sleep(3); FILE *dfd=fopen(destination,"wb+"); printf("Opened %s\n", destination); sleep(3); // free(destination); fwrite(data, TMDc[z].size, 1, dfd); printf("Wrote data to %s\n", destination); sleep(3); fclose(dfd); printf("Closed %s\n", destination); sleep(2); skip: _nop(); } // Make a file containing the lookups called files.txt char* lookup_file=calloc(sizeof(location)+14, 1); sprintf(lookup_file, "%s/files.txt",location); printf("Got destination as: %s\n", lookup_file); sleep(3); FILE* lfd=fopen(lookup_file,"wb+"); printf("Opened %s\n", lookup_file); sleep(3); // free(lookup_file); fwrite(lookup_list, 21, ((tmd*)SIGNATURE_PAYLOAD(TMD))->num_contents, lfd); printf("Wrote lookups to %s\n", lookup_file); sleep(3); fclose(lfd); printf("Closed %s\n", lookup_file); sleep(2); printf("Freed TMD and views"); sleep(1);
int NandTitle::ExtractFile(const char *nandPath, const char *filepath) { if(!nandPath || !filepath) return -1; char *strDup = strdup(filepath); if(!strDup) return -666; char *ptr = strrchr(strDup, '/'); if(!ptr) { free(strDup); return -333; } else { *ptr = 0; CreateSubfolder(strDup); free(strDup); } int done = 0; int fd = -1; int blocksize = 32*1024; u8 *buffer = (u8 *) memalign(32, ALIGN32(blocksize)); if(!buffer) return -666; fstats *stats = (fstats *) memalign(32, ALIGN32(sizeof(fstats))); if(!stats) { free(buffer); return -666; } do { fd = ISFS_Open(nandPath, ISFS_OPEN_READ); if(fd < 0) break; int ret = ISFS_GetFileStats(fd, stats); if (ret < 0) break; int filesize = stats->file_length; FILE *pFile = fopen(filepath, "wb"); if(!pFile) break; while(done < filesize) { if(filesize-done < blocksize) blocksize = filesize-done; ret = ISFS_Read(fd, buffer, blocksize); if(ret < 0) { done = ret; break; } fwrite(buffer, 1, ret, pFile); done += ret; } fclose(pFile); } while(0); free(buffer); free(stats); if(fd >= 0) ISFS_Close(fd); return done; }
s8 WritePriiloader( bool priiloader_found ) { s32 ret = 0; s32 fd = 0; Nand_Permissions SysPerm; if(priiloader_found == false) { memset(&SysPerm,0,sizeof(Nand_Permissions)); SysPerm.otherperm = 3; SysPerm.groupperm = 3; SysPerm.ownerperm = 3; //system menu coping printf("Moving System Menu app..."); ret = nand_copy(original_app,copy_app,SysPerm); if (ret < 0) { if (ret == -80) { //checksum issues printf("\x1b[%u;%dm", 33, 1); printf("\nWARNING!!\n Installer could not calculate the Checksum for the System menu app"); printf("\nbut Copy was successfull.\n"); printf("Do you want the Continue ?\n"); printf("A = Yes B = No\n "); printf("\x1b[%u;%dm", 37, 1); if(!UserYesNoStop()) { printf("reverting changes...\n"); ISFS_Delete(copy_app); abort("System Menu Copying Failure"); } else printf("\nDone!\n"); } else abort("\nUnable to move the system menu. error %d",ret); } else { gprintf("Moving System Menu Done\n"); printf("Done!\n"); } } ret = 0; //sys_menu app moved. lets write priiloader STACK_ALIGN(fstats,status,sizeof(fstats),32); memset(&SysPerm,0,sizeof(Nand_Permissions)); SysPerm.otherperm = 3; SysPerm.groupperm = 3; SysPerm.ownerperm = 3; printf("Writing Priiloader app..."); gprintf("Writing Priiloader\n"); char temp_dest[ISFS_MAXPATH]; memset(temp_dest,0,ISFS_MAXPATH); char *ptemp = NULL; ptemp = strstr(original_app,"/"); while(ptemp != NULL && strstr(ptemp+1,"/") != NULL) { ptemp = strstr(ptemp+1,"/"); } if(ptemp[0] == '/') { ptemp = ptemp+1; } memset(temp_dest,0,ISFS_MAXPATH); sprintf(temp_dest,"/tmp/%s",ptemp); ISFS_Delete(temp_dest); ret = ISFS_CreateFile(temp_dest,SysPerm.attributes,SysPerm.ownerperm,SysPerm.groupperm,SysPerm.otherperm); fd = ISFS_Open(temp_dest,ISFS_OPEN_RW); if (fd < 0) { gprintf("error %d\n",fd); abort("\nFailed to open file for Priiloader writing"); } ret = ISFS_Write(fd,priiloader_app,priiloader_app_size); if (ret < 0 ) //check if the app was writen correctly { ISFS_Close(fd); ISFS_Delete(copy_app); ISFS_Delete(temp_dest); gprintf("Write failed. ret %d\n",ret); abort("\nWrite of Priiloader app failed"); } ISFS_Close(fd); //SHA1 check here fd = ISFS_Open(temp_dest,ISFS_OPEN_READ); if (fd < 0) { ISFS_Delete(copy_app); abort("\nFailed to open file for Priiloader checking"); } if (ISFS_GetFileStats(fd,status) < 0) { ISFS_Close(fd); ISFS_Delete(copy_app); abort("Failed to get stats of %s. System Menu Recovered",temp_dest); } else { if ( status->file_length != priiloader_app_size ) { ISFS_Close(fd); ISFS_Delete(copy_app); abort("Written Priiloader app isn't the correct size.System Menu Recovered"); } else { gprintf("Size Check Success\n"); printf("Size Check Success!\n"); } } u8 *AppData = (u8 *)memalign(32,ALIGN32(status->file_length)); if (AppData) ret = ISFS_Read(fd,AppData,status->file_length); else { ISFS_Close(fd); ISFS_Delete(copy_app); abort("Checksum comparison Failure! MemAlign Failure of AppData\n"); } ISFS_Close(fd); if (ret < 0) { if (AppData) { free(AppData); AppData = NULL; } ISFS_Delete(copy_app); abort("Checksum comparison Failure! read of priiloader app returned %u\n",ret); } if(CompareSha1Hash((u8*)priiloader_app,priiloader_app_size,AppData,status->file_length)) printf("Checksum comparison Success!\n"); else { if (AppData) { free(AppData); AppData = NULL; } ISFS_Delete(copy_app); abort("Checksum comparison Failure!\n"); } if (AppData) { free(AppData); AppData = NULL; } // rename and do a final SHA1 chezck ISFS_Delete(original_app); ret = ISFS_Rename(temp_dest,original_app); if(ret < 0 ) { gprintf("WritePriiloader : rename returned %d\n",ret); nand_copy(copy_app,original_app,SysPerm); ISFS_Delete(copy_app); abort("\nFailed to Write Priiloader : error Ren %d",ret); } printf("Done!!\n"); gprintf("Wrote Priiloader App.Checking Installation\n"); printf("\nChecking Priiloader Installation...\n"); memset(status,0,sizeof(fstats)); fd = ISFS_Open(original_app,ISFS_OPEN_READ); if (fd < 0) { nand_copy(copy_app,original_app,SysPerm); ISFS_Delete(copy_app); abort("\nFailed to open file for Priiloader checking"); } if (ISFS_GetFileStats(fd,status) < 0) { ISFS_Close(fd); nand_copy(copy_app,original_app,SysPerm); abort("Failed to get stats of %s. System Menu Recovered",original_app); } else { if ( status->file_length != priiloader_app_size ) { ISFS_Close(fd); nand_copy(copy_app,original_app,SysPerm); ISFS_Delete(copy_app); abort("Written Priiloader app isn't the correct size.System Menu Recovered"); } else { gprintf("Size Check Success\n"); printf("Size Check Success!\n"); } } AppData = (u8 *)memalign(32,ALIGN32(status->file_length)); if (AppData != NULL) ret = ISFS_Read(fd,AppData,status->file_length); else { ISFS_Close(fd); nand_copy(copy_app,original_app,SysPerm); ISFS_Delete(copy_app); abort("Checksum comparison Failure! MemAlign Failure of AppData\n"); } ISFS_Close(fd); if (ret < 0) { if (AppData) { free(AppData); AppData = NULL; } nand_copy(copy_app,original_app,SysPerm); ISFS_Delete(copy_app); abort("Checksum comparison Failure! read of priiloader app returned %u\n",ret); } if(CompareSha1Hash((u8*)priiloader_app,priiloader_app_size,AppData,status->file_length)) printf("Checksum comparison Success!\n"); else { if (AppData) { free(AppData); AppData = NULL; } nand_copy(copy_app,original_app,SysPerm); ISFS_Delete(copy_app); abort("Checksum comparison Failure!\n"); } if (AppData) { free(AppData); AppData = NULL; } gprintf("Priiloader Update Complete\n"); printf("Done!\n\n"); return 1; }
s32 nand_copy(const char *destination,u8* Buf_To_Write_to_Copy, u32 buf_size,Nand_Permissions src_perm) { if( Buf_To_Write_to_Copy == NULL || buf_size < 1 ) { return -1; } s32 ret, dest_handler; gprintf("owner %d group %d attributes %X perm:%X-%X-%X\n", src_perm.owner, (u32)src_perm.group, (u32)src_perm.attributes, (u32)src_perm.ownerperm, (u32)src_perm.groupperm, (u32)src_perm.otherperm); //extract filename from destination char temp_dest[ISFS_MAXPATH]; memset(temp_dest,0,ISFS_MAXPATH); char *ptemp = NULL; ptemp = strstr(destination,"/"); while(ptemp != NULL && strstr(ptemp+1,"/") != NULL) { ptemp = strstr(ptemp+1,"/"); } if(ptemp[0] == '/') { ptemp = ptemp+1; } //create temp path memset(temp_dest,0,ISFS_MAXPATH); sprintf(temp_dest,"/tmp/%s",ptemp); ISFS_Delete(temp_dest); //and go for it ret = ISFS_CreateFile(temp_dest,src_perm.attributes,src_perm.ownerperm,src_perm.groupperm,src_perm.otherperm); if (ret != ISFS_OK) { printf("Failed to create file %s. ret = %d\n",temp_dest,ret); gprintf("Failed to create file %s. ret = %d\n",temp_dest,ret); return ret; } dest_handler = ISFS_Open(temp_dest,ISFS_OPEN_RW); if (dest_handler < 0) { gprintf("failed to open destination : %s\n",temp_dest); ISFS_Delete(temp_dest); return dest_handler; } ret = ISFS_Write(dest_handler,Buf_To_Write_to_Copy,buf_size); if (ret < 0) { gprintf("failed to write destination : %s\n",temp_dest); ISFS_Close(dest_handler); ISFS_Delete(temp_dest); return ret; } ISFS_Close(dest_handler); s32 temp = 0; u8 *Data2 = NULL; STACK_ALIGN(fstats,D2stat,sizeof(fstats),32); /*if (D2stat == NULL) { temp = -1; goto free_and_Return; }*/ dest_handler = ISFS_Open(temp_dest,ISFS_OPEN_RW); if(dest_handler < 0) { gprintf("temp_dest open error %d\n",dest_handler); temp = -2; goto free_and_Return; } temp = ISFS_GetFileStats(dest_handler,D2stat); if(temp < 0) { goto free_and_Return; } Data2 = (u8*)memalign(32,ALIGN32(D2stat->file_length)); if (Data2 == NULL) { temp = -3; goto free_and_Return; } if( ISFS_Read(dest_handler,Data2,D2stat->file_length) > 0 ) { if( !CompareSha1Hash(Buf_To_Write_to_Copy,buf_size,Data2,D2stat->file_length)) { temp = -4; goto free_and_Return; } } else { temp = -5; goto free_and_Return; } if(Data2) { free(Data2); Data2 = NULL; } ISFS_Close(dest_handler); //so it was written to /tmp correctly. lets call ISFS_Rename and compare AGAIN ISFS_Delete(destination); ret = ISFS_Rename(temp_dest,destination); if(ret < 0 ) { gprintf("nand_copy(buf) : rename returned %d\n",ret); temp = -6; goto free_and_Return; } free_and_Return: if(Data2 != NULL) { free(Data2); Data2 = NULL; } ISFS_Close(dest_handler); if (temp < 0) { gprintf("temp %d\n",temp); //ISFS_Delete(destination); return -80; } return 1; }
u8* U8NandArchive::GetFileAllocated( const char *path, u32 *size ) const { //gprintf( "U8NandArchive::GetFileAllocated( %s )\n" ); if( !path || !fst ) { return NULL; } // find file int f = EntryFromPath( path, 0 ); if( f < 1 || f >= (int)fst[ 0 ].filelen ) { gprintf( "U8: \"%s\" wasn't found in the archive.\n", path ); return NULL; } if( fst[ f ].filetype ) { gprintf( "U8: \"%s\" is a folder\n", path ); return NULL; } // create a buffer u8* ret = (u8*)memalign( 32, RU( fst[ f ].filelen, 32 ) ); if( !ret ) { gprintf( "U8: out of memory\n" ); return NULL; } // seek and read if( ISFS_Seek( fd, dataOffset + fst[ f ].fileoffset, SEEK_SET ) != (s32)( dataOffset + fst[ f ].fileoffset ) || ISFS_Read( fd, ret, fst[ f ].filelen ) != (s32)fst[ f ].filelen ) { free( ret ); gprintf( "U8: error reading data from nand\n" ); gprintf( "fd: %i fst[ fd ].filelen: %08x\n", fd, fst[ f ].filelen ); return NULL; } u32 len = fst[ f ].filelen; u8* ret2; // determine if it needs to be decompressed if( IsAshCompressed( ret, len ) ) { // ASH0 ret2 = DecompressAsh( ret, len ); if( !ret2 ) { free( ret ); gprintf( "out of memory\n" ); return NULL; } free( ret ); } else if( isLZ77compressed( ret ) ) { // LZ77 with no magic word if( decompressLZ77content( ret, len, &ret2, &len ) ) { free( ret ); return NULL; } free( ret ); } else if( *(u32*)( ret ) == 0x4C5A3737 )// LZ77 { // LZ77 with a magic word if( decompressLZ77content( ret + 4, len - 4, &ret2, &len ) ) { free( ret ); return NULL; } free( ret ); } else { // already got what we are after ret2 = ret; } if( size ) { *size = len; } // flush the cache so if there are any textures in this data, it will be ready for the GX DCFlushRange( ret2, len ); return ret2; }
bool U8NandArchive::SetFile( const char* nandPath ) { if(fst) free(fst); if(name_table) free(name_table); CloseFile(); // open file if( (fd = ISFS_Open( nandPath, ISFS_OPEN_READ ) ) < 0 ) { gprintf( "U8NandArchive: ISFS_Open( \"%s\" ) failed\n", nandPath ); return false; } // get file size fstats stats __attribute__(( aligned( 32 ) )); int ret = ISFS_GetFileStats( fd, &stats ); if( ret < 0 ) { CloseFile(); gprintf( "U8NandArchive: ISFS_GetFileStats( \"%s\" ) failed\n", nandPath ); return false; } // buffer for reading the header and stuff u8* buffer = (u8*)memalign( 32, 0x800 ); if( !buffer ) { CloseFile(); gprintf( "U8NandArchive: enomem\n" ); return false; } // read a chunk big enough that it should contain the U8 header if there is going to be one if( (ret = ISFS_Read( fd, buffer, 0x800 )) != 0x800 ) { free( buffer ); CloseFile(); gprintf( "U8NandArchive: ISFS_Read( 0x800 ) = %i\n", ret ); return false; } // find the start of the U8 data U8Header* tagStart = (U8Header*)FindU8Tag( buffer, ret ); if( !tagStart ) { free( buffer ); CloseFile(); gprintf( "U8NandArchive: didn't see a U8 tag\n" ); return false; } // remember where in the file the U8 starts dataOffset = ( (u8*)tagStart - buffer ); // allocate memory and read the fst if( !(fst = (FstEntry *)memalign( 32, RU( tagStart->dataOffset - dataOffset, 32 ) ) ) || ( ISFS_Seek( fd, dataOffset + tagStart->rootNodeOffset, SEEK_SET ) != (s32)( dataOffset + tagStart->rootNodeOffset ) ) || ( ISFS_Read( fd, fst, tagStart->dataOffset - dataOffset ) != (s32)( tagStart->dataOffset - dataOffset ) ) || ( fst->filelen * 0xC > tagStart->dataOffset ) ) { dataOffset = 0; free( buffer ); if( fst ) free( fst ); CloseFile(); gprintf( "U8NandArchive: error reading fst\n" ); } // set name table pointer u32 name_table_offset = fst->filelen * 0xC; name_table = ((char *)fst) + name_table_offset; free( buffer ); return true; }
s8 GetTitleName(u64 id, u32 app, char* name,u8* _dst_uncode_name) { s32 r; int lang = 1; //CONF_GetLanguage(); /* languages: enum { CONF_LANG_JAPANESE = 0, CONF_LANG_ENGLISH, CONF_LANG_GERMAN, CONF_LANG_FRENCH, CONF_LANG_SPANISH, CONF_LANG_ITALIAN, CONF_LANG_DUTCH, CONF_LANG_SIMP_CHINESE, CONF_LANG_TRAD_CHINESE, CONF_LANG_KOREAN }; cause we dont support unicode stuff in font.cpp we will force to use english then(1) */ u8 return_unicode_name = 0; if(_dst_uncode_name == NULL) { return_unicode_name = 0; } else { return_unicode_name = 1; } char file[256] ATTRIBUTE_ALIGN(32); memset(file,0,256); sprintf(file, "/title/%08x/%08x/content/%08x.app", (u32)(id >> 32), (u32)(id & 0xFFFFFFFF), app); gdprintf("GetTitleName : %s\n",file); u32 cnt ATTRIBUTE_ALIGN(32); cnt = 0; IMET *data = (IMET *)mem_align(32, ALIGN32( sizeof(IMET) ) ); if(data == NULL) { gprintf("GetTitleName : IMET header align failure\n"); return -1; } memset(data,0,sizeof(IMET) ); r = ES_GetNumTicketViews(id, &cnt); if(r < 0) { gprintf("GetTitleName : GetNumTicketViews error %d!\n",r); mem_free(data); return -1; } tikview *views = (tikview *)mem_align( 32, sizeof(tikview)*cnt ); if(views == NULL) { mem_free(data); return -2; } r = ES_GetTicketViews(id, views, cnt); if (r < 0) { gprintf("GetTitleName : GetTicketViews error %d \n",r); mem_free(data); mem_free(views); return -3; } //lets get this party started with the right way to call ES_OpenTitleContent. and not like how libogc < 1.8.3 does it. patch was passed on , and is done correctly in 1.8.3 //the right way is ES_OpenTitleContent(u64 TitleID,tikview* views,u16 Index); note the views >_> s32 fh = ES_OpenTitleContent(id, views, 0); if (fh == -106) { CheckTitleOnSD(id); mem_free(data); mem_free(views); return -106; } else if(fh < 0) { //ES method failed. remove tikviews from memory and fall back on ISFS method gprintf("GetTitleName : ES_OpenTitleContent error %d\n",fh); mem_free(views); fh = ISFS_Open(file, ISFS_OPEN_READ); // f**k failed. lets check SD & GTFO if (fh == -106) { CheckTitleOnSD(id); return -106; } else if (fh < 0) { mem_free(data); gprintf("open %s error %d\n",file,fh); return -5; } // read the completed IMET header r = ISFS_Read(fh, data, sizeof(IMET)); if (r < 0) { gprintf("IMET read error %d\n",r); ISFS_Close(fh); mem_free(data); return -6; } ISFS_Close(fh); } else { //ES method r = ES_ReadContent(fh,(u8*)data,sizeof(IMET)); if (r < 0) { gprintf("GetTitleName : ES_ReadContent error %d\n",r); ES_CloseContent(fh); mem_free(data); mem_free(views); return -8; } //free data and let it point to IMET_data so everything else can work just fine ES_CloseContent(fh); mem_free(views); } char str[10][84]; char str_unprocessed[10][84]; //clear any memory that is in the place of the array cause we dont want any confusion here memset(str,0,10*84); if(return_unicode_name) memset(str_unprocessed,0,10*84); if(data->imet == 0x494d4554) // check if its a valid imet header { for(u8 y =0;y <= 9;y++) { u8 p = 0; u8 up = 0; for(u8 j=0;j<83;j++) { if(data->names[y][j] < 0x20) if(return_unicode_name && data->names[y][j] == 0x00) str_unprocessed[y][up++] = data->names[y][j]; else continue; else if(data->names[y][j] > 0x7E) continue; else { str[y][p++] = data->names[y][j]; str_unprocessed[y][up++] = data->names[y][j]; } } str[y][83] = '\0'; } mem_free(data); } else { gprintf("invalid IMET header for 0x%08x/0x%08x\n", (u32)(id >> 32), (u32)(id & 0xFFFFFFFF)); return -9; } if(str[lang][0] != '\0') { gdprintf("GetTitleName : title %s\n",str[lang]); snprintf(name,255, "%s", str[lang]); if (return_unicode_name && str_unprocessed[lang][1] != '\0') { memcpy(_dst_uncode_name,&str_unprocessed[lang][0],83); } else if(return_unicode_name) gprintf("WARNING : empty unprocessed string\n"); } else gprintf("GetTitleName: no name found\n"); memset(str,0,10*84); memset(str_unprocessed,0,10*84); return 1; }
void load() { u32 file_size; static fstats filestats_settings ATTRIBUTE_ALIGN(32); static fstats filestats_appios ATTRIBUTE_ALIGN(32); static u8 filearray_settings[1024] ATTRIBUTE_ALIGN(32); static u8 filearray_appios[1024] ATTRIBUTE_ALIGN(32); #if defined(STBOOT) || defined(STBOOTVWII) Settings.ios_dat = "/title/00010001/48424630/data/appios.dat"; Settings.dir_dat = "/title/00010001/48424630/data/list.dat"; Settings.settings_dat = "/title/00010001/48424630/data/settings.dat"; #else Settings.ios_dat = "/title/00010001/54484246/data/appios.dat"; Settings.dir_dat = "/title/00010001/54484246/data/list.dat"; Settings.settings_dat = "/title/00010001/54484246/data/settings.dat"; #endif AvailableCategoryLoad(Settings.dir_dat); // get settings s32 fd; fd = ISFS_Open(Settings.settings_dat.c_str(), ISFS_OPEN_READ); if (fd <= 0) ISFS_Close(fd); ISFS_GetFileStats(fd, &filestats_settings); file_size = ISFS_Read(fd, filearray_settings, filestats_settings.file_length); ISFS_Close(fd); if(file_size >= 0) { string source = (char*)filearray_settings; if(get_setting(source, "device_dat") != "") Settings.device_dat = get_setting(source, "device_dat"); if (get_setting(source, "theme") != "") { sprintf (Options.theme, get_setting(source, "theme").c_str()); theme(check_path(Settings.device_dat + ":/config/HBF/themes/") + Options.theme + "/"); } if(get_setting(source, "language") != "") { sprintf (Options.language, get_setting(source, "language").c_str()); ini_Open(check_path(Settings.device_dat + ":/config/HBF/languages/") + Options.language + ".lang"); AvailableCategory.categories[0] = tr(Settings.category_name_all); } if(get_setting(source, "font") != "") sprintf (Options.font, get_setting(source, "font").c_str()); if(get_setting(source, "slide_effect") != "") Options.slide_effect = atoi(get_setting(source, "slide_effect").c_str()); if(get_setting(source, "last_category_name") != "") { if(KategorieNr(get_setting(source, "last_category_name")) != -1) Settings.current_category = KategorieNr(get_setting(source, "last_category_name").c_str()); } if(get_setting(source, "last_category") != "") { Options.last_category = atoi(get_setting(source, "last_category").c_str()); if(Options.last_category == 1) Options.last_category = Settings.current_category +1; } if(get_setting(source, "last_app_name") != "") Settings.startingAppName = get_setting(source, "last_app_name"); if(get_setting(source, "apps_nr") != "") { Options.apps = atoi(get_setting(source, "apps_nr").c_str()); if(Options.apps > 5) Options.apps = 5; else if(Options.apps < 4) Options.apps = 4; } if(get_setting(source, "quick_start") != "") Options.quick_start = atoi(get_setting(source, "quick_start").c_str()); if(get_setting(source, "show_all") != "") Options.show_all = atoi(get_setting(source, "show_all").c_str()); if(get_setting(source, "navigation") != "") Options.navigation = atoi(get_setting(source, "navigation").c_str()); if(get_setting(source, "sdgecko") != "") Options.sdgecko = atoi(get_setting(source, "sdgecko").c_str()); #ifndef VWII if(get_setting(source, "bootmii_boot2") != "") Options.bootmii_boot2 = atoi(get_setting(source, "bootmii_boot2").c_str()); #endif if(get_setting(source, "network") != "") { Options.network = atoi(get_setting(source, "network").c_str()); Options.temp_network = Options.network; } if(get_setting(source, "wifigecko") != "") { Options.wifigecko = atoi(get_setting(source, "wifigecko").c_str()); Options.temp_wifigecko = Options.wifigecko; } if(get_setting(source, "newrevtext") != "") { Options.newrevtext = atoi(get_setting(source, "newrevtext").c_str()); Options.temp_newrevtext = Options.newrevtext; } if(get_setting(source, "code") != "") { sprintf (Settings.code, get_setting(source, "code").c_str()); strcpy (Options.temp_code, Settings.code); } if(get_setting(source, "grid") != "") Settings.grid = atoi(get_setting(source, "grid").c_str()); if(get_setting(source, "device") != "") Settings.device = get_setting(source, "device"); if(get_setting(source, "device_icon") != "") Options.device_icon = atoi(get_setting(source, "device_icon").c_str()); if(get_setting(source, "wiiload_ahb") != "") Options.wiiload_ahb = atoi(get_setting(source, "wiiload_ahb").c_str()); if(get_setting(source, "wiiload_ios") != "") Options.wiiload_ios = atoi(get_setting(source, "wiiload_ios").c_str()); if(get_setting(source, "system") != "") Settings.system = atoi(get_setting(source, "system").c_str()); if(get_setting(source, "top") != "") Settings.top = atoi(get_setting(source, "top").c_str()); if(get_setting(source, "bottom") != "") Settings.bottom = atoi(get_setting(source, "bottom").c_str()); if(get_setting(source, "left") != "") Settings.left = atoi(get_setting(source, "left").c_str()); if(get_setting(source, "right") != "") Settings.right = atoi(get_setting(source, "right").c_str()); } // get appios fd = ISFS_Open(Settings.ios_dat.c_str(), ISFS_OPEN_READ); if (fd <= 0) ISFS_Close(fd); ISFS_GetFileStats(fd, &filestats_appios); file_size = ISFS_Read(fd, filearray_appios, filestats_appios.file_length); ISFS_Close(fd); if(file_size >= 0) { string line; istringstream in((char*)filearray_appios); while(getline(in, line)) appios.push_back(app_ios(line.substr(0, line.find(" = ")), atoi(line.substr(line.find(" = ") +3).c_str()))); } }
s32 nand_copy(const char *source, const char *destination,Nand_Permissions src_perm) { //variables u8 *buffer = NULL; STACK_ALIGN(fstats,status,sizeof(fstats),32); s32 file_handler, ret; u32 FileHash_D1[5]; memset(FileHash_D1,0,5); u32 FileHash_D2[5]; memset(FileHash_D2,0xFF,5); //place different data in D2 so that if something goes wrong later on, the comparison will fail SHA1 sha; sha.Reset(); //variables - temp dir & SHA1 check char temp_dest[ISFS_MAXPATH]; memset(temp_dest,0,ISFS_MAXPATH); char *ptemp = NULL; u8 temp = 0; //get temp filename ptemp = strstr(destination,"/"); while(ptemp != NULL && strstr(ptemp+1,"/") != NULL) { ptemp = strstr(ptemp+1,"/"); } if(ptemp[0] == '/') { ptemp = ptemp+1; } memset(temp_dest,0,ISFS_MAXPATH); sprintf(temp_dest,"/tmp/%s",ptemp); //get data into pointer from original file file_handler = ISFS_Open(source,ISFS_OPEN_READ); if (file_handler < 0) { gprintf("failed to open source : %s\n",source); return file_handler; } ret = ISFS_GetFileStats(file_handler,status); if (ret < 0) { printf("\n\nFailed to get information about %s!\n",source); sleepx(2); ISFS_Close(file_handler); return ret; } buffer = (u8 *)memalign(32,ALIGN32(status->file_length)); if (buffer == NULL) { gprintf("buffer failed to align\n"); sleepx(2); ISFS_Close(file_handler); return 0; } memset(buffer,0,status->file_length); ret = ISFS_Read(file_handler,buffer,status->file_length); if (ret < 0) { printf("\n\nFailed to Read Data from %s!\n",source); sleepx(2); ISFS_Close(file_handler); free(buffer); buffer = NULL; return ret; } ISFS_Close(file_handler); //everything read into buffer. generate SHA1 hash of the buffer sha.Input(buffer,status->file_length); if (!sha.Result(FileHash_D1)) { gprintf("could not compute Hash of D1!\n"); free(buffer); buffer = NULL; return -80; } sha.Reset(); //done, lets create temp file and write :') ISFS_Delete(temp_dest); ISFS_CreateFile(temp_dest,src_perm.attributes,src_perm.ownerperm,src_perm.groupperm,src_perm.otherperm); //created. opening it... file_handler = ISFS_Open(temp_dest,ISFS_OPEN_RW); if (file_handler < 0) { gprintf("failed to open destination : %s\n",temp_dest); ISFS_Delete(temp_dest); free(buffer); buffer = NULL; return file_handler; } ret = ISFS_Write(file_handler,buffer,status->file_length); if (ret < 0) { gprintf("failed to write destination : %s\n",destination); ISFS_Close(file_handler); ISFS_Delete(temp_dest); free(buffer); buffer = NULL; return ret; } //write done. reopen file for reading and compare SHA1 hash ISFS_Close(file_handler); free(buffer); buffer = NULL; memset(status,0,sizeof(fstats)); file_handler = ISFS_Open(temp_dest,ISFS_OPEN_READ); if(!file_handler) { temp = -1; goto free_and_Return; } ret = ISFS_GetFileStats(file_handler,status); if (ret < 0) { ISFS_Close(file_handler); temp = -2; goto free_and_Return; } buffer = (u8 *)memalign(32,ALIGN32(status->file_length)); if (buffer == NULL) { gprintf("buffer failed to align\n"); ISFS_Close(file_handler); temp = -3; goto free_and_Return; } memset(buffer,0,status->file_length); if( ISFS_Read(file_handler,buffer,status->file_length) < 0 ) { temp = -4; goto free_and_Return; } ISFS_Close(file_handler); sha.Reset(); sha.Input(buffer,status->file_length); free(buffer); buffer = NULL; if (!sha.Result(FileHash_D2)) { gprintf("could not compute Hash of D2!\n"); return -80; } sha.Reset(); /*gprintf("sha1 original : %x %x %x %x %x\nsha1 written : %x %x %x %x %x\n", FileHash_D1[0],FileHash_D1[1],FileHash_D1[2],FileHash_D1[3],FileHash_D1[4], FileHash_D2[0],FileHash_D2[1],FileHash_D2[2],FileHash_D2[3],FileHash_D2[4]);*/ if (!memcmp(FileHash_D1,FileHash_D2,sizeof(FileHash_D1))) { gprintf("nand_copy : SHA1 hash success\n"); ISFS_Delete(destination); ret = ISFS_Rename(temp_dest,destination); gprintf("ISFS_Rename ret %d\n",ret); if ( ret < 0) temp = -5; goto free_and_Return; } else { temp = -6; goto free_and_Return; } free_and_Return: if(buffer) { free(buffer); buffer = NULL; } if (temp < 0) { gprintf("nand_copy temp %d fail o.o;\n",temp); ISFS_Delete(temp_dest); return -80; } return 1; }
return ERR_NONE; } void changeChannelName(u64 titleID) { printf("Identifying as 00000001-00000000 (SU)!... "); CheckESRetval(ES_Identify(SU_IDENTIFY)); // if(ES_SetUID(titleID)<0) // return; u32 tmd_size ATTRIBUTE_ALIGN(32); if(CheckESRetval(ES_GetStoredTMDSize(titleID, &tmd_size))!=0) return; signed_blob *TMD = (signed_blob *)memalign( 32, tmd_size ); memset(TMD, 0, tmd_size); if(CheckESRetval(ES_GetStoredTMD(titleID, TMD, tmd_size))!=0) { free(TMD); return; } u32 cnt ATTRIBUTE_ALIGN(32); if(CheckESRetval(ES_GetNumTicketViews(titleID, &cnt))!=0) { free(TMD); return; } if( cnt <= 0 ) { free(TMD); return; } tikview *views = (tikview *)memalign( 32, sizeof(tikview)*cnt ); if(CheckESRetval(ES_GetTicketViews(titleID, views, cnt))!=0) { free(views); free(TMD); return; } char *name=calloc((0x54/2),1); int z; for(z=0; z < 1; ++z) { tmd_content *TMDc = TMD_CONTENTS(((tmd*)(SIGNATURE_PAYLOAD(TMD)))); // OH GOD CREDIAR, WTF WAS THAT MESS!!! //printf("%d,",TMDc->index); s32 cfd = ES_OpenTitleContent( titleID, TMDc->index); free(views); if(CheckESRetval(cfd)!=0) { ; //printf("ES_OpenContent(%d) failed\n", cfd); //sleep(10); //exit(0); } else { u64 sz ATTRIBUTE_ALIGN(32) = 0x140; u8 *data = (u8*)memalign(32, sz); if( TMDc->size < sz ) sz = TMDc->size; if( data != NULL ) { if(ES_ReadContent(cfd, data, sz)<0) { free(data); return; } int y; int chan_name_offset=(language_setting*0x54); // Set to WiiMU's language for(y=0;y<(0x54/2);y++) name[y]=data[(0x9C+chan_name_offset)+(y*2)+1]; } if(CheckESRetval(ES_CloseContent(cfd))!=0) { ; //printf("ES_CloseContent failed\n"); //sleep(10); //exit(0); } free(data); } } int wiistring_size; reenter: wiistring_size=type_string_wiimote(name, 0x54/2); if(wiistring_size<=0) { printf("\n\nPlease enter a name!\n"); sleep(3); goto reenter; } name[wiistring_size+1]=0; /* Get Content */ char nameDirectory[80]; tmd_content *TMDc = TMD_CONTENTS(((tmd*)(SIGNATURE_PAYLOAD(TMD)))); sprintf(nameDirectory,"/title/%08x/%08x/content/%08x.app",TITLE_UPPER(titleID),TITLE_LOWER(titleID),TMDc->cid); s32 contentFd=ISFS_Open(nameDirectory,ISFS_OPEN_RW); CheckISFSRetval(contentFd); ClearScreen(); printf("\n\nOpened content!\n"); u8 *data=calloc(TMDc->size,1); int isUnaligned = ((int)data)%32 | TMDc->size%32; int alignedLen = (TMDc->size+31)&0xffffffe0; u8* alignedBuf; if(isUnaligned) alignedBuf = memalign(32, alignedLen); else alignedBuf = data; CheckISFSRetval(ISFS_Seek(contentFd,0,0)); CheckISFSRetval(ISFS_Read(contentFd, alignedBuf, alignedLen)); printf("Read content!\n"); int y; int chan_name_offset=(SYSCONF_GetArea()*0x54); // Edits the one for the Wii's system Menu char* nameOut=calloc(96,1); for(y=0;y<(0x54/2);y++) nameOut[(y*2)+1]=name[y]; printf("Wrote new name! %s\n", name); CheckISFSRetval(ISFS_Seek(contentFd,(0x9C+chan_name_offset),0)); printf("Seeked to location!\n"); if(nameOut==NULL) { printf("FAILED! (Name Out is NULL!)\n"); sleep(5); Finish(1); } if(((u32)nameOut%32)!=0) { isUnaligned = ((int)nameOut)%32 | 0x54%32; alignedLen = (0x54+31)&0xffffffe0; if(isUnaligned){ alignedBuf = memalign(32, alignedLen); memcpy(alignedBuf, nameOut, 0x54); } else alignedBuf = (u8*)nameOut; } CheckISFSRetval(ISFS_Write(contentFd, alignedBuf, 0x54)); printf("Wrote content name!\nReading new Header Chunk!\n"); CheckISFSRetval(ISFS_Seek(contentFd,0,0)); CheckISFSRetval(ISFS_Read(contentFd, alignedBuf, alignedLen)); printf("Read content!\n"); u8* header_chunk=calloc(0x640, 1); int i; for(i=0;i<0x630;i++) header_chunk[i]=alignedBuf[i]; for(i=0x630;i<0x640;i++) header_chunk[i]=0; u8* hash=calloc(0x10,1); md5(header_chunk, 0x640, hash); CheckISFSRetval(ISFS_Seek(contentFd,0x630,0)); printf("Seeked to location!\n"); if(hash==NULL) { printf("FAILED! (Hash is NULL!)\n"); sleep(5); Finish(1); } if(((u32)hash%32)!=0) { isUnaligned = ((int)hash)%32 | 0x10%32; alignedLen = (0x10+31)&0xffffffe0; if(isUnaligned){ alignedBuf = memalign(32, alignedLen); memcpy(alignedBuf, hash, 0x10); } else alignedBuf = hash;
s8 PatchTMD( u8 delete_mode ) { Nand_Permissions Perm; memset(&Perm,0,sizeof(Nand_Permissions)); u8 SaveTmd = 0; SHA1 sha; // SHA-1 class sha.Reset(); u32 FileHash[5]; u8 *TMD_chk = NULL; s32 fd = 0; s32 r = 0; #ifdef _DEBUG gprintf("Path : %s\n",TMD_Path); #endif r = ISFS_GetAttr(TMD_Path, &Perm.owner, &Perm.group, &Perm.attributes, &Perm.ownerperm, &Perm.groupperm, &Perm.otherperm); if(r < 0 ) { //attribute getting failed. returning to default printf("\x1b[%u;%dm", 33, 1); printf("\nWARNING : failed to get file's permissions. using defaults\n"); printf("\x1b[%u;%dm", 37, 1); gprintf("permission failure on desination! error %d\n",r); gprintf("writing with max permissions\n"); Perm.ownerperm = 3; Perm.groupperm = 3; Perm.otherperm = 0; } else { gprintf("r %d owner %d group %d attributes %X perm:%X-%X-%X\n", r, Perm.owner, Perm.group, Perm.attributes, Perm.ownerperm, Perm.groupperm, Perm.otherperm); } if(delete_mode == 0) { gprintf("patching TMD...\n"); printf("Patching TMD..."); } else { //return 1; gprintf("restoring TMD...\n"); printf("Restoring System Menu TMD...\n"); } fd = ISFS_Open(TMD_Path2,ISFS_OPEN_READ); if(fd < 0) { if(delete_mode) { printf("TMD backup not found. leaving TMD alone...\n"); return 1; } else { //got to make tmd copy :) gprintf("Making tmd backup...\n"); r = nand_copy(TMD_Path2,tmd_buf,tmd_size,Perm); if ( r < 0) { gprintf("Failure making TMD backup.error %d\n",r); printf("TMD backup/Patching Failure : error %d",r); goto _return; } } fd = 0; } ISFS_Close(fd); gprintf("TMD backup found\n"); //not so sure why we'd want to delete the tmd modification but ok... if(delete_mode) { if ( nand_copy(TMD_Path2,TMD_Path,Perm) < 0) { if(r == -80) { //checksum issues printf("\x1b[%u;%dm", 33, 1); printf("\nWARNING!!\nInstaller could not calculate the Checksum when restoring the TMD back!\n"); printf("the TMD however was copied...\n"); printf("Do you want to Continue ?\n"); printf("A = Yes B = No\n "); printf("\x1b[%u;%dm", 37, 1); if(!UserYesNoStop()) { nand_copy(TMD_Path,TMD_Path2,Perm); abort("TMD restoring failure."); } } else { printf("\x1b[%u;%dm", 33, 1); printf("UNABLE TO RESTORE THE SYSTEM MENU TMD!!!\n\nTHIS COULD BRICK THE WII SO PLEASE REINSTALL SYSTEM MENU\nWHEN RETURNING TO THE HOMEBREW CHANNEL!!!\n\n"); printf("\x1b[%u;%dm", 37, 1); printf("press A to return to the homebrew channel\n"); nand_copy(TMD_Path,TMD_Path2,Perm); UserYesNoStop(); exit(0); } } else ISFS_Delete(TMD_Path2); return 1; } else { //check if version is the same STACK_ALIGN(fstats,TMDb_status,sizeof(fstats),32); static u8 tmdb_buf[MAX_SIGNED_TMD_SIZE] ATTRIBUTE_ALIGN(32); static signed_blob *mbTMD; static tmd* pbTMD; fd = ISFS_Open(TMD_Path2,ISFS_OPEN_READ); if (fd < 0) { gprintf("TMD bCheck : failed to open source : %s\n",TMD_Path2); goto patch_tmd; } r = ISFS_GetFileStats(fd,TMDb_status); if (r < 0) { gprintf("TMD bCheck : Failed to get information about %s!\n",TMD_Path2); ISFS_Close(fd); goto patch_tmd; } memset(tmdb_buf,0,MAX_SIGNED_TMD_SIZE); r = ISFS_Read(fd,tmdb_buf,TMDb_status->file_length); if (r < 0) { gprintf("TMD bCheck : Failed to Read Data from %s!\n",TMD_Path2); ISFS_Close(fd); goto patch_tmd; } ISFS_Close(fd); mbTMD = (signed_blob *)tmdb_buf; pbTMD = (tmd*)SIGNATURE_PAYLOAD(mbTMD); if (pbTMD->title_version != rTMD->title_version) { gprintf("TMD bCheck : backup TMD version mismatch: %d & %d\n",rTMD->title_version,pbTMD->title_version); //got to make tmd copy :) r = nand_copy(TMD_Path2,tmd_buf,tmd_size,Perm); if ( r < 0) { gprintf("TMD bCheck : Failure making TMD backup.error %d\n",r); printf("TMD backup/Patching Failure : error %d",r); goto _return; } } else gprintf("TMD bCheck : backup TMD is correct\n"); r = 0; } patch_tmd: gprintf("detected access rights : 0x%08X\n",rTMD->access_rights); if(rTMD->access_rights == 0x03) { gprintf("no AHBPROT modification needed\n"); } else { rTMD->access_rights = 0x03; DCFlushRange(rTMD,sizeof(tmd)); if(rTMD->access_rights != 0x03) { gprintf("rights change failure.\n"); goto _return; } SaveTmd++; } gprintf("checking Boot app SHA1 hash...\n"); gprintf("bootapp ( %d ) SHA1 hash = %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x\n",rTMD->boot_index ,rTMD->contents[rTMD->boot_index].hash[0],rTMD->contents[rTMD->boot_index].hash[1],rTMD->contents[rTMD->boot_index].hash[2],rTMD->contents[rTMD->boot_index].hash[3] ,rTMD->contents[rTMD->boot_index].hash[4],rTMD->contents[rTMD->boot_index].hash[5],rTMD->contents[rTMD->boot_index].hash[6],rTMD->contents[rTMD->boot_index].hash[7] ,rTMD->contents[rTMD->boot_index].hash[8],rTMD->contents[rTMD->boot_index].hash[9],rTMD->contents[rTMD->boot_index].hash[10],rTMD->contents[rTMD->boot_index].hash[11] ,rTMD->contents[rTMD->boot_index].hash[12],rTMD->contents[rTMD->boot_index].hash[13],rTMD->contents[rTMD->boot_index].hash[14],rTMD->contents[rTMD->boot_index].hash[15] ,rTMD->contents[rTMD->boot_index].hash[16],rTMD->contents[rTMD->boot_index].hash[17],rTMD->contents[rTMD->boot_index].hash[18],rTMD->contents[rTMD->boot_index].hash[19]); gprintf("generated priiloader SHA1 : "); sha.Reset(); sha.Input(priiloader_app,priiloader_app_size); if (!sha.Result(FileHash)) { gprintf("could not compute Hash of Priiloader!\n"); r = -1; goto _return; } if (!memcmp(rTMD->contents[rTMD->boot_index].hash, FileHash, sizeof(FileHash) ) ) { gprintf("no SHA hash change needed\n"); } else { memcpy(rTMD->contents[rTMD->boot_index].hash,FileHash,sizeof(FileHash)); gprintf("%08x %08x %08x %08x %08x\n",FileHash[0],FileHash[1],FileHash[2],FileHash[3],FileHash[4]); DCFlushRange(rTMD,sizeof(tmd)); SaveTmd++; } if(SaveTmd > 0) { gprintf("saving TMD\n"); r = nand_copy(TMD_Path,tmd_buf,tmd_size,Perm); if(r < 0 ) { gprintf("nand_copy failure. error %d\n",r); if(r == -80) goto _checkreturn; else goto _return; } } else { gprintf("no TMD mod's needed\n"); printf("no TMD modifications needed\n"); goto _return; } printf("Done\n"); _return: if (fd < r) { r = fd; } if(fd) { ISFS_Close(fd); } if (r < 0) { printf("\x1b[%u;%dm", 33, 1); printf("\nWARNING!!\nInstaller couldn't Patch the system menu TMD.\n"); printf("Priiloader could still end up being installed but could end up working differently\n"); printf("Do you want the Continue ?\n"); printf("A = Yes B = No\n "); printf("\x1b[%u;%dm", 37, 1); if(!UserYesNoStop()) { fd = ISFS_Open(TMD_Path2,ISFS_OPEN_RW); if(fd >= 0) { //the backup is there. as safety lets copy it back. ISFS_Close(fd); nand_copy(TMD_Path2,TMD_Path,Perm); } abort("TMD failure"); return -1; } else { nand_copy(TMD_Path2,TMD_Path,Perm); printf("\nDone!\n"); return 1; } return r; } else return 1; _checkreturn: if(fd) { ISFS_Close(fd); } if(TMD_chk) { free(TMD_chk); TMD_chk = NULL; } printf("\x1b[%u;%dm", 33, 1); printf("\nWARNING!!\n Installer could not calculate the Checksum for the TMD!"); printf("\nbut Patch write was successfull.\n"); printf("Do you want the Continue ?\n"); printf("A = Yes B = No\n "); printf("\x1b[%u;%dm", 37, 1); if(!UserYesNoStop()) { printf("reverting changes...\n"); nand_copy(TMD_Path2,TMD_Path,Perm); abort("TMD Patch failure\n"); } else { printf("\nDone!\n"); } return -80; }
DRESULT disk_read(BYTE drv,BYTE *buff, DWORD sector, BYTE count) { int retval = 0; #ifdef DEBUG printf("disk read sector %x num %x\n", (unsigned int)sector, (unsigned int)count); #endif if(sector==0)return diskio_generatefatsector(drv, sector, buff); if(sector==1 && vff_fat_types[(int)drv]==32)return diskio_generatefatsector(drv, sector, buff); sector--; if((sector>0 && sector<31) && vff_fat_types[(int)drv]==32) { memset(buff, 0, count*0x200); return 0; } if(sector>=31 && vff_fat_types[(int)drv]==32)sector-=31; //sector-=2; #ifdef HW_RVL if(vff_types[(int)drv]==0) { retval = ISFS_Seek((s32)disk_vff_handles[(int)drv], 0x20 + (sector*0x200), SEEK_SET); if(retval<0) { #ifdef DEBUG printf("seek fail\n"); #endif return RES_PARERR; } } #endif if(vff_types[(int)drv]==1) { retval = fseek((FILE*)disk_vff_handles[(int)drv], 0x20 + (sector*0x200), SEEK_SET); if(retval<0)return RES_PARERR; } if(vff_types[(int)drv]==1) { retval = fread(buff, 0x200, count, (FILE*)disk_vff_handles[(int)drv]); if(retval!=(0x200 * count))return RES_PARERR; } else { while(count>0) { #ifdef HW_RVL retval = ISFS_Read((s32)disk_vff_handles[(int)drv], diskio_buffer, 0x200); #endif if(retval!=0x200) { #ifdef DEBUG printf("read only %x bytes, wanted %x bytes\n", retval, 0x200); #endif return RES_PARERR; } memcpy(buff, diskio_buffer, 0x200); buff+=0x200; count--; } } return 0; }