s32 Title_GetTitleKey(tik *p_tik, u8 *key) { static u8 iv[16] ATTRIBUTE_ALIGN(32); static u8 enc[16] ATTRIBUTE_ALIGN(32); static u8 dec[16] ATTRIBUTE_ALIGN(32); s32 ret; /* Set IV */ memset(iv, 0, sizeof(iv)); memcpy(iv, &p_tik->titleid, sizeof(u64)); /* Set encrypted key */ memset(enc, 0, sizeof(enc)); memcpy(enc, &p_tik->cipher_title_key, sizeof(enc)); /* Clear output buffer */ memset(dec, 0, sizeof(dec)); /* Decrypt title key */ ret = ES_Decrypt(ES_KEY_COMMON, iv, enc, sizeof(enc), dec); if (ret < 0) return ret; /* Copy key */ memcpy(key, dec, sizeof(dec)); return 0; }
void CreateSavePath(const char *basepath, struct dir_discHdr *hdr) { CreateNandPath("%s/import", basepath); CreateNandPath("%s/meta", basepath); CreateNandPath("%s/shared1", basepath); CreateNandPath("%s/shared2", basepath); CreateNandPath("%s/sys", basepath); CreateNandPath("%s/ticket", basepath); CreateNandPath("%s/tmp", basepath); CreateNandPath("%s/title", basepath); const char *titlePath = "/title/00010000"; if( memcmp(hdr->id, "RGW", 3) == 0) titlePath = "/title/00010004"; char fullpath[ISFS_MAXPATH] ATTRIBUTE_ALIGN(32); snprintf(fullpath, sizeof(fullpath), "%s%s", basepath, titlePath); CreateNandPath(fullpath); char nandPath[ISFS_MAXPATH] ATTRIBUTE_ALIGN(32); snprintf(nandPath, sizeof(nandPath), "%s/%02x%02x%02x%02x", fullpath, hdr->id[0], hdr->id[1], hdr->id[2], hdr->id[3]); CreateNandPath(nandPath); CreateNandPath("%s/data", nandPath); CreateNandPath("%s/content", nandPath); strcat(nandPath, "/content/title.tmd"); CreateTitleTMD(nandPath, hdr); }
void RestoreSneekFolder (void) { s32 fd; int ret; char path[ISFS_MAXPATH] ATTRIBUTE_ALIGN(32); char pathBak[ISFS_MAXPATH] ATTRIBUTE_ALIGN(32); Debug ("RestoreSneekFolder [begin]"); ISFS_Initialize (); sprintf (path, "/sneek/nandpath.bin"); ret = ISFS_Delete (path); Debug ("RestoreSneekFolder: delete '%s' = %d", path, ret); sprintf (path, "/sneek/nandcfg.pl"); ret = ISFS_Delete (path); Debug ("RestoreSneekFolder: delete '%s' = %d", path, ret); ret = sprintf (path, "/sneek/nandcfg.ch"); ISFS_Delete (path); Debug ("RestoreSneekFolder: delete '%s' = %d", path, ret); sprintf (path, "/title/00000001/00000002/data/loader.ini"); sprintf (pathBak, "/title/00000001/00000002/data/loader.bak"); fd = ISFS_Open(pathBak, ISFS_OPEN_READ); if (fd > 0) { ISFS_Close(fd); ret = ISFS_Delete (path); Debug ("RestoreSneekFolder: delete '%s' = %d", path, ret); ret = ISFS_Rename (pathBak, path); Debug ("RestoreSneekFolder: rename '%s'->'%s' = %d", pathBak, path, ret); } sprintf (path, "/sneek/nandcfg.bin"); sprintf (pathBak, "/sneek/nandcfg.bak"); fd = ISFS_Open(pathBak, ISFS_OPEN_READ); if (fd > 0) { ISFS_Close(fd); ret = ISFS_Delete (path); Debug ("RestoreSneekFolder: delete '%s' = %d", path, ret); ret = ISFS_Rename (pathBak, path); Debug ("RestoreSneekFolder: rename '%s'->'%s' = %d", pathBak, path, ret); } ISFS_Deinitialize (); Debug ("RestoreSneekFolder [end]"); }
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; }
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 gecko_readrange(u32 memstart, u32 memend) { char pcresponse; static char packetbuffer[packetsize] ATTRIBUTE_ALIGN(32); u32 memrange; u32 fullpackets; u32 currentpacket; u32 lastpacketbytes; memrange = memend - memstart; fullpackets = memrange / packetsize; lastpacketbytes = memrange % packetsize; // Full Packet Size for (currentpacket = 0;currentpacket < fullpackets;) { memcpy(packetbuffer, (char*)memstart, packetsize); usb_sendbuffer_safe(gecko_channel,&packetbuffer, packetsize); usb_recvbuffer_safe(gecko_channel,&pcresponse,1); if(pcresponse != 0xAA){ return 0; } memstart += packetsize; currentpacket++; } // Remainder if(lastpacketbytes > 0) { memcpy(packetbuffer, (char*)memstart, lastpacketbytes); usb_sendbuffer_safe(gecko_channel,&packetbuffer, lastpacketbytes); } return 1; }
static int set_operational(struct ds3wiibt_context *ctx) { static const unsigned char buf[] ATTRIBUTE_ALIGN(32) = { (HIDP_TRANS_SETREPORT | HIDP_DATA_RTYPE_FEATURE), 0xF4, 0x42, 0x03, 0x00, 0x00 }; return senddata_raw(ctx->ctrl_pcb, buf, sizeof(buf)); }
u32 do_bca_code(const char *BCAFilepath, u8 *gameid) { if (!BCAFilepath || !gameid) return 0; if (IOS_GetVersion() == 222 || IOS_GetVersion() == 223) { FILE *fp; u32 filesize; char filepath[150]; memset(filepath, 0, 150); u8 bcaCode[64] ATTRIBUTE_ALIGN( 32 ); // Attempt to open the BCA file using the full game ID. snprintf(filepath, sizeof(filepath), "%s%.6s.bca", BCAFilepath, gameid); fp = fopen(filepath, "rb"); if (!fp) { // Not found. Try again without the system code or company code. snprintf(filepath, sizeof(filepath), "%s%.3s.bca", BCAFilepath, gameid+1); fp = fopen(filepath, "rb"); if (!fp) { // Not found. Use the default BCA. memset(bcaCode, 0, 64); bcaCode[0x33] = 1; } } if (fp) { // BCA file opened. u32 ret = 0; fseek(fp, 0, SEEK_END); filesize = ftell(fp); if (filesize == 64) { fseek(fp, 0, SEEK_SET); ret = fread(bcaCode, 1, 64, fp); } fclose(fp); if (ret != 64) { // Error reading the BCA file. // Use the default BCA. memset(bcaCode, 0, 64); bcaCode[0x33] = 1; } } Set_DIP_BCA_Datas(bcaCode); } return 0; }
void RestoreSM (int nidx) { bool find = FALSE; char path[ISFS_MAXPATH] ATTRIBUTE_ALIGN(32); char pathBack[ISFS_MAXPATH] ATTRIBUTE_ALIGN(32); char *sm[] = {"00000088","00000085","0000008b","0000008e","00000098","00000095","0000009b","0000009e"}; s32 smsize; bool issm = FALSE; ISFS_Initialize(); int i; s32 fd; for (i = 0; i < sizeof(sm) / sizeof(char*); i++) { sprintf (path, "%s/title/00000001/00000002/content/%s.app", nandConfig->NandInfo[nidx], sm[i]); sprintf (pathBack, "%s/title/00000001/00000002/content/%s.bak", nandConfig->NandInfo[nidx], sm[i]); fd = ISFS_Open (path, ISFS_OPEN_READ); Debug ("ReplaceNandSystemMenu: checking %s (%d)", sm[i], fd); if (fd < 0) continue; smsize = ISFS_Seek(fd, 0, 2); Debug ("ReplaceNandSystemMenu: sm size %d", smsize); if (smsize > 1000000) // E' piu' grande di 1MB... e' il sistem menu issm = TRUE; ISFS_Close (fd); find = TRUE; break; } if (find && !issm) { // Restore filesistem ISFS_Delete (path); ISFS_Rename (pathBack, path); } ISFS_Deinitialize (); }
s32 CheckDisk(void *id) { const char di_fs[] ATTRIBUTE_ALIGN(32) = "/dev/di"; s32 di_fd = -1; u32 inbuf[8] ATTRIBUTE_ALIGN(32); u32 outbuf[8] ATTRIBUTE_ALIGN(32); /* Open "/dev/di" */ di_fd = IOS_Open(di_fs, 0); if (di_fd < 0) return di_fd; // error /* Reset drive */ memset(inbuf, 0, sizeof(inbuf)); inbuf[0] = IOCTL_DI_RESET << 24; inbuf[1] = 1; s32 ret = IOS_Ioctl(di_fd, IOCTL_DI_RESET, inbuf, sizeof(inbuf), outbuf, sizeof(outbuf)); if (ret < 0) { IOS_Close(di_fd); return ret; } /* Read disc ID */ memset(inbuf, 0, sizeof(inbuf)); inbuf[0] = IOCTL_DI_READID << 24; ret = IOS_Ioctl(di_fd, IOCTL_DI_READID, inbuf, sizeof(inbuf), outbuf, sizeof(outbuf)); if (ret < 0) return ret; if (ret == 1 && id) memcpy(id, outbuf, sizeof(dvddiskid)); /* Stop motor */ memset(inbuf, 0, sizeof(inbuf)); inbuf[0] = IOCTL_DI_STOPMOTOR << 24; IOS_Ioctl(di_fd, IOCTL_DI_STOPMOTOR, inbuf, sizeof(inbuf), outbuf, sizeof(outbuf)); IOS_Close(di_fd); if (ret != 1) { grlib_menu (0, "Sorry, no disc is detected in your WII", " OK "); } return ret; }
void get_title_key(signed_blob *s_tik, u8 *key) { static u8 iv[16] ATTRIBUTE_ALIGN(0x20); static u8 keyin[16] ATTRIBUTE_ALIGN(0x20); static u8 keyout[16] ATTRIBUTE_ALIGN(0x20); const tik *p_tik; p_tik = (tik*)SIGNATURE_PAYLOAD(s_tik); u8 *enc_key = (u8 *)&p_tik->cipher_title_key; memcpy(keyin, enc_key, sizeof keyin); memset(keyout, 0, sizeof keyout); memset(iv, 0, sizeof iv); memcpy(iv, &p_tik->titleid, sizeof p_tik->titleid); aes_set_key(commonkey); aes_decrypt(iv, keyin, keyout, sizeof keyin); memcpy(key, keyout, sizeof keyout); }
void RestorePriiloader (int nidx) { char path[ISFS_MAXPATH] ATTRIBUTE_ALIGN(32); char pathBack[ISFS_MAXPATH] ATTRIBUTE_ALIGN(32); ISFS_Initialize(); sprintf (path, "%s/title/00000001/00000002/data/main.bin", nandConfig->NandInfo[nidx]); sprintf (pathBack, "%s/title/00000001/00000002/data/main.bak", nandConfig->NandInfo[nidx]); ISFS_Delete (path); ISFS_Rename (pathBack, path); sprintf (path, "%s/title/00000001/00000002/data/loader.ini", nandConfig->NandInfo[nidx]); sprintf (pathBack, "%s/title/00000001/00000002/data/loader.bak", nandConfig->NandInfo[nidx]); ISFS_Delete (path); ISFS_Rename (pathBack, path); ISFS_Deinitialize (); }
//--------------------------------------------------------------------------------- int get_title_key(signed_blob *s_tik, u8 *key){ //--------------------------------------------------------------------------------- static u8 iv[16] ATTRIBUTE_ALIGN(0x20); static u8 keyin[16] ATTRIBUTE_ALIGN(0x20); static u8 keyout[16] ATTRIBUTE_ALIGN(0x20); int retval; const tik *p_tik; p_tik = (tik*)SIGNATURE_PAYLOAD(s_tik); u8 *enc_key = (u8 *)&p_tik->cipher_title_key; memcpy(keyin, enc_key, sizeof keyin); memset(keyout, 0, sizeof keyout); memset(iv, 0, sizeof iv); memcpy(iv, &p_tik->titleid, sizeof p_tik->titleid); retval = ES_Decrypt(ES_KEY_COMMON, iv, keyin, sizeof keyin, keyout); if (retval){ // printf("ES_Decrypt returned %d\n", retval); } memcpy(key, keyout, sizeof keyout); return retval; }
void change_ticket_title_id(signed_blob *s_tik, u32 titleid1, u32 titleid2) { static u8 iv[16] ATTRIBUTE_ALIGN(0x20); static u8 keyin[16] ATTRIBUTE_ALIGN(0x20); static u8 keyout[16] ATTRIBUTE_ALIGN(0x20); tik *p_tik; p_tik = (tik*)SIGNATURE_PAYLOAD(s_tik); u8 *enc_key = (u8 *)&p_tik->cipher_title_key; memcpy(keyin, enc_key, sizeof keyin); memset(keyout, 0, sizeof keyout); memset(iv, 0, sizeof iv); memcpy(iv, &p_tik->titleid, sizeof p_tik->titleid); aes_set_key(commonkey); aes_decrypt(iv, keyin, keyout, sizeof keyin); p_tik->titleid = (u64)titleid1 << 32 | (u64)titleid2; memset(iv, 0, sizeof iv); memcpy(iv, &p_tik->titleid, sizeof p_tik->titleid); aes_encrypt(iv, keyout, keyin, sizeof keyout); memcpy(enc_key, keyin, sizeof keyin); }
int gecko_readmem() { u8 startaddress[4]; u8 endaddress[5]; u8 ack_packet = 0xAA; u8 pcresponse; static u8 packetbuffer[packetsize] ATTRIBUTE_ALIGN(32); u32 memstart; u32 memend; u32 memrange; u32 fullpackets; u32 currentpacket; u32 lastpacketbytes; // ACK usb_sendbuffer_safe(gecko_channel,&ack_packet,1); usb_recvbuffer_safe(gecko_channel,&startaddress,4); usb_recvbuffer_safe(gecko_channel,&endaddress,4); memstart = be32(startaddress); memend = be32(endaddress); memrange = memend - memstart; fullpackets = memrange / packetsize; lastpacketbytes = memrange % packetsize; // Full Packet Size for (currentpacket = 0;currentpacket < fullpackets;) { memcpy(packetbuffer, (char*)memstart, packetsize); usb_sendbuffer(gecko_channel,&packetbuffer, packetsize); usb_recvbuffer_safe(gecko_channel,&pcresponse,1); if(pcresponse != 0xAA){ // printf("failed to read packet\n"); return 0; } memstart += packetsize; currentpacket++; } // Remainder if(lastpacketbytes > 0) { memcpy(packetbuffer, (char*)memstart, lastpacketbytes); usb_sendbuffer_safe(gecko_channel,&packetbuffer, lastpacketbytes); usb_recvbuffer_safe(gecko_channel,&pcresponse,1); } // printf("memory dump complete\n"); return 1; }
bool isIOSstub(u8 ios_number) { static signed_blob ios_tmd_buf[MAX_SIGNED_TMD_SIZE] ATTRIBUTE_ALIGN(32); u32 tmd_size; tmd *ios_tmd; if (ios_number == 249) { ES_GetStoredTMDSize(0x0000000100000000ULL | ios_number, &tmd_size); ES_GetStoredTMD(0x0000000100000000ULL | ios_number, ios_tmd_buf, tmd_size); ios_tmd = SIGNATURE_PAYLOAD(ios_tmd_buf); if (ios_tmd->title_version >= 65280) return TRUE; } return FALSE; }
iosinfo_t *IOS_GetInfo(u8 ios) { u32 TMD_Length; signed_blob *TMD = GetTMD(ios, &TMD_Length); if(TMD == NULL) return NULL; char filepath[ISFS_MAXPATH] ATTRIBUTE_ALIGN(32); sprintf(filepath, "/title/00000001/%08x/content/%08x.app", ios, *(u8 *)((u32)TMD+0x1E7)); MEM2_free(TMD); u32 size = 0; u8 *buffer = ISFS_GetFile(filepath, &size, sizeof(iosinfo_t)); if(buffer == NULL || size == 0) return NULL; iosinfo_t *iosinfo = (iosinfo_t *)buffer; return iosinfo; }
s32 Uninstall_RemoveTicket(u64 tid) { static tikview viewdata[0x10] ATTRIBUTE_ALIGN(32); u32 cnt, views; s32 ret; //printf("\t\t- Removing tickets..."); fflush(stdout); /* Get number of ticket views */ ret = ES_GetNumTicketViews(tid, &views); if (ret < 0) { //printf(" Error! (ret = %d)\n", ret); return ret; } if (!views) { //printf(" No tickets found!\n"); return 1; } else if (views > 16) { //printf(" Too many ticket views! (views = %d)\n", views); return -1; } /* Get ticket views */ ret = ES_GetTicketViews(tid, viewdata, views); if (ret < 0) { //printf(" \n\tError! ES_GetTicketViews (ret = %d)\n", ret); return ret; } /* Remove tickets */ for (cnt = 0; cnt < views; cnt++) { ret = ES_DeleteTicket(&viewdata[cnt]); if (ret < 0) { //printf(" Error! (view = %d, ret = %d)\n", cnt, ret); return ret; } } //printf(" OK!\n"); return ret; }
s32 BlockIOSReload(void) { /* Open ES Module */ s32 ESHandle = IOS_Open("/dev/es", 0); /* IOS Reload Block */ static ioctlv block_vector[2] ATTRIBUTE_ALIGN(32); static u32 mode ATTRIBUTE_ALIGN(32); static u32 ios ATTRIBUTE_ALIGN(32); mode = 2; block_vector[0].data = &mode; block_vector[0].len = sizeof(u32); ios = IOS_GetVersion(); block_vector[1].data = &ios; block_vector[1].len = sizeof(u32); s32 ret = IOS_Ioctlv(ESHandle, 0xA0, 2, 0, block_vector); /* Close ES Module */ IOS_Close(ESHandle); return ret; }
static void __ARClearArea(u32 aramaddr,u32 len) { u32 currlen,curraddr,endaddr; static u8 zero_buffer[2048] ATTRIBUTE_ALIGN(32); while(!(_dspReg[11]&0x0001)); memset(zero_buffer,0,2048); DCFlushRange(zero_buffer,2048); curraddr = aramaddr; endaddr = aramaddr+len; currlen = 2048; while(curraddr<endaddr) { if((endaddr-curraddr)<currlen) currlen = ((endaddr-curraddr)+31)&~31; __ARWriteDMA((u32)zero_buffer,curraddr,currlen); curraddr += currlen; } }
s32 StartMIOS (void) { s32 ret; SetGCVideoMode (); tikview view ATTRIBUTE_ALIGN(32); ret = ES_GetTicketViews(BC, &view, 1); if (ret != 0) return -1; // Tell DML to boot the game from sd card *(u32 *)0x80001800 = 0xB002D105; DCFlushRange((void *)(0x80001800), 4); ICInvalidateRange((void *)(0x80001800), 4); *(volatile unsigned int *)0xCC003024 |= 7; ret = ES_LaunchTitle(BC, &view); return -102; }
s32 __FAT_Initialize(u32 *queuehandle) { /* Heap space */ //static u32 heapspace[0x8000] ATTRIBUTE_ALIGN(32); static u32 heapspace[0x7000] ATTRIBUTE_ALIGN(32); void *buffer = NULL; s32 ret; /* Initialize memory heap */ ret = Mem_Init(heapspace, sizeof(heapspace)); if (ret < 0) return ret; /* Initialize timer subsystem */ ret = Timer_Init(); if (ret < 0) return ret; /* Allocate queue buffer */ buffer = Mem_Alloc(0x80); if (!buffer) return IPC_ENOMEM; /* Create message queue */ ret = os_message_queue_create(buffer, 32); if (ret < 0) return ret; /* Register device */ os_device_register(DEVICE_FAT, ret); os_device_register("$", ret); /* Copy queue handler */ *queuehandle = ret; return 0; }
s8 CheckTitleOnSD(u64 id) { //check Mounted Devices so that IF the SD is inserted it also gets mounted PollDevices(); if (!(GetMountedValue() & 2)) //no SD mounted, lets bail out return -1; char title_ID[5]; //Check app on SD. it might be there. not that it matters cause we can't boot from SD memset(title_ID,0,5); u32 title_l = id & 0xFFFFFFFF; memcpy(title_ID, &title_l, 4); for (s8 f=0; f<4; f++) { if(title_ID[f] < 0x20) title_ID[f] = '.'; if(title_ID[f] > 0x7E) title_ID[f] = '.'; } title_ID[4]='\0'; char file[256] ATTRIBUTE_ALIGN(32); memset(file,0,256); sprintf(file, "fat:/private/wii/title/%s/content.bin", title_ID); FILE* SDHandler = fopen(file,"rb"); if (SDHandler) { //content.bin is there meaning its on SD fclose(SDHandler); gprintf("CheckTitleOnSD : title is saved on SD\n"); return 1; } else { //title isn't on SD either. ow well... gprintf("CheckTitleOnSD : content not found on NAND or SD for %08X\\%08X\n",(u32)(id >> 32),title_l); return 0; } }
static int send_output_report(struct ds3wiibt_context *ctx) { unsigned char buf[] ATTRIBUTE_ALIGN(32) = { (HIDP_TRANS_SETREPORT | HIDP_DATA_RTYPE_OUPUT), 0x01, //Report ID 0x00, //Padding 0x00, 0x00, 0x00, 0x00, //Rumble (r, r, l, l) 0x00, 0x00, 0x00, 0x00, //Padding 0x00, /* LED_1 = 0x02, LED_2 = 0x04, ... */ 0xff, 0x27, 0x10, 0x00, 0x32, /* LED_4 */ 0xff, 0x27, 0x10, 0x00, 0x32, /* LED_3 */ 0xff, 0x27, 0x10, 0x00, 0x32, /* LED_2 */ 0xff, 0x27, 0x10, 0x00, 0x32, /* LED_1 */ 0x00, 0x00, 0x00, 0x00, 0x00 /* LED_5 (not soldered) */ }; buf[3] = ctx->rumble.duration_right; buf[4] = ctx->rumble.power_right; buf[5] = ctx->rumble.duration_left; buf[6] = ctx->rumble.power_left; buf[11] = led_pattern[ctx->led%11]; return senddata_raw(ctx->ctrl_pcb, buf, sizeof(buf)); }
char *__IOP_SyscallOpen(char *path, s32 mode) { static char newpath[FAT_MAXPATH] ATTRIBUTE_ALIGN(32); s32 ret; #ifdef IOP_TRACE_OPEN svc_write("IOP: open ");svc_write(path);svc_write("\n"); #endif /* * Paths starting with '#' are always sent to real nand. * This is an internal feature, only authorized threads * can use it. */ if (*path == '#') { /* Check opening request */ ret = __IOP_CheckOpeningRequest(path, TID_RIGHTS_FORCE_REAL_NAND); /* Block request returning original invalid path */ if (!ret) return path; /* Copy path */ strcpy(newpath, path); /* Replace first character */ *newpath = '/'; /* Set flag for mode rev17-like */ forceRealPath = ((config.mode & MODE_REV17) != 0); /* Return new path */ return newpath; } /* * When a title is running only authorized threads * can open fat. * * NOTE: * Since v8 beta r42 relative fat paths, identified by the initial * '$', have been introduced to fix issue 16. * These paths are always relative to nand emulation folder. */ if (*path == '$' || !strncmp(path, "fat", 3)) { u32 running_title; /* Check a title is running */ running_title = Swi_GetRunningTitle(); /* Check thread rigths if a title is running */ if (running_title) { /* Check opening request */ ret = __IOP_CheckOpeningRequest(path, TID_RIGHTS_OPEN_FAT); /* Block opening request */ if (!ret) { /* Set new invalid path */ strcpy(newpath, "GTFO"); /* Return new path */ return newpath; } } /* Return original path */ return path; } /* Emulation mode */ if (config.mode) { /* SDHC mode */ if (config.mode & MODE_SDHC) { if (!strcmp(path, "/dev/sdio/slot0")) { /* Log */ svc_write("IOP: The game is trying to open /dev/sdio/slot0.\n"); svc_write("IOP: To avoid interferences with emu nand on sd card the request is redirected to /dev/null.\n"); /* Replace path */ strcpy(newpath, "/dev/null"); /* Return new path */ return newpath; } } /* Direct FAT mode */ if (!(config.mode & MODE_REV17)) { /* Check path */ ret = FS_CheckRealPath(path); /* Emulate path */ if (!ret) { /* Generate relative path */ ret = FS_GenerateRelativePath(path, newpath); /* Return new path */ if (ret) return newpath; } } } /* Return original path */ return path; }
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);
bool Theme::loadSystemFont(bool korean) { const char contentMapPath[] ATTRIBUTE_ALIGN(32) = "/shared1/content.map"; u8 *contentMap = NULL; u32 mapsize = 0; Nand::LoadFile(contentMapPath, &contentMap, &mapsize); if(!contentMap) return false; int fileCount = mapsize / sizeof(map_entry_t); map_entry_t *mapEntryList = (map_entry_t *) contentMap; for (int i = 0; i < fileCount; i++) { if (memcmp(mapEntryList[i].hash, korean ? WIIFONT_HASH_KOR : WIIFONT_HASH, 20) != 0) continue; //! Name found, load it and unpack it char font_filename[32] ATTRIBUTE_ALIGN(32); snprintf(font_filename, sizeof(font_filename), "/shared1/%.8s.app", mapEntryList[i].name); u8 *fontArchive = NULL; u32 filesize = 0; Nand::LoadFile(font_filename, &fontArchive, &filesize); if(!fontArchive) continue; const U8Header *u8Archive = (U8Header *) fontArchive; const U8Entry *fst = (const U8Entry *) (((const u8 *) u8Archive) + u8Archive->rootNodeOffset); if(fst[0].numEntries < 1) { free(fontArchive); continue; } if(systemFont) delete [] systemFont; systemFontSize = fst[1].fileLength; systemFont = new (std::nothrow) FT_Byte[systemFontSize]; if(!systemFont) { free(fontArchive); continue; } memcpy(systemFont, fontArchive + fst[1].fileOffset, systemFontSize); free(fontArchive); free(contentMap); gprintf("Loaded Wii System Font: %s\n", u8Filename(fst, 1)); return true; } free(contentMap); return false; }
s32 identify(u64 titleid, u32 *ios){ char filepath[ISFS_MAXPATH] ATTRIBUTE_ALIGN(0x20); u8 *tmdBuffer = NULL; u32 tmdSize; signed_blob *tikBuffer = NULL; u32 tikSize; u8 *certBuffer = NULL; u32 certSize; int ret; printf("Reading TMD..."); fflush(stdout); sprintf(filepath, "/title/%08x/%08x/content/title.tmd", TITLE_UPPER(titleid), TITLE_LOWER(titleid)); ret = read_file(filepath, &tmdBuffer, &tmdSize); if (ret < 0) { printf("Reading TMD failed\n"); return ret; } printf("done\n"); *ios = (u32)(tmdBuffer[0x18b]); printf("Generating fake ticket..."); fflush(stdout); /* sprintf(filepath, "/ticket/%08x/%08x.tik", TITLE_UPPER(titleid), TITLE_LOWER(titleid)); ret = read_file(filepath, &tikBuffer, &tikSize); if (ret < 0) { printf("Reading ticket failed\n"); free(tmdBuffer); return ret; }*/ Identify_GenerateTik(&tikBuffer,&tikSize); printf("done\n"); printf("Reading certs..."); fflush(stdout); sprintf(filepath, "/sys/cert.sys"); ret = read_file(filepath, &certBuffer, &certSize); if (ret < 0) { printf("Reading certs failed\n"); free(tmdBuffer); free(tikBuffer); return ret; } printf("done\n"); printf("ES_Identify..."); fflush(stdout); ret = ES_Identify((signed_blob*)certBuffer, certSize, (signed_blob*)tmdBuffer, tmdSize, tikBuffer, tikSize, NULL); if (ret < 0) { switch(ret) { case ES_EINVAL: printf("Error! ES_Identify (ret = %d;) Data invalid!\n", ret); break; case ES_EALIGN: printf("Error! ES_Identify (ret = %d;) Data not aligned!\n", ret); break; case ES_ENOTINIT: printf("Error! ES_Identify (ret = %d;) ES not initialized!\n", ret); break; case ES_ENOMEM: printf("Error! ES_Identify (ret = %d;) No memory!\n", ret); break; default: printf("Error! ES_Identify (ret = %d)\n", ret); break; } free(tmdBuffer); free(tikBuffer); free(certBuffer); return ret; } printf("done\n"); free(tmdBuffer); free(tikBuffer); free(certBuffer); return 0; }
static void __ARCheckSize() { u32 i,arsize,arszflag; static u32 test_data[8] ATTRIBUTE_ALIGN(32); static u32 dummy_data[8] ATTRIBUTE_ALIGN(32); static u32 buffer[8] ATTRIBUTE_ALIGN(32); #ifdef _AR_DEBUG printf("__ARCheckSize()\n"); #endif while(!(_dspReg[11]&0x0001)); __ARSize = __ARInternalSize = arsize = 0x1000000; _dspReg[9] = (_dspReg[9]&~0x3f)|0x23; for(i=0;i<8;i++) { test_data[i] = 0xBAD1BAD0; dummy_data[i] = 0xDEADBEEF; } DCFlushRange(test_data,32); DCFlushRange(dummy_data,32); __ARExpansionSize = 0; __ARWriteDMA((u32)test_data,0x1000000,32); __ARWriteDMA((u32)test_data,0x1200000,32); __ARWriteDMA((u32)test_data,0x2000000,32); __ARWriteDMA((u32)test_data,0x1000200,32); __ARWriteDMA((u32)test_data,0x1400000,32); memset(buffer,0,32); DCFlushRange(buffer,32); __ARWriteDMA((u32)dummy_data,0x1000000,32); DCInvalidateRange(buffer,32); __ARReadDMA((u32)buffer,0x1000000,32); _nop(); arszflag = 0x03; if(buffer[0]==dummy_data[0]) { memset(buffer,0,32); DCFlushRange(buffer,32); __ARReadDMA((u32)buffer,0x1200000,32); _nop(); if(buffer[0]==dummy_data[0]) { __ARExpansionSize = 0x200000; arsize += 0x200000; goto end_check; //not nice but fast } memset(buffer,0,32); DCFlushRange(buffer,32); __ARReadDMA((u32)buffer,0x2000000,32); _nop(); if(buffer[0]==dummy_data[0]) { __ARExpansionSize = 0x400000; arsize += 0x400000; arszflag |= 0x08; goto end_check; //not nice but fast } memset(buffer,0,32); DCFlushRange(buffer,32); __ARReadDMA((u32)buffer,0x1400000,32); _nop(); if(buffer[0]==dummy_data[0]) { __ARExpansionSize = 0x1000000; arsize += 0x1000000; arszflag |= 0x18; } else { __ARExpansionSize = 0x2000000; arsize += 0x2000000; arszflag |= 0x20; } end_check: _dspReg[9] = (_dspReg[9]&~0x3f)|arszflag; } #ifdef _AR_DEBUG printf("__ARCheckSize(%d)\n",arsize); #endif *(u32*)0x800000d0 = arsize; __ARSize = arsize; }
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; }