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); } }
int fileBrowser_WiiFS_writeFile(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); memcpy(alignedBuf, buffer, length); } else alignedBuf = buffer; // Make sure the filename is 8.3 and open the short filename shrinkFilename( &file->name ); char* name = getAlignedName(&file->name); int f = ISFS_Open( name, 2 ); if(f < 0){ // Create rw file: rwrwr- if((f = ISFS_CreateFile( name, 0, 1|2, 1|2, 1 )) < 0) return FILE_BROWSER_ERROR; else f = ISFS_Open( name, 2 ); } // Do the actual write, from the aligned buffer if need be ISFS_Seek(f, file->offset, 0); int bytes_read = ISFS_Write(f, alignedBuf, alignedLen); if(bytes_read > 0) file->offset += bytes_read; // Clean up if(isUnaligned) free(alignedBuf); ISFS_Close(f); return bytes_read; }
s8 RemovePriiloader ( void ) { s32 fd = 0; Nand_Permissions SysPerm; memset(&SysPerm,0,sizeof(Nand_Permissions)); SysPerm.otherperm = 3; SysPerm.groupperm = 3; SysPerm.ownerperm = 3; printf("Restoring System menu app..."); s32 ret = nand_copy(copy_app,original_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 when coping the System menu app\n"); printf("back! the app 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()) { printf("reverting changes...\n"); ISFS_Close(fd); ISFS_CreateFile(original_app,0,3,3,3); fd = ISFS_Open(original_app,ISFS_OPEN_RW); ISFS_Write(fd,priiloader_app,priiloader_app_size); ISFS_Close(fd); abort("System Menu Copying Failure"); } } else { ISFS_CreateFile(original_app,0,3,3,3); fd = ISFS_Open(original_app,ISFS_OPEN_RW); ISFS_Write(fd,priiloader_app,priiloader_app_size); ISFS_Close(fd); abort("\nUnable to restore the system menu! (ret = %d)",ret); } } ret = ISFS_Delete(copy_app); printf("Done!\n"); return 1; }
void NandSave::WriteFile(const char *file_name, u8 *content, u32 size) { memset(&ISFS_Path, 0, ISFS_MAXPATH); if(file_name == NULL || content == NULL || size == 0) return; strcpy(ISFS_Path, file_name); ISFS_CreateFile(ISFS_Path, 0, 3, 3, 3); fd = ISFS_Open(ISFS_Path, ISFS_OPEN_WRITE); if(fd < 0) return; ret = ISFS_Write(fd, content, size); ISFS_Close(fd); if(ret < 0) ISFS_Delete(ISFS_Path); }
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 SetNandBootInfo(void) { static NANDBootInfo BootInfo ATTRIBUTE_ALIGN(32); memset(&BootInfo,0,sizeof(NANDBootInfo)); BootInfo.apptype = 0x80; BootInfo.titletype = 2; if(ES_GetTitleID(&BootInfo.launcher) < 0) BootInfo.launcher = 0x0000000100000002LL; BootInfo.checksum = __CalcChecksum((u32*)&BootInfo,sizeof(NANDBootInfo)); s32 fd = ISFS_Open("/shared2/sys/NANDBOOTINFO", ISFS_OPEN_RW ); if(fd < 0) { return fd; } s32 ret = ISFS_Write(fd, &BootInfo, sizeof(NANDBootInfo)); if(ret < 0) { ISFS_Close(fd); gprintf("SetNandBootInfo : ISFS_Write returned %d\n",ret); return -2; } ISFS_Close(fd); 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;
DRESULT disk_write(BYTE drv, const BYTE *buff, DWORD sector, BYTE count) { int retval = 0; #ifdef DEBUG printf("disk write sector %x num %x\n", (unsigned int)sector, (unsigned int)count); #endif if(sector==0)return 0; if(sector==1 && vff_fat_types[(int)drv]==32)return 0; sector--; if((sector>=0 && sector<31) && vff_fat_types[(int)drv]==32) { 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 = fwrite(buff, 0x200, count, (FILE*)disk_vff_handles[(int)drv]); if(retval!=(0x200 * count))return RES_PARERR; } else { while(count>0) { memcpy(diskio_buffer, buff, 0x200); #ifdef HW_RVL retval = ISFS_Write((s32)disk_vff_handles[(int)drv], diskio_buffer, 0x200); #endif if(retval!=0x200) { #ifdef DEBUG printf("wrote only %x bytes, wanted %x bytes\n", retval, 0x200); #endif return RES_PARERR; } buff+=0x200; count--; } } return 0; }
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; }
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; }
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; }
static int identify(void){ // Identify as our own title void* dvdCert = NULL, * dvdTMD = NULL, * dvdTicket = NULL; unsigned int dvdCertSize, dvdTMDSize, dvdTicketSize, keyid; int ret; if(!customCert){ // If there's no certificate supplied #if 0 // Use the one from the DVD ret = getTitle(&dvdCert, &dvdCertSize, &dvdTMD, &dvdTMDSize, &dvdTicket, &dvdTicketSize); customCert = dvdCert; customCertSize = dvdCertSize; if(ret < 0) return ret; #else return identified = 0; #endif } ret = ES_Identify(customCert, customCertSize, customTMD, customTMDSize, customTicket, customTicketSize, &keyid); if(ret >= 0){ ES_GetTitleID(&titleID); ISFS_Initialize(); // If we haven't identified this title before // we'll need to set some things up char* path = memalign(32, 64);; ES_GetDataDir(titleID, path); strncat(path, "/banner.bin", 64); ret = ISFS_Open(path, 1); if(ret < 0){ // If the banner doesn't exist // Create our banner.bin ret = ISFS_CreateFile(path, 0, 3, 3, 1); if(ret < 0) return 0; ret = ISFS_Open(path, 2); if(ret < 0) return 0; ISFS_Write(ret, customBanner, customBannerSize); ISFS_Close(ret); // Create the N64SAVES directory ES_GetDataDir(titleID, path); strncat(path, "/N64SAVES", 64); ISFS_CreateDir(path, 0, 3, 3, 1); } else ISFS_Close(ret); free(path); return identified = 1; } #if 0 // If that still fails, try to identify from the discs certs if(!dvdCert || !dvdTMD || !dvdTicket) ret = getTitle(&dvdCert, &dvdCertSize, &dvdTMD, &dvdTMDSize, &dvdTicket, &dvdTicketSize); else ret = 0; if(ret >= 0){ ret = ES_Identify(dvdCert, dvdCertSize, dvdTMD, dvdTMDSize, dvdTicket, dvdTicketSize, &keyid); ES_GetTitleID(&titleID); ISFS_Initialize(); return identified = (ret >= 0); } #endif return identified = 0; }
bool NandSave::CheckSave() { /* 10 million variables */ u32 u8_bin_size = 0; u8 *u8_bin = NULL; u32 certSize = 0; signed_blob *certBuffer = NULL; u32 tmd_bin_size = 0; const signed_blob *tmd_bin = NULL; u32 tik_bin_size = 0; const signed_blob *tik_bin = NULL; u32 banner_bin_size = 0; const u8 *banner_bin = NULL; u32 entries = 0; /* May our banner already exist */ memset(&ISFS_Path, 0, ISFS_MAXPATH); strcpy(ISFS_Path, BANNER_PATH); fd = ISFS_Open(ISFS_Path, ISFS_OPEN_READ); if(fd >= 0) { ISFS_Close(fd); gprintf("Found WiiFlow Save\n"); goto done; } /* extract our archive */ u8_bin = DecompressCopy(save_bin, save_bin_size, &u8_bin_size); if(u8_bin == NULL || u8_bin_size == 0) goto error; /* grab cert.sys */ memset(&ISFS_Path, 0, ISFS_MAXPATH); strcpy(ISFS_Path, "/sys/cert.sys"); certBuffer = (signed_blob*)ISFS_GetFile(ISFS_Path, &certSize, -1); if(certBuffer == NULL || certSize == 0) goto error; /* Install tik and tmd */ tik_bin = (const signed_blob*)u8_get_file(u8_bin, "tik.bin", &tik_bin_size); if(tik_bin == NULL || tik_bin_size == 0) goto error; ret = ES_AddTicket(tik_bin, tik_bin_size, certBuffer, certSize, NULL, 0); if(ret < 0) goto error; tmd_bin = (const signed_blob*)u8_get_file(u8_bin, "tmd.bin", &tmd_bin_size); if(tmd_bin == NULL || tmd_bin_size == 0) goto error; ret = ES_AddTitleStart(tmd_bin, tmd_bin_size, certBuffer, certSize, NULL, 0); if(ret < 0) goto error; ret = ES_AddTitleFinish(); if(ret < 0) goto error; /* WARNING dirty, delete tik again */ memset(&ISFS_Path, 0, ISFS_MAXPATH); strcpy(ISFS_Path, "/ticket/00010000/57465346.tik"); ret = ISFS_Delete(ISFS_Path); if(ret < 0) goto error; /* Delete the unused ticket folder */ memset(&ISFS_Path, 0, ISFS_MAXPATH); strcpy(ISFS_Path, "/ticket/00010000"); ret = ISFS_ReadDir(ISFS_Path, NULL, &entries); if(ret < 0) goto error; if(entries == 0) { ret = ISFS_Delete(ISFS_Path); if(ret < 0) goto error; } banner_bin = u8_get_file(u8_bin, "banner.bin", &banner_bin_size); if(banner_bin == NULL || banner_bin_size == 0) goto error; memset(&ISFS_Path, 0, ISFS_MAXPATH); strcpy(ISFS_Path, BANNER_PATH); /* Write our banner */ ISFS_CreateFile(ISFS_Path, 0, 3, 3, 3); fd = ISFS_Open(ISFS_Path, ISFS_OPEN_WRITE); if(fd < 0) goto error; ret = ISFS_Write(fd, banner_bin, banner_bin_size); ISFS_Close(fd); if(ret < 0) { ISFS_Delete(ISFS_Path); goto error; } free(certBuffer); if(u8_bin != save_bin) free(u8_bin); gprintf("Created WiiFlow Save\n"); done: loaded = true; return loaded; error: gprintf("Error while creating WiiFlow Save\n"); loaded = false; ES_AddTitleCancel(); if(certBuffer != NULL) free(certBuffer); certBuffer = NULL; if(u8_bin != NULL) free(u8_bin); u8_bin = NULL; tik_bin = NULL; tmd_bin = NULL; banner_bin = NULL; return loaded; }
s32 Downgrade_TMD_Revision(void *ptmd, u32 tmd_size, void *certs, u32 certs_size) { // The revison of the tmd used as paramter here has to be >= the revision of the installed tmd s32 ret; printf("Setting the revision to 0...\n"); ret = ES_AddTitleStart(ptmd, tmd_size, certs, certs_size, NULL, 0); if (ret < 0) { if (ret == -1035) { printf("Error: ES_AddTitleStart returned %d, maybe you need an updated Downgrader\n", ret); } else { printf("Error: ES_AddTitleStart returned %d\n", ret); } ES_AddTitleCancel(); return ret; } s32 file; char *tmd_path = "/tmp/title.tmd"; ret = ISFS_Delete(tmd_path); if (ret < 0) { printf("Error: ISFS_Delete returned %d\n", ret); ES_AddTitleCancel(); ISFS_Deinitialize(); return ret; } ret = ISFS_CreateFile(tmd_path, 0, 3, 3, 3); if (ret < 0) { printf("Error: ISFS_CreateFile returned %d\n", ret); ES_AddTitleCancel(); ISFS_Deinitialize(); return ret; } file = ISFS_Open(tmd_path, ISFS_OPEN_RW); if (file < 0) { printf("Error: ISFS_Open returned %d\n", file); ES_AddTitleCancel(); ISFS_Deinitialize(); return file; } u8 *tmd = (u8 *)ptmd; tmd[0x1dc] = 0; tmd[0x1dd] = 0; ret = ISFS_Write(file, (u8 *)ptmd, tmd_size); if (ret < 0) { printf("Error: ISFS_Write returned %d\n", ret); ISFS_Close(file); ES_AddTitleCancel(); ISFS_Deinitialize(); return ret; } ISFS_Close(file); ISFS_Deinitialize(); ret = ES_AddTitleFinish(); if (ret < 0) { printf("Error: ES_AddTitleFinish returned %d\n", ret); return ret; } return 1; }