s32 __usbstorage_GetCapacity(u32 *_sectorSz) { STACK_ALIGN(ioctlv, vector, 1, 32); STACK_ALIGN(u32, buffer, 1, 32); if (fd >= 0) { s32 ret; /* Setup vector */ vector[0].data = buffer; vector[0].len = sizeof(u32); os_sync_after_write(vector, sizeof(ioctlv)); /* Get capacity */ ret = os_ioctlv(fd, USB_IOCTL_UMS_GET_CAPACITY, 0, 1, vector); os_sync_after_write(buffer, sizeof(u32)); /* Set sector size */ sectorSz = buffer[0]; if (ret && _sectorSz) *_sectorSz = sectorSz; return ret; } return IPC_ENOENT; }
bool __usbstorage_Read_Write(u32 sector, u32 numSectors, void *buffer, int write) { STACK_ALIGN(ioctlv, vector, 3, 32); STACK_ALIGN(u32, _sector, 1, 32); STACK_ALIGN(u32, _numSectors, 1, 32); u32 cnt, len = (sectorSz * numSectors); s32 ret; /* Device not opened */ if (fd < 0) return false; /* Sector info */ *_sector = sector; *_numSectors = numSectors; /* Setup vector */ vector[0].data = _sector; vector[0].len = sizeof(u32); vector[1].data = _numSectors; vector[1].len = sizeof(u32); vector[2].data = buffer; vector[2].len = len; /* Flush cache */ for (cnt = 0; cnt < 3; cnt++) os_sync_after_write(vector[cnt].data, vector[cnt].len); os_sync_after_write(vector, sizeof(ioctlv) * 3); if(!write) { /* Read data */ ret = os_ioctlv(fd, USB_IOCTL_UMS_READ_SECTORS, 2, 1, vector); } else { /* Write data */ ret = os_ioctlv(fd, USB_IOCTL_UMS_WRITE_SECTORS, 3, 0, vector); } if (ret < 0) return false; /* Invalidate cache */ for (cnt = 0; cnt < 3; cnt++) os_sync_before_read(vector[cnt].data, vector[cnt].len); return true; }
s32 WII_LaunchTitle(u64 titleID) { s32 res; u32 numviews; STACK_ALIGN(tikview,views,4,32); if(!__initialized) return WII_ENOTINIT; res = ES_GetNumTicketViews(titleID, &numviews); if(res < 0) { return res; } if(numviews > 4) { return WII_EINTERNAL; } res = ES_GetTicketViews(titleID, views, numviews); if(res < 0) return res; VIDEO_SetBlack(1); VIDEO_Flush(); res = ES_LaunchTitle(titleID, &views[0]); if(res < 0) return res; return WII_EINTERNAL; }
/**************************************************************************** * Get network IP ***************************************************************************/ bool ShutdownWC24() { bool onlinefix = IsNetworkInit(); if (onlinefix) { s32 kd_fd, ret; STACK_ALIGN(u8, kd_buf, 0x20, 32); kd_fd = IOS_Open("/dev/net/kd/request", 0); if (kd_fd >= 0) { ret = IOS_Ioctl(kd_fd, 7, NULL, 0, kd_buf, 0x20); if (ret >= 0) onlinefix = false; // fixed no IOS reload needed IOS_Close(kd_fd); } } return onlinefix; }
s32 __IOS_LaunchNewIOS(int version) { u32 numviews; s32 res; u64 titleID = 0x100000000LL; raw_irq_handler_t irq_handler; u32 counter; STACK_ALIGN(tikview,views,4,32); #ifdef DEBUG_IOS s32 oldversion; #endif s32 newversion; if(version < 3 || version > 0xFF) { return IOS_EBADVERSION; } #ifdef DEBUG_IOS oldversion = IOS_GetVersion(); if(oldversion>0) printf("Current IOS Version: IOS%d\n",oldversion); #endif titleID |= version; #ifdef DEBUG_IOS printf("Launching IOS TitleID: %016llx\n",titleID); #endif res = ES_GetNumTicketViews(titleID, &numviews); if(res < 0) { #ifdef DEBUG_IOS printf(" GetNumTicketViews failed: %d\n",res); #endif return res; } if(numviews > 4) { printf(" GetNumTicketViews too many views: %lu\n",numviews); return IOS_ETOOMANYVIEWS; } res = ES_GetTicketViews(titleID, views, numviews); if(res < 0) { #ifdef DEBUG_IOS printf(" GetTicketViews failed: %d\n",res); #endif return res; } write32(0x80003140, 0); res = ES_LaunchTitleBackground(titleID, &views[0]); if(res < 0) { #ifdef DEBUG_IOS printf(" LaunchTitleBackground failed: %d\n",res); #endif return res; } __ES_Reset(); // Mask IPC IRQ while we're busy reloading __MaskIrq(IRQ_PI_ACR); irq_handler = IRQ_Free(IRQ_PI_ACR); #ifdef DEBUG_IOS printf("Waiting for IOS ...\n"); #endif while ((read32(0x80003140) >> 16) == 0) udelay(1000); #ifdef DEBUG_IOS u32 v = read32(0x80003140); printf("IOS loaded: IOS%d v%d.%d\n", v >> 16, (v >> 8) & 0xff, v & 0xff); #endif #ifdef DEBUG_IOS printf("Waiting for IPC ...\n"); #endif for (counter = 0; !(read32(0x0d000004) & 2); counter++) { udelay(1000); if (counter >= MAX_IPC_RETRIES) break; } #ifdef DEBUG_IOS printf("IPC started (%u)\n", counter); #endif IRQ_Request(IRQ_PI_ACR, irq_handler, NULL); __UnmaskIrq(IRQ_PI_ACR); __IPC_Reinitialize(); newversion = IOS_GetVersion(); if(newversion != version) { #ifdef DEBUG_IOS printf(" Version mismatch!\n"); #endif return IOS_EMISMATCH; } return version; }
ER_UINT acre_tsk(const T_CTSK *pk_ctsk) { TCB *p_tcb; TINIB *p_tinib; ATR tskatr; TASK task; PRI itskpri; size_t stksz; STK_T *stk; ER ercd; LOG_ACRE_TSK_ENTER(pk_ctsk); CHECK_TSKCTX_UNL(); tskatr = pk_ctsk->tskatr; task = pk_ctsk->task; itskpri = pk_ctsk->itskpri; stksz = pk_ctsk->stksz; stk = pk_ctsk->stk; CHECK_RSATR(tskatr, TA_ACT|TA_NOACTQUE|TARGET_TSKATR); CHECK_PAR(FUNC_ALIGN(task)); CHECK_PAR(FUNC_NONNULL(task)); CHECK_PAR(VALID_TPRI(itskpri)); CHECK_PAR(stksz >= TARGET_MIN_STKSZ); if (stk != NULL) { CHECK_PAR(STKSZ_ALIGN(stksz)); CHECK_PAR(STACK_ALIGN(stk)); } lock_cpu(); if (queue_empty(&free_tcb)) { ercd = E_NOID; } else { if (stk == NULL) { stk = kernel_malloc(ROUND_STK_T(stksz)); tskatr |= TA_MEMALLOC; } if (stk == NULL) { ercd = E_NOMEM; } else { p_tcb = ((TCB *) queue_delete_next(&free_tcb)); p_tinib = (TINIB *)(p_tcb->p_tinib); p_tinib->tskatr = tskatr; p_tinib->exinf = pk_ctsk->exinf; p_tinib->task = task; p_tinib->ipriority = INT_PRIORITY(itskpri); #ifdef USE_TSKINICTXB init_tskinictxb(&(p_tinib->tskinictxb), stksz, stk); #else /* USE_TSKINICTXB */ p_tinib->stksz = stksz; p_tinib->stk = stk; #endif /* USE_TSKINICTXB */ p_tcb->actque = false; make_dormant(p_tcb); if ((p_tcb->p_tinib->tskatr & TA_ACT) != 0U) { make_active(p_tcb); } ercd = TSKID(p_tcb); } } unlock_cpu(); error_exit: LOG_ACRE_TSK_LEAVE(ercd); return(ercd); }
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; }
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; }
s8 LoadHacks_Hash( bool Force_Load_Nand ) { if( hacks_hash.size() ) //hacks_hash already loaded { hacks_hash.clear(); if(states_hash) { mem_free(states_hash); } } if(foff != 0) foff=0; bool mode = true; s32 fd=0; char *buf=NULL; STACK_ALIGN(fstats,status,sizeof(fstats),32); unsigned int size=0; FILE* in = NULL; if(!Force_Load_Nand) { in = fopen ("fat:/apps/priiloader/hacks_hash.ini","rb"); if(!in) gprintf("fopen error : strerror %s\n",strerror(errno)); } if( !in ) { fd = ISFS_Open("/title/00000001/00000002/data/hackshas.ini", 1 ); if( fd < 0 ) { gprintf("LoadHacks : hacks_hash.ini not on FAT or Nand. ISFS_Open error %d\n",fd); return 0; } mode = false; } if( mode ) //read file from FAT { //read whole file in fseek( in, 0, SEEK_END ); size = ftell(in); fseek( in, 0, 0); if( size == 0 ) { PrintFormat( 1, ((640/2)-((strlen("Error \"hacks_hash.ini\" is 0 byte!"))*13/2))>>1, 208, "Error \"hacks_hash.ini\" is 0 byte!"); sleep(5); return 0; } buf = (char*)mem_align( 32, ALIGN32(size)); if( buf == NULL ) { error = ERROR_MALLOC; return 0; } memset( buf, 0, size ); if(fread( buf, sizeof( char ), size, in ) != size ) { mem_free(buf); PrintFormat( 1, ((640/2)-((strlen("Error reading \"hacks_hash.ini\""))*13/2))>>1, 208, "Error reading \"hacks_hash.ini\""); sleep(5); return 0; }