void romfs_visit_file(romfs_context* ctx, u32 fileoffset, u32 depth, u32 actions, const oschar_t* rootpath) { u32 siblingoffset = 0; oschar_t* currentpath = NULL; romfs_fileentry* entry = &ctx->fileentry; if (!romfs_fileblock_readentry(ctx, fileoffset, entry)) return; // fprintf(stdout, "%08X %08X %016llX %016llX %08X ", // getle32(entry->parentdiroffset), getle32(entry->siblingoffset), ctx->datablockoffset+getle64(entry->dataoffset), // getle64(entry->datasize), getle32(entry->unknown)); // fwprintf(stdout, L"%ls\n", entry->name); if (rootpath && os_strlen(rootpath)) { currentpath = os_AppendUTF16StrToPath(rootpath, (const utf16char_t*)entry->name); if (currentpath) { fputs("Saving ", stdout); os_fputs(currentpath, stdout); fputs("...\n", stdout); romfs_extract_datafile(ctx, getle64(entry->dataoffset), getle64(entry->datasize), currentpath); } else { fputs("Error creating file in root ", stderr); os_fputs(rootpath, stderr); fputs("\n", stderr); return; } } else { currentpath = os_CopyConvertUTF16Str((const utf16char_t*)entry->name); if (settings_get_list_romfs_files(ctx->usersettings)) { u32 i; for(i=0; i<depth; i++) printf(" "); os_fputs(currentpath, stdout); fputs("\n", stdout); } free(currentpath); currentpath = NULL; } siblingoffset = getle32(entry->siblingoffset); if (siblingoffset != (~0)) romfs_visit_file(ctx, siblingoffset, depth, actions, rootpath); free(currentpath); }
void ivfc_process(ivfc_context* ctx, u32 actions) { ivfc_fseek(ctx, ctx->offset); ivfc_fread(ctx, &ctx->header, 1, sizeof(ivfc_header)); if (getle32(ctx->header.magic) != MAGIC_IVFC) { fprintf(stdout, "Error, IVFC segment corrupted\n"); return; } if (getle32(ctx->header.id) == 0x10000) { ctx->levelcount = 3; ctx->level[2].hashblocksize = 1 << getle32(ctx->header.level3.blocksize); ctx->level[1].hashblocksize = 1 << getle32(ctx->header.level2.blocksize); ctx->level[0].hashblocksize = 1 << getle32(ctx->header.level1.blocksize); ctx->bodyoffset = align64(IVFC_HEADER_SIZE + getle32(ctx->header.masterhashsize), ctx->level[2].hashblocksize); ctx->bodysize = getle64(ctx->header.level3.hashdatasize); ctx->level[2].dataoffset = ctx->bodyoffset; ctx->level[2].datasize = align64(ctx->bodysize, ctx->level[2].hashblocksize); ctx->level[0].dataoffset = ctx->level[2].dataoffset + ctx->level[2].datasize; ctx->level[0].datasize = align64(getle64(ctx->header.level1.hashdatasize), ctx->level[0].hashblocksize); ctx->level[1].dataoffset = ctx->level[0].dataoffset + ctx->level[0].datasize; ctx->level[1].datasize = align64(getle64(ctx->header.level2.hashdatasize), ctx->level[1].hashblocksize); ctx->level[0].hashoffset = IVFC_HEADER_SIZE; ctx->level[1].hashoffset = ctx->level[0].dataoffset; ctx->level[2].hashoffset = ctx->level[1].dataoffset; } if (actions & VerifyFlag) ivfc_verify(ctx, actions); if (actions & InfoFlag) ivfc_print(ctx); }
void ncsd_print(ncsd_context* ctx) { char magic[5]; ctr_ncsdheader* header = &ctx->header; unsigned int i; unsigned int mediaunitsize = (unsigned int) ncsd_get_mediaunit_size(ctx); memcpy(magic, header->magic, 4); magic[4] = 0; fprintf(stdout, "Header: %s\n", magic); if (ctx->headersigcheck == Unchecked) memdump(stdout, "Signature: ", header->signature, 0x100); else if (ctx->headersigcheck == Good) memdump(stdout, "Signature (GOOD): ", header->signature, 0x100); else memdump(stdout, "Signature (FAIL): ", header->signature, 0x100); fprintf(stdout, "Media size: 0x%08x\n", getle32(header->mediasize)); fprintf(stdout, "Media id: %016"PRIx64"\n", getle64(header->mediaid)); //memdump(stdout, "Partition FS type: ", header->partitionfstype, 8); //memdump(stdout, "Partition crypt type: ", header->partitioncrypttype, 8); //memdump(stdout, "Partition offset/size: ", header->partitionoffsetandsize, 0x40); fprintf(stdout, "\n"); for(i=0; i<8; i++) { u32 partitionoffset = header->partitiongeometry[i].offset * mediaunitsize; u32 partitionsize = header->partitiongeometry[i].size * mediaunitsize; if (partitionsize != 0) { fprintf(stdout, "Partition %d \n", i); memdump(stdout, " Id: ", header->partitionid+i*8, 8); fprintf(stdout, " Area: 0x%08X-0x%08X\n", partitionoffset, partitionoffset+partitionsize); fprintf(stdout, " Filesystem: %02X\n", header->partitionfstype[i]); fprintf(stdout, " Encryption: %02X\n", header->partitioncrypttype[i]); fprintf(stdout, "\n"); } } memdump(stdout, "Extended header hash: ", header->extendedheaderhash, 0x20); memdump(stdout, "Additional header size: ", header->additionalheadersize, 4); memdump(stdout, "Sector zero offset: ", header->sectorzerooffset, 4); memdump(stdout, "Flags: ", header->flags, 8); fprintf(stdout, " > Mediaunit size: 0x%X\n", mediaunitsize); fprintf(stdout, " > Mediatype: %s\n", ncsd_print_mediatype(header->flags[5])); fprintf(stdout, " > Card Device: %s\n", ncsd_print_carddevice(header->flags[3] | header->flags[7])); }
void cia_process(cia_context* ctx, u32 actions) { fseek(ctx->file, 0, SEEK_SET); if (fread(&ctx->header, 1, sizeof(ctr_ciaheader), ctx->file) != sizeof(ctr_ciaheader)) { fprintf(stderr, "Error reading CIA header\n"); goto clean; } ctx->sizeheader = getle32(ctx->header.headersize); ctx->sizecert = getle32(ctx->header.certsize); ctx->sizetik = getle32(ctx->header.ticketsize); ctx->sizetmd = getle32(ctx->header.tmdsize); ctx->sizecontent = (u32)getle64(ctx->header.contentsize); ctx->sizemeta = getle32(ctx->header.metasize); ctx->offsetcerts = align(ctx->sizeheader, 64); ctx->offsettik = align(ctx->offsetcerts + ctx->sizecert, 64); ctx->offsettmd = align(ctx->offsettik + ctx->sizetik, 64); ctx->offsetcontent = align(ctx->offsettmd + ctx->sizetmd, 64); ctx->offsetmeta = align(ctx->offsetcontent + ctx->sizecontent, 64); if (actions & InfoFlag) cia_print(ctx); tik_set_file(&ctx->tik, ctx->file); tik_set_offset(&ctx->tik, ctx->offsettik); tik_set_size(&ctx->tik, ctx->sizetik); tik_set_usersettings(&ctx->tik, ctx->usersettings); tik_process(&ctx->tik, actions); memset(ctx->iv, 0, 16); if (settings_get_common_key(ctx->usersettings)) tik_get_decrypted_titlekey(&ctx->tik, ctx->titlekey); tmd_set_file(&ctx->tmd, ctx->file); tmd_set_offset(&ctx->tmd, ctx->offsettmd); tmd_set_size(&ctx->tmd, ctx->sizetmd); tmd_set_usersettings(&ctx->tmd, ctx->usersettings); tmd_process(&ctx->tmd, actions); if (actions & VerifyFlag) { cia_verify_contents(ctx, actions); } if (actions & InfoFlag || actions & VerifyFlag) tmd_print(&ctx->tmd); if (actions & ExtractFlag) { cia_save(ctx, CIATYPE_CERTS, actions); cia_save(ctx, CIATYPE_TMD, actions); cia_save(ctx, CIATYPE_TIK, actions); cia_save(ctx, CIATYPE_META, actions); cia_save(ctx, CIATYPE_CONTENT, actions); } clean: return; }