diff --git a/ctrtool/cia.c b/ctrtool/cia.c index c0963a5..91333bd 100644 --- a/ctrtool/cia.c +++ b/ctrtool/cia.c @@ -20,12 +20,12 @@ void cia_set_file(cia_context* ctx, FILE* file) ctx->file = file; } -void cia_set_offset(cia_context* ctx, u32 offset) +void cia_set_offset(cia_context* ctx, u64 offset) { ctx->offset = offset; } -void cia_set_size(cia_context* ctx, u32 size) +void cia_set_size(cia_context* ctx, u64 size) { ctx->size = size; } @@ -39,8 +39,8 @@ void cia_set_usersettings(cia_context* ctx, settings* usersettings) void cia_save(cia_context* ctx, u32 type, u32 flags) { - u32 offset; - u32 size; + u64 offset; + u64 size; u16 contentflags; u8 docrypto; filepath* path = 0; @@ -133,14 +133,13 @@ void cia_save(cia_context* ctx, u32 type, u32 flags) cia_save_blob(ctx, path->pathname, offset, size, 0); } -void cia_save_blob(cia_context *ctx, char *out_path, u32 offset, u32 size, int do_cbc) +void cia_save_blob(cia_context *ctx, char *out_path, u64 offset, u64 size, int do_cbc) { FILE *fout = 0; u8 buffer[16*1024]; - fseek(ctx->file, ctx->offset + offset, SEEK_SET); + fseeko64(ctx->file, ctx->offset + offset, SEEK_SET); - fout = fopen(out_path, "wb"); if (fout == NULL) { @@ -180,7 +179,7 @@ clean: void cia_process(cia_context* ctx, u32 actions) { - fseek(ctx->file, 0, SEEK_SET); + fseeko64(ctx->file, 0, SEEK_SET); if (fread(&ctx->header, 1, sizeof(ctr_ciaheader), ctx->file) != sizeof(ctr_ciaheader)) { @@ -192,14 +191,14 @@ void cia_process(cia_context* ctx, u32 actions) 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->sizecontent = 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); + ctx->offsetmeta = align64(ctx->offsetcontent + ctx->sizecontent, 64); if (actions & InfoFlag) cia_print(ctx); @@ -260,7 +259,7 @@ void cia_verify_contents(cia_context *ctx, u32 actions) body = tmd_get_body(&ctx->tmd); chunk = (ctr_tmd_contentchunk*)(body->contentinfo + (sizeof(ctr_tmd_contentinfo) * TMD_MAX_CONTENTS)); - fseek(ctx->file, ctx->offset + ctx->offsetcontent, SEEK_SET); + fseeko64(ctx->file, ctx->offset + ctx->offsetcontent, SEEK_SET); for(i = 0; i < getbe16(body->contentcount); i++) { content_size = getbe64(chunk->size) & 0xffffffff; @@ -298,14 +297,14 @@ void cia_print(cia_context* ctx) fprintf(stdout, "Header size 0x%08x\n", getle32(header->headersize)); fprintf(stdout, "Type %04x\n", getle16(header->type)); fprintf(stdout, "Version %04x\n", getle16(header->version)); - fprintf(stdout, "Certificates offset: 0x%08x\n", ctx->offsetcerts); - fprintf(stdout, "Certificates size: 0x%04x\n", ctx->sizecert); - fprintf(stdout, "Ticket offset: 0x%08x\n", ctx->offsettik); - fprintf(stdout, "Ticket size 0x%04x\n", ctx->sizetik); - fprintf(stdout, "TMD offset: 0x%08x\n", ctx->offsettmd); - fprintf(stdout, "TMD size: 0x%04x\n", ctx->sizetmd); - fprintf(stdout, "Meta offset: 0x%04x\n", ctx->offsetmeta); - fprintf(stdout, "Meta size: 0x%04x\n", ctx->sizemeta); - fprintf(stdout, "Content offset: 0x%08x\n", ctx->offsetcontent); - fprintf(stdout, "Content size: 0x%016"PRIx64"\n", getle64(header->contentsize)); + fprintf(stdout, "Certificates offset: 0x%"PRIx64"\n", ctx->offsetcerts); + fprintf(stdout, "Certificates size: 0x%x\n", ctx->sizecert); + fprintf(stdout, "Ticket offset: 0x%"PRIx64"n", ctx->offsettik); + fprintf(stdout, "Ticket size 0x%x\n", ctx->sizetik); + fprintf(stdout, "TMD offset: 0x%"PRIx64"\n", ctx->offsettmd); + fprintf(stdout, "TMD size: 0x%x\n", ctx->sizetmd); + fprintf(stdout, "Meta offset: 0x%"PRIx64"\n", ctx->offsetmeta); + fprintf(stdout, "Meta size: 0x%x\n", ctx->sizemeta); + fprintf(stdout, "Content offset: 0x%"PRIx64"\n", ctx->offsetcontent); + fprintf(stdout, "Content size: 0x%"PRIx64"\n", ctx->sizecontent); } diff --git a/ctrtool/cia.h b/ctrtool/cia.h index 531c7c1..52b0152 100644 --- a/ctrtool/cia.h +++ b/ctrtool/cia.h @@ -33,8 +33,8 @@ typedef struct typedef struct { FILE* file; - u32 offset; - u32 size; + u64 offset; + u64 size; u8 titlekey[16]; u8 iv[16]; ctr_ciaheader header; @@ -48,25 +48,25 @@ typedef struct u32 sizecert; u32 sizetik; u32 sizetmd; - u32 sizecontent; + u64 sizecontent; u32 sizemeta; - u32 offsetcerts; - u32 offsettik; - u32 offsettmd; - u32 offsetcontent; - u32 offsetmeta; + u64 offsetcerts; + u64 offsettik; + u64 offsettmd; + u64 offsetcontent; + u64 offsetmeta; } cia_context; void cia_init(cia_context* ctx); void cia_set_file(cia_context* ctx, FILE* file); -void cia_set_offset(cia_context* ctx, u32 offset); -void cia_set_size(cia_context* ctx, u32 size); +void cia_set_offset(cia_context* ctx, u64 offset); +void cia_set_size(cia_context* ctx, u64 size); void cia_set_usersettings(cia_context* ctx, settings* usersettings); void cia_print(cia_context* ctx); void cia_save(cia_context* ctx, u32 type, u32 flags); void cia_process(cia_context* ctx, u32 actions); -void cia_save_blob(cia_context *ctx, char *out_path, u32 offset, u32 size, int do_cbc); +void cia_save_blob(cia_context *ctx, char *out_path, u64 offset, u64 size, int do_cbc); void cia_verify_contents(cia_context *ctx, u32 actions); #endif // _CIA_H_ diff --git a/ctrtool/ctr.c b/ctrtool/ctr.c index 417d03f..6948bf8 100644 --- a/ctrtool/ctr.c +++ b/ctrtool/ctr.c @@ -13,33 +13,24 @@ void ctr_set_iv( ctr_aes_context* ctx, } void ctr_add_counter( ctr_aes_context* ctx, - u32 carry ) + u32 block_num ) { - u32 counter[4]; - u32 sum; - int i; + u32 i, j; + for (i = 0; i < block_num; i++) { + for (j = 0x10; j > 0; j--) { + // increment u8 by 1 + ctx->ctr[j - 1]++; - for(i=0; i<4; i++) - counter[i] = (ctx->ctr[i*4+0]<<24) | (ctx->ctr[i*4+1]<<16) | (ctx->ctr[i*4+2]<<8) | (ctx->ctr[i*4+3]<<0); + // if it didn't overflow to 0, then we can exit now + if (ctx->ctr[j - 1]) + break; - for(i=3; i>=0; i--) - { - sum = counter[i] + carry; + // if we reach here, the next u8 needs to be incremented - if (sum < counter[i]) - carry = 1; - else - carry = 0; - - counter[i] = sum; - } - - for(i=0; i<4; i++) - { - ctx->ctr[i*4+0] = counter[i]>>24; - ctx->ctr[i*4+1] = counter[i]>>16; - ctx->ctr[i*4+2] = counter[i]>>8; - ctx->ctr[i*4+3] = counter[i]>>0; + // Loop to beginning back if needed + if (j == 1) + j = 0x10; + } } } diff --git a/ctrtool/ctr.h b/ctrtool/ctr.h index 9321051..66caff7 100644 --- a/ctrtool/ctr.h +++ b/ctrtool/ctr.h @@ -56,7 +56,7 @@ void ctr_set_iv( ctr_aes_context* ctx, u8 iv[16] ); void ctr_add_counter( ctr_aes_context* ctx, - u32 carry ); + u32 block_num ); void ctr_set_counter( ctr_aes_context* ctx, u8 ctr[16] ); diff --git a/ctrtool/cwav.c b/ctrtool/cwav.c index e532db0..4c1242d 100644 --- a/ctrtool/cwav.c +++ b/ctrtool/cwav.c @@ -37,12 +37,12 @@ void cwav_set_file(cwav_context* ctx, FILE* file) ctx->file = file; } -void cwav_set_offset(cwav_context* ctx, u32 offset) +void cwav_set_offset(cwav_context* ctx, u64 offset) { ctx->offset = offset; } -void cwav_set_size(cwav_context* ctx, u32 size) +void cwav_set_size(cwav_context* ctx, u64 size) { ctx->size = size; } @@ -57,12 +57,12 @@ void cwav_process(cwav_context* ctx, u32 actions) u32 i; u32 infoheaderoffset; - fseek(ctx->file, ctx->offset, SEEK_SET); + fseeko64(ctx->file, ctx->offset, SEEK_SET); fread(&ctx->header, 1, sizeof(cwav_header), ctx->file); infoheaderoffset = getle32(ctx->header.infoblockref.offset); - fseek(ctx->file, ctx->offset + infoheaderoffset, SEEK_SET); + fseeko64(ctx->file, ctx->offset + infoheaderoffset, SEEK_SET); fread(&ctx->infoheader, 1, sizeof(cwav_infoheader), ctx->file); ctx->channelcount = getle32(ctx->infoheader.channelcount); @@ -79,7 +79,7 @@ void cwav_process(cwav_context* ctx, u32 actions) { u32 channeloffset = infoheaderoffset + 0x1C + getle32(ctx->channel[i].inforef.offset); - fseek(ctx->file, ctx->offset + channeloffset, SEEK_SET); + fseeko64(ctx->file, ctx->offset + channeloffset, SEEK_SET); fread(&ctx->channel[i].info, sizeof(cwav_channelinfo), 1, ctx->file); if (ctx->infoheader.encoding == CWAV_ENCODING_DSPADPCM) @@ -88,7 +88,7 @@ void cwav_process(cwav_context* ctx, u32 actions) { u32 codecoffset = channeloffset + getle32(ctx->channel[i].info.codecref.offset); - fseek(ctx->file, ctx->offset + codecoffset, SEEK_SET); + fseeko64(ctx->file, ctx->offset + codecoffset, SEEK_SET); fread(&ctx->channel[i].infodspadpcm, sizeof(cwav_dspadpcminfo), 1, ctx->file); } } @@ -98,7 +98,7 @@ void cwav_process(cwav_context* ctx, u32 actions) { u32 codecoffset = channeloffset + getle32(ctx->channel[i].info.codecref.offset); - fseek(ctx->file, ctx->offset + codecoffset, SEEK_SET); + fseeko64(ctx->file, ctx->offset + codecoffset, SEEK_SET); fread(&ctx->channel[i].infoimaadpcm, sizeof(cwav_imaadpcminfo), 1, ctx->file); } } diff --git a/ctrtool/cwav.h b/ctrtool/cwav.h index e75f22c..180f4b0 100644 --- a/ctrtool/cwav.h +++ b/ctrtool/cwav.h @@ -165,8 +165,8 @@ typedef struct { FILE* file; settings* usersettings; - u32 offset; - u32 size; + u64 offset; + u64 size; u32 channelcount; cwav_header header; cwav_infoheader infoheader; @@ -175,8 +175,8 @@ typedef struct void cwav_init(cwav_context* ctx); void cwav_set_file(cwav_context* ctx, FILE* file); -void cwav_set_offset(cwav_context* ctx, u32 offset); -void cwav_set_size(cwav_context* ctx, u32 size); +void cwav_set_offset(cwav_context* ctx, u64 offset); +void cwav_set_size(cwav_context* ctx, u64 size); void cwav_set_usersettings(cwav_context* ctx, settings* usersettings); void cwav_process(cwav_context* ctx, u32 actions); void cwav_dspadpcm_init(cwav_dspadpcmstate* state); diff --git a/ctrtool/exefs.c b/ctrtool/exefs.c index 7807071..3618043 100644 --- a/ctrtool/exefs.c +++ b/ctrtool/exefs.c @@ -18,12 +18,12 @@ void exefs_set_file(exefs_context* ctx, FILE* file) ctx->file = file; } -void exefs_set_offset(exefs_context* ctx, u32 offset) +void exefs_set_offset(exefs_context* ctx, u64 offset) { ctx->offset = offset; } -void exefs_set_size(exefs_context* ctx, u32 size) +void exefs_set_size(exefs_context* ctx, u64 size) { ctx->size = size; } @@ -122,10 +122,8 @@ void exefs_save(exefs_context* ctx, u32 index, u32 flags) fprintf(stderr, "Error, failed to create file %s\n", outfname); goto clean; } - - - fseek(ctx->file, ctx->offset + offset, SEEK_SET); + fseeko64(ctx->file, ctx->offset + offset, SEEK_SET); ctr_init_counter(&ctx->aes, ctx->key, ctx->counter); ctr_add_counter(&ctx->aes, offset / 0x10); @@ -209,7 +207,7 @@ clean: void exefs_read_header(exefs_context* ctx, u32 flags) { - fseek(ctx->file, ctx->offset, SEEK_SET); + fseeko64(ctx->file, ctx->offset, SEEK_SET); fread(&ctx->header, 1, sizeof(exefs_header), ctx->file); ctr_init_counter(&ctx->aes, ctx->key, ctx->counter); @@ -270,7 +268,7 @@ int exefs_verify(exefs_context* ctx, u32 index, u32 flags) if (size == 0) return 0; - fseek(ctx->file, ctx->offset + offset, SEEK_SET); + fseeko64(ctx->file, ctx->offset + offset, SEEK_SET); ctr_init_counter(&ctx->aes, ctx->key, ctx->counter); ctr_add_counter(&ctx->aes, offset / 0x10); diff --git a/ctrtool/exefs.h b/ctrtool/exefs.h index a062478..28afffb 100644 --- a/ctrtool/exefs.h +++ b/ctrtool/exefs.h @@ -30,8 +30,8 @@ typedef struct u8 partitionid[8]; u8 counter[16]; u8 key[16]; - u32 offset; - u32 size; + u64 offset; + u64 size; exefs_header header; ctr_aes_context aes; ctr_sha256_context sha; @@ -42,8 +42,8 @@ typedef struct void exefs_init(exefs_context* ctx); void exefs_set_file(exefs_context* ctx, FILE* file); -void exefs_set_offset(exefs_context* ctx, u32 offset); -void exefs_set_size(exefs_context* ctx, u32 size); +void exefs_set_offset(exefs_context* ctx, u64 offset); +void exefs_set_size(exefs_context* ctx, u64 size); void exefs_set_usersettings(exefs_context* ctx, settings* usersettings); void exefs_set_partitionid(exefs_context* ctx, u8 partitionid[8]); void exefs_set_counter(exefs_context* ctx, u8 counter[16]); diff --git a/ctrtool/exheader.c b/ctrtool/exheader.c index a7e16b1..9715616 100644 --- a/ctrtool/exheader.c +++ b/ctrtool/exheader.c @@ -17,12 +17,12 @@ void exheader_set_file(exheader_context* ctx, FILE* file) ctx->file = file; } -void exheader_set_offset(exheader_context* ctx, u32 offset) +void exheader_set_offset(exheader_context* ctx, u64 offset) { ctx->offset = offset; } -void exheader_set_size(exheader_context* ctx, u32 size) +void exheader_set_size(exheader_context* ctx, u64 size) { ctx->size = size; } @@ -88,7 +88,7 @@ void exheader_read(exheader_context* ctx, u32 actions) { if (ctx->haveread == 0) { - fseek(ctx->file, ctx->offset, SEEK_SET); + fseeko64(ctx->file, ctx->offset, SEEK_SET); fread(&ctx->header, 1, sizeof(exheader_header), ctx->file); ctr_init_counter(&ctx->aes, ctx->key, ctx->counter); diff --git a/ctrtool/exheader.h b/ctrtool/exheader.h index 63bb169..9691e0f 100644 --- a/ctrtool/exheader.h +++ b/ctrtool/exheader.h @@ -154,8 +154,8 @@ typedef struct u8 hash[32]; u8 counter[16]; u8 key[16]; - u32 offset; - u32 size; + u64 offset; + u64 size; exheader_header header; exheader_arm11systemlocalcaps_deserialised system_local_caps; @@ -181,8 +181,8 @@ typedef struct void exheader_init(exheader_context* ctx); void exheader_set_file(exheader_context* ctx, FILE* file); -void exheader_set_offset(exheader_context* ctx, u32 offset); -void exheader_set_size(exheader_context* ctx, u32 size); +void exheader_set_offset(exheader_context* ctx, u64 offset); +void exheader_set_size(exheader_context* ctx, u64 size); void exheader_set_partitionid(exheader_context* ctx, u8 partitionid[8]); void exheader_set_counter(exheader_context* ctx, u8 counter[16]); void exheader_set_programid(exheader_context* ctx, u8 programid[8]); diff --git a/ctrtool/firm.c b/ctrtool/firm.c index 5c3d07d..e865cc0 100644 --- a/ctrtool/firm.c +++ b/ctrtool/firm.c @@ -16,7 +16,7 @@ void firm_set_file(firm_context* ctx, FILE* file) ctx->file = file; } -void firm_set_offset(firm_context* ctx, u32 offset) +void firm_set_offset(firm_context* ctx, u64 offset) { ctx->offset = offset; } @@ -66,7 +66,7 @@ void firm_save(firm_context* ctx, u32 index, u32 flags) - fseek(ctx->file, ctx->offset + offset, SEEK_SET); + fseeko64(ctx->file, ctx->offset + offset, SEEK_SET); fprintf(stdout, "Saving section %d to %s...\n", index, outpath.pathname); while(size) @@ -100,7 +100,7 @@ void firm_process(firm_context* ctx, u32 actions) { u32 i; - fseek(ctx->file, ctx->offset, SEEK_SET); + fseeko64(ctx->file, ctx->offset, SEEK_SET); fread(&ctx->header, 1, sizeof(firm_header), ctx->file); if (getle32(ctx->header.magic) != MAGIC_FIRM) @@ -154,7 +154,7 @@ int firm_verify(firm_context* ctx, u32 flags) if (size == 0) return 0; - fseek(ctx->file, ctx->offset + offset, SEEK_SET); + fseeko64(ctx->file, ctx->offset + offset, SEEK_SET); ctr_sha_256_init(&ctx->sha); diff --git a/ctrtool/firm.h b/ctrtool/firm.h index c663f71..29af98f 100644 --- a/ctrtool/firm.h +++ b/ctrtool/firm.h @@ -35,7 +35,7 @@ typedef struct { FILE* file; settings* usersettings; - u32 offset; + u64 offset; u32 size; firm_header header; ctr_sha256_context sha; @@ -45,7 +45,7 @@ typedef struct void firm_init(firm_context* ctx); void firm_set_file(firm_context* ctx, FILE* file); -void firm_set_offset(firm_context* ctx, u32 offset); +void firm_set_offset(firm_context* ctx, u64 offset); void firm_set_size(firm_context* ctx, u32 size); void firm_set_usersettings(firm_context* ctx, settings* usersettings); void firm_process(firm_context* ctx, u32 actions); diff --git a/ctrtool/ivfc.c b/ctrtool/ivfc.c index a4796ac..7fbb5fc 100644 --- a/ctrtool/ivfc.c +++ b/ctrtool/ivfc.c @@ -17,12 +17,12 @@ void ivfc_set_usersettings(ivfc_context* ctx, settings* usersettings) ctx->usersettings = usersettings; } -void ivfc_set_offset(ivfc_context* ctx, u32 offset) +void ivfc_set_offset(ivfc_context* ctx, u64 offset) { ctx->offset = offset; } -void ivfc_set_size(ivfc_context* ctx, u32 size) +void ivfc_set_size(ivfc_context* ctx, u64 size) { ctx->size = size; } @@ -35,9 +35,7 @@ void ivfc_set_file(ivfc_context* ctx, FILE* file) void ivfc_process(ivfc_context* ctx, u32 actions) { - - - fseek(ctx->file, ctx->offset, SEEK_SET); + fseeko64(ctx->file, ctx->offset, SEEK_SET); fread(&ctx->header, 1, sizeof(ivfc_header), ctx->file); if (getle32(ctx->header.magic) != MAGIC_IVFC) @@ -55,22 +53,22 @@ void ivfc_process(ivfc_context* ctx, u32 actions) ctx->level[2].hashblocksize = 1 << getle32(ctx->romfsheader.level3.blocksize); ctx->level[1].hashblocksize = 1 << getle32(ctx->romfsheader.level2.blocksize); ctx->level[0].hashblocksize = 1 << getle32(ctx->romfsheader.level1.blocksize); - ctx->level[0].hashoffset = 0x60; - ctx->bodyoffset = align64(ctx->level[0].hashoffset + getle32(ctx->romfsheader.masterhashsize), ctx->level[2].hashblocksize); + ctx->bodyoffset = align64(IVFC_HEADER_SIZE + getle32(ctx->romfsheader.masterhashsize), ctx->level[2].hashblocksize); ctx->bodysize = getle64(ctx->romfsheader.level3.hashdatasize); ctx->level[2].dataoffset = ctx->bodyoffset; ctx->level[2].datasize = align64(ctx->bodysize, ctx->level[2].hashblocksize); - ctx->level[1].hashoffset = align64(ctx->bodyoffset + ctx->bodysize, ctx->level[2].hashblocksize); - ctx->level[2].hashoffset = ctx->level[1].hashoffset + getle64(ctx->romfsheader.level2.logicaloffset) - getle64(ctx->romfsheader.level1.logicaloffset); + ctx->level[0].dataoffset = ctx->level[2].dataoffset + ctx->level[2].datasize; + ctx->level[0].datasize = align64(getle64(ctx->romfsheader.level1.hashdatasize), ctx->level[0].hashblocksize); - ctx->level[1].dataoffset = ctx->level[2].hashoffset; + ctx->level[1].dataoffset = ctx->level[0].dataoffset + ctx->level[0].datasize; ctx->level[1].datasize = align64(getle64(ctx->romfsheader.level2.hashdatasize), ctx->level[1].hashblocksize); - ctx->level[0].dataoffset = ctx->level[1].hashoffset; - ctx->level[0].datasize = align64(getle64(ctx->romfsheader.level1.hashdatasize), ctx->level[0].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) @@ -98,7 +96,7 @@ void ivfc_verify(ivfc_context* ctx, u32 flags) ivfc_level* level = ctx->level + i; blockcount = level->datasize / level->hashblocksize; - if (blockcount * level->hashblocksize != level->datasize) + if (level->datasize % level->hashblocksize != 0) { fprintf(stderr, "Error, IVFC block size mismatch\n"); return; @@ -110,7 +108,6 @@ void ivfc_verify(ivfc_context* ctx, u32 flags) { u8 calchash[32]; u8 testhash[32]; - ivfc_hash(ctx, level->dataoffset + level->hashblocksize * j, level->hashblocksize, calchash); ivfc_read(ctx, level->hashoffset + 0x20 * j, 0x20, testhash); @@ -121,15 +118,15 @@ void ivfc_verify(ivfc_context* ctx, u32 flags) } } -void ivfc_read(ivfc_context* ctx, u32 offset, u32 size, u8* buffer) +void ivfc_read(ivfc_context* ctx, u64 offset, u64 size, u8* buffer) { if ( (offset > ctx->size) || (offset+size > ctx->size) ) { - fprintf(stderr, "Error, IVFC offset out of range (offset=0x%08x, size=0x%08x)\n", offset, size); + fprintf(stderr, "Error, IVFC offset out of range (offset=0x%08"PRIx64", size=0x%08"PRIx64")\n", offset, size); return; } - fseek(ctx->file, ctx->offset + offset, SEEK_SET); + fseeko64(ctx->file, ctx->offset + offset, SEEK_SET); if (size != fread(buffer, 1, size, ctx->file)) { fprintf(stderr, "Error, IVFC could not read file\n"); @@ -137,7 +134,7 @@ void ivfc_read(ivfc_context* ctx, u32 offset, u32 size, u8* buffer) } } -void ivfc_hash(ivfc_context* ctx, u32 offset, u32 size, u8* hash) +void ivfc_hash(ivfc_context* ctx, u64 offset, u64 size, u8* hash) { if (size > IVFC_MAX_BUFFERSIZE) { @@ -157,7 +154,7 @@ void ivfc_print(ivfc_context* ctx) fprintf(stdout, "\nIVFC:\n"); - fprintf(stdout, "Header: %c%c%c%c\n", header->magic[0], header->magic[1], header->magic[2], header->magic[3]); + fprintf(stdout, "Header: %.4s\n", header->magic); fprintf(stdout, "Id: %08x\n", getle32(header->id)); for(i=0; ilevelcount; i++) @@ -169,9 +166,9 @@ void ivfc_print(ivfc_context* ctx) fprintf(stdout, "Level %d: \n", i); else fprintf(stdout, "Level %d (%s): \n", i, level->hashcheck == Good? "GOOD" : "FAIL"); - fprintf(stdout, " Data offset: 0x%016"PRIx64"\n", ctx->offset + level->dataoffset); - fprintf(stdout, " Data size: 0x%016"PRIx64"\n", level->datasize); - fprintf(stdout, " Hash offset: 0x%016"PRIx64"\n", ctx->offset + level->hashoffset); + fprintf(stdout, " Data offset: 0x%08"PRIx64"\n", ctx->offset + level->dataoffset); + fprintf(stdout, " Data size: 0x%08"PRIx64"\n", level->datasize); + fprintf(stdout, " Hash offset: 0x%08"PRIx64"\n", ctx->offset + level->hashoffset); fprintf(stdout, " Hash block size: 0x%08x\n", level->hashblocksize); } } diff --git a/ctrtool/ivfc.h b/ctrtool/ivfc.h index e4e9256..5c0aa1b 100644 --- a/ctrtool/ivfc.h +++ b/ctrtool/ivfc.h @@ -4,6 +4,7 @@ #include "types.h" #include "settings.h" +#define IVFC_HEADER_SIZE 0x60 #define IVFC_MAX_LEVEL 4 #define IVFC_MAX_BUFFERSIZE 0x4000 @@ -43,8 +44,8 @@ typedef struct typedef struct { FILE* file; - u32 offset; - u32 size; + u64 offset; + u64 size; settings* usersettings; ivfc_header header; @@ -59,14 +60,14 @@ typedef struct void ivfc_init(ivfc_context* ctx); void ivfc_process(ivfc_context* ctx, u32 actions); -void ivfc_set_offset(ivfc_context* ctx, u32 offset); -void ivfc_set_size(ivfc_context* ctx, u32 size); +void ivfc_set_offset(ivfc_context* ctx, u64 offset); +void ivfc_set_size(ivfc_context* ctx, u64 size); void ivfc_set_file(ivfc_context* ctx, FILE* file); void ivfc_set_usersettings(ivfc_context* ctx, settings* usersettings); void ivfc_verify(ivfc_context* ctx, u32 flags); void ivfc_print(ivfc_context* ctx); -void ivfc_read(ivfc_context* ctx, u32 offset, u32 size, u8* buffer); -void ivfc_hash(ivfc_context* ctx, u32 offset, u32 size, u8* hash); +void ivfc_read(ivfc_context* ctx, u64 offset, u64 size, u8* buffer); +void ivfc_hash(ivfc_context* ctx, u64 offset, u64 size, u8* hash); #endif // __IVFC_H__ diff --git a/ctrtool/lzss.c b/ctrtool/lzss.c index 93bc769..1a853a5 100644 --- a/ctrtool/lzss.c +++ b/ctrtool/lzss.c @@ -40,7 +40,7 @@ void lzss_process(lzss_context* ctx, u32 actions) FILE* fout = 0; - fseek(ctx->file, ctx->offset, SEEK_SET); + fseeko64(ctx->file, ctx->offset, SEEK_SET); if (actions & ExtractFlag) diff --git a/ctrtool/main.c b/ctrtool/main.c index dabd615..c5ef33c 100644 --- a/ctrtool/main.c +++ b/ctrtool/main.c @@ -31,7 +31,7 @@ typedef struct int actions; u32 filetype; FILE* infile; - u32 infilesize; + u64 infilesize; settings usersettings; } toolcontext; @@ -259,6 +259,7 @@ int main(int argc, char* argv[]) if (ctx.actions & ShowKeysFlag) keyset_dump(&ctx.usersettings.keys); + ctx.infilesize = _fsize(infname); ctx.infile = fopen(infname, "rb"); if (ctx.infile == 0) @@ -267,16 +268,9 @@ int main(int argc, char* argv[]) return -1; } - fseek(ctx.infile, 0, SEEK_END); - ctx.infilesize = ftell(ctx.infile); - fseek(ctx.infile, 0, SEEK_SET); - - - - if (ctx.filetype == FILETYPE_UNKNOWN) { - fseek(ctx.infile, 0x100, SEEK_SET); + fseeko64(ctx.infile, 0x100, SEEK_SET); fread(&magic, 1, 4, ctx.infile); switch(getle32(magic)) @@ -296,7 +290,7 @@ int main(int argc, char* argv[]) if (ctx.filetype == FILETYPE_UNKNOWN) { - fseek(ctx.infile, 0, SEEK_SET); + fseeko64(ctx.infile, 0, SEEK_SET); fread(magic, 1, 4, ctx.infile); switch(getle32(magic)) diff --git a/ctrtool/ncch.c b/ctrtool/ncch.c index 5de61ce..991afc3 100644 --- a/ctrtool/ncch.c +++ b/ctrtool/ncch.c @@ -30,12 +30,12 @@ void ncch_set_usersettings(ncch_context* ctx, settings* usersettings) ctx->usersettings = usersettings; } -void ncch_set_offset(ncch_context* ctx, u32 offset) +void ncch_set_offset(ncch_context* ctx, u64 offset) { ctx->offset = offset; } -void ncch_set_size(ncch_context* ctx, u32 size) +void ncch_set_size(ncch_context* ctx, u64 size) { ctx->size = size; } @@ -51,7 +51,7 @@ void ncch_get_counter(ncch_context* ctx, u8 counter[16], u8 type) u32 mediaunitsize = ncch_get_mediaunit_size(ctx); u8* partitionid = ctx->header.partitionid; u32 i; - u32 x = 0; + u64 x = 0; memset(counter, 0, 16); @@ -81,8 +81,8 @@ void ncch_get_counter(ncch_context* ctx, u8 counter[16], u8 type) int ncch_extract_prepare(ncch_context* ctx, u32 type, u32 flags) { - u32 offset = 0; - u32 size = 0; + u64 offset = 0; + u64 size = 0; u8 counter[16]; @@ -126,7 +126,7 @@ int ncch_extract_prepare(ncch_context* ctx, u32 type, u32 flags) ctx->extractsize = size; ctx->extractflags = flags; - fseek(ctx->file, offset, SEEK_SET); + fseeko64(ctx->file, offset, SEEK_SET); ncch_get_counter(ctx, counter, type); ctr_init_counter(&ctx->aes, ctx->key, counter); @@ -138,25 +138,25 @@ clean: int ncch_extract_buffer(ncch_context* ctx, u8* buffer, u32 buffersize, u32* outsize, u8 nocrypto) { - u32 max = buffersize; + u32 read_len = buffersize; - if (max > ctx->extractsize) - max = ctx->extractsize; + if (read_len > ctx->extractsize) + read_len = ctx->extractsize; - *outsize = max; + *outsize = read_len; if (ctx->extractsize) { - if (max != fread(buffer, 1, max, ctx->file)) + if (read_len != fread(buffer, 1, read_len, ctx->file)) { fprintf(stdout, "Error reading input file\n"); goto clean; } if (ctx->encrypted && !nocrypto) - ctr_crypt_counter(&ctx->aes, buffer, buffer, max); + ctr_crypt_counter(&ctx->aes, buffer, buffer, read_len); - ctx->extractsize -= max; + ctx->extractsize -= read_len; } return 1; @@ -203,15 +203,15 @@ void ncch_save(ncch_context* ctx, u32 type, u32 flags) while(1) { - u32 max; + u32 read_len; - if (0 == ncch_extract_buffer(ctx, buffer, sizeof(buffer), &max, type == NCCHTYPE_LOGO)) + if (0 == ncch_extract_buffer(ctx, buffer, sizeof(buffer), &read_len, type == NCCHTYPE_LOGO)) goto clean; - if (max == 0) + if (read_len == 0) break; - if (max != fwrite(buffer, 1, max, fout)) + if (read_len != fwrite(buffer, 1, read_len, fout)) { fprintf(stdout, "Error writing output file\n"); goto clean; @@ -307,7 +307,7 @@ void ncch_process(ncch_context* ctx, u32 actions) int result = 1; - fseek(ctx->file, ctx->offset, SEEK_SET); + fseeko64(ctx->file, ctx->offset, SEEK_SET); fread(&ctx->header, 1, 0x200, ctx->file); if (getle32(ctx->header.magic) != MAGIC_NCCH) @@ -385,53 +385,47 @@ int ncch_signature_verify(ncch_context* ctx, rsakey2048* key) } -u32 ncch_get_exefs_offset(ncch_context* ctx) +u64 ncch_get_exefs_offset(ncch_context* ctx) { - u32 mediaunitsize = ncch_get_mediaunit_size(ctx); - return ctx->offset + getle32(ctx->header.exefsoffset) * mediaunitsize; + return ctx->offset + getle32(ctx->header.exefsoffset) * ncch_get_mediaunit_size(ctx); } -u32 ncch_get_exefs_size(ncch_context* ctx) +u64 ncch_get_exefs_size(ncch_context* ctx) { - u32 mediaunitsize = ncch_get_mediaunit_size(ctx); - return getle32(ctx->header.exefssize) * mediaunitsize; + return getle32(ctx->header.exefssize) * ncch_get_mediaunit_size(ctx); } -u32 ncch_get_romfs_offset(ncch_context* ctx) +u64 ncch_get_romfs_offset(ncch_context* ctx) { - u32 mediaunitsize = ncch_get_mediaunit_size(ctx); - return ctx->offset + getle32(ctx->header.romfsoffset) * mediaunitsize; + return ctx->offset + getle32(ctx->header.romfsoffset) * ncch_get_mediaunit_size(ctx); } -u32 ncch_get_romfs_size(ncch_context* ctx) +u64 ncch_get_romfs_size(ncch_context* ctx) { - u32 mediaunitsize = ncch_get_mediaunit_size(ctx); - return getle32(ctx->header.romfssize) * mediaunitsize; + return getle32(ctx->header.romfssize) * ncch_get_mediaunit_size(ctx); } -u32 ncch_get_exheader_offset(ncch_context* ctx) +u64 ncch_get_exheader_offset(ncch_context* ctx) { return ctx->offset + 0x200; } -u32 ncch_get_exheader_size(ncch_context* ctx) +u64 ncch_get_exheader_size(ncch_context* ctx) { return getle32(ctx->header.extendedheadersize); } -u32 ncch_get_logo_offset(ncch_context* ctx) +u64 ncch_get_logo_offset(ncch_context* ctx) { - u32 mediaunitsize = ncch_get_mediaunit_size(ctx); - return ctx->offset + getle32(ctx->header.logooffset) * mediaunitsize; + return ctx->offset + getle32(ctx->header.logooffset) * ncch_get_mediaunit_size(ctx); } -u32 ncch_get_logo_size(ncch_context* ctx) +u64 ncch_get_logo_size(ncch_context* ctx) { - u32 mediaunitsize = ncch_get_mediaunit_size(ctx); - return getle32(ctx->header.logosize) * mediaunitsize; + return getle32(ctx->header.logosize) * ncch_get_mediaunit_size(ctx); } -u32 ncch_get_mediaunit_size(ncch_context* ctx) +u64 ncch_get_mediaunit_size(ncch_context* ctx) { unsigned int mediaunitsize = settings_get_mediaunit_size(ctx->usersettings); @@ -473,7 +467,7 @@ void ncch_determine_key(ncch_context* ctx, u32 actions) // Firstly, check if the NCCH is already decrypted, by reading the programid in the exheader // Otherwise, use determination rules - fseek(ctx->file, ncch_get_exheader_offset(ctx), SEEK_SET); + fseeko64(ctx->file, ncch_get_exheader_offset(ctx), SEEK_SET); memset(&exheader, 0, sizeof(exheader)); fread(&exheader, 1, sizeof(exheader), ctx->file); @@ -560,9 +554,8 @@ static const char* contentplatformtostring(unsigned char platform) void ncch_print(ncch_context* ctx) { ctr_ncchheader *header = &ctx->header; - u32 offset = ctx->offset; - u32 mediaunitsize = ncch_get_mediaunit_size(ctx); - + u64 offset = ctx->offset; + u64 mediaunitsize = ncch_get_mediaunit_size(ctx); fprintf(stdout, "\nNCCH:\n"); @@ -573,10 +566,10 @@ void ncch_print(ncch_context* ctx) memdump(stdout, "Signature (GOOD): ", header->signature, 0x100); else memdump(stdout, "Signature (FAIL): ", header->signature, 0x100); - fprintf(stdout, "Content size: 0x%08x\n", getle32(header->contentsize)*mediaunitsize); + fprintf(stdout, "Content size: 0x%08"PRIx64"\n", getle32(header->contentsize)*mediaunitsize); fprintf(stdout, "Partition id: %016"PRIx64"\n", getle64(header->partitionid)); fprintf(stdout, "Maker code: %.2s\n", header->makercode); - fprintf(stdout, "Version: %04x\n", getle16(header->version)); + fprintf(stdout, "Version: %d\n", getle16(header->version)); fprintf(stdout, "Title seed check: %08x\n", getle32(header->seedcheck)); fprintf(stdout, "Program id: %016"PRIx64"\n", getle64(header->programid)); if(ctx->logohashcheck == Unchecked) @@ -594,7 +587,7 @@ void ncch_print(ncch_context* ctx) else memdump(stdout, "Exheader hash (FAIL): ", header->extendedheaderhash, 0x20); fprintf(stdout, "Flags: %016"PRIx64"\n", getle64(header->flags)); - fprintf(stdout, " > Mediaunit size: 0x%x\n", mediaunitsize); + fprintf(stdout, " > Mediaunit size: 0x%x\n", (u32)mediaunitsize); if (header->flags[7] & 4) fprintf(stdout, " > Crypto key: None\n"); else if (header->flags[7] & 1) @@ -608,16 +601,16 @@ void ncch_print(ncch_context* ctx) fprintf(stdout, " > No RomFS mount\n"); - fprintf(stdout, "Plain region offset: 0x%08x\n", getle32(header->plainregionsize)? offset+getle32(header->plainregionoffset)*mediaunitsize : 0); - fprintf(stdout, "Plain region size: 0x%08x\n", getle32(header->plainregionsize)*mediaunitsize); - fprintf(stdout, "Logo offset: 0x%08x\n", getle32(header->logosize)? offset+getle32(header->logooffset)*mediaunitsize : 0); - fprintf(stdout, "Logo size: 0x%08x\n", getle32(header->logosize)*mediaunitsize); - fprintf(stdout, "ExeFS offset: 0x%08x\n", getle32(header->exefssize)? offset+getle32(header->exefsoffset)*mediaunitsize : 0); - fprintf(stdout, "ExeFS size: 0x%08x\n", getle32(header->exefssize)*mediaunitsize); - fprintf(stdout, "ExeFS hash region size: 0x%08x\n", getle32(header->exefshashregionsize)*mediaunitsize); - fprintf(stdout, "RomFS offset: 0x%08x\n", getle32(header->romfssize)? offset+getle32(header->romfsoffset)*mediaunitsize : 0); - fprintf(stdout, "RomFS size: 0x%08x\n", getle32(header->romfssize)*mediaunitsize); - fprintf(stdout, "RomFS hash region size: 0x%08x\n", getle32(header->romfshashregionsize)*mediaunitsize); + fprintf(stdout, "Plain region offset: 0x%08"PRIx64"\n", getle32(header->plainregionsize)? offset+getle32(header->plainregionoffset)*mediaunitsize : 0); + fprintf(stdout, "Plain region size: 0x%08"PRIx64"\n", getle32(header->plainregionsize)*mediaunitsize); + fprintf(stdout, "Logo offset: 0x%08"PRIx64"\n", getle32(header->logosize)? offset+getle32(header->logooffset)*mediaunitsize : 0); + fprintf(stdout, "Logo size: 0x%08"PRIx64"\n", getle32(header->logosize)*mediaunitsize); + fprintf(stdout, "ExeFS offset: 0x%08"PRIx64"\n", getle32(header->exefssize)? offset+getle32(header->exefsoffset)*mediaunitsize : 0); + fprintf(stdout, "ExeFS size: 0x%08"PRIx64"\n", getle32(header->exefssize)*mediaunitsize); + fprintf(stdout, "ExeFS hash region size: 0x%08"PRIx64"\n", getle32(header->exefshashregionsize)*mediaunitsize); + fprintf(stdout, "RomFS offset: 0x%08"PRIx64"\n", getle32(header->romfssize)? offset+getle32(header->romfsoffset)*mediaunitsize : 0); + fprintf(stdout, "RomFS size: 0x%08"PRIx64"\n", getle32(header->romfssize)*mediaunitsize); + fprintf(stdout, "RomFS hash region size: 0x%08"PRIx64"\n", getle32(header->romfshashregionsize)*mediaunitsize); if (ctx->exefshashcheck == Unchecked) memdump(stdout, "ExeFS Hash: ", header->exefssuperblockhash, 0x20); else if (ctx->exefshashcheck == Good) diff --git a/ctrtool/ncch.h b/ctrtool/ncch.h index f453bb5..4bad2be 100644 --- a/ctrtool/ncch.h +++ b/ctrtool/ncch.h @@ -57,8 +57,8 @@ typedef struct FILE* file; u8 key[16]; u32 encrypted; - u32 offset; - u32 size; + u64 offset; + u64 size; settings* usersettings; ctr_ncchheader header; ctr_aes_context aes; @@ -69,31 +69,31 @@ typedef struct int exheaderhashcheck; int logohashcheck; int headersigcheck; - u32 extractsize; + u64 extractsize; u32 extractflags; } ncch_context; void ncch_init(ncch_context* ctx); void ncch_process(ncch_context* ctx, u32 actions); -void ncch_set_offset(ncch_context* ctx, u32 offset); -void ncch_set_size(ncch_context* ctx, u32 size); +void ncch_set_offset(ncch_context* ctx, u64 offset); +void ncch_set_size(ncch_context* ctx, u64 size); void ncch_set_file(ncch_context* ctx, FILE* file); void ncch_set_usersettings(ncch_context* ctx, settings* usersettings); -u32 ncch_get_exefs_offset(ncch_context* ctx); -u32 ncch_get_exefs_size(ncch_context* ctx); -u32 ncch_get_romfs_offset(ncch_context* ctx); -u32 ncch_get_romfs_size(ncch_context* ctx); -u32 ncch_get_exheader_offset(ncch_context* ctx); -u32 ncch_get_exheader_size(ncch_context* ctx); -u32 ncch_get_logo_offset(ncch_context* ctx); -u32 ncch_get_logo_size(ncch_context* ctx); +u64 ncch_get_exefs_offset(ncch_context* ctx); +u64 ncch_get_exefs_size(ncch_context* ctx); +u64 ncch_get_romfs_offset(ncch_context* ctx); +u64 ncch_get_romfs_size(ncch_context* ctx); +u64 ncch_get_exheader_offset(ncch_context* ctx); +u64 ncch_get_exheader_size(ncch_context* ctx); +u64 ncch_get_logo_offset(ncch_context* ctx); +u64 ncch_get_logo_size(ncch_context* ctx); void ncch_print(ncch_context* ctx); int ncch_signature_verify(ncch_context* ctx, rsakey2048* key); void ncch_verify(ncch_context* ctx, u32 flags); void ncch_save(ncch_context* ctx, u32 type, u32 flags); int ncch_extract_prepare(ncch_context* ctx, u32 type, u32 flags); int ncch_extract_buffer(ncch_context* ctx, u8* buffer, u32 buffersize, u32* outsize, u8 nocrypto); -u32 ncch_get_mediaunit_size(ncch_context* ctx); +u64 ncch_get_mediaunit_size(ncch_context* ctx); void ncch_get_counter(ncch_context* ctx, u8 counter[16], u8 type); void ncch_determine_key(ncch_context* ctx, u32 actions); #endif // _NCCH_H_ diff --git a/ctrtool/ncsd.c b/ctrtool/ncsd.c index cfa55a3..384216a 100644 --- a/ctrtool/ncsd.c +++ b/ctrtool/ncsd.c @@ -13,7 +13,7 @@ void ncsd_init(ncsd_context* ctx) memset(ctx, 0, sizeof(ncsd_context)); } -void ncsd_set_offset(ncsd_context* ctx, u32 offset) +void ncsd_set_offset(ncsd_context* ctx, u64 offset) { ctx->offset = offset; } @@ -23,7 +23,7 @@ void ncsd_set_file(ncsd_context* ctx, FILE* file) ctx->file = file; } -void ncsd_set_size(ncsd_context* ctx, u32 size) +void ncsd_set_size(ncsd_context* ctx, u64 size) { ctx->size = size; } @@ -48,7 +48,7 @@ int ncsd_signature_verify(const void* blob, rsakey2048* key) return ctr_rsa_verify_hash(sig, hash, key); } -unsigned int ncsd_get_mediaunit_size(ncsd_context* ctx) +u64 ncsd_get_mediaunit_size(ncsd_context* ctx) { unsigned int mediaunitsize = settings_get_mediaunit_size(ctx->usersettings); @@ -60,7 +60,7 @@ unsigned int ncsd_get_mediaunit_size(ncsd_context* ctx) void ncsd_process(ncsd_context* ctx, u32 actions) { - fseek(ctx->file, ctx->offset, SEEK_SET); + fseeko64(ctx->file, ctx->offset, SEEK_SET); fread(&ctx->header, 1, 0x200, ctx->file); if (getle32(ctx->header.magic) != MAGIC_NCSD) diff --git a/ctrtool/ncsd.h b/ctrtool/ncsd.h index 58b8506..afd895a 100644 --- a/ctrtool/ncsd.h +++ b/ctrtool/ncsd.h @@ -33,8 +33,8 @@ typedef struct typedef struct { FILE* file; - u32 offset; - u32 size; + u64 offset; + u64 size; u32 ncch_index; ctr_ncsdheader header; settings* usersettings; @@ -44,14 +44,14 @@ typedef struct void ncsd_init(ncsd_context* ctx); -void ncsd_set_offset(ncsd_context* ctx, u32 offset); -void ncsd_set_size(ncsd_context* ctx, u32 size); +void ncsd_set_offset(ncsd_context* ctx, u64 offset); +void ncsd_set_size(ncsd_context* ctx, u64 size); void ncsd_set_ncch_index(ncsd_context* ctx, u32 ncch_index); void ncsd_set_file(ncsd_context* ctx, FILE* file); void ncsd_set_usersettings(ncsd_context* ctx, settings* usersettings); int ncsd_signature_verify(const void* blob, rsakey2048* key); void ncsd_process(ncsd_context* ctx, u32 actions); void ncsd_print(ncsd_context* ctx); -unsigned int ncsd_get_mediaunit_size(ncsd_context* ctx); +u64 ncsd_get_mediaunit_size(ncsd_context* ctx); #endif // _NCSD_H_ diff --git a/ctrtool/romfs.c b/ctrtool/romfs.c index ad45181..df95fdc 100644 --- a/ctrtool/romfs.c +++ b/ctrtool/romfs.c @@ -18,12 +18,12 @@ void romfs_set_file(romfs_context* ctx, FILE* file) ctx->file = file; } -void romfs_set_offset(romfs_context* ctx, u32 offset) +void romfs_set_offset(romfs_context* ctx, u64 offset) { ctx->offset = offset; } -void romfs_set_size(romfs_context* ctx, u32 size) +void romfs_set_size(romfs_context* ctx, u64 size) { ctx->size = size; } @@ -49,7 +49,7 @@ void romfs_process(romfs_context* ctx, u32 actions) ivfc_set_usersettings(&ctx->ivfc, ctx->usersettings); ivfc_process(&ctx->ivfc, actions); - fseek(ctx->file, ctx->offset, SEEK_SET); + fseeko64(ctx->file, ctx->offset, SEEK_SET); fread(&ctx->header, 1, sizeof(romfs_header), ctx->file); if (getle32(ctx->header.magic) != MAGIC_IVFC) @@ -60,7 +60,7 @@ void romfs_process(romfs_context* ctx, u32 actions) ctx->infoblockoffset = ctx->offset + 0x1000; - fseek(ctx->file, ctx->infoblockoffset, SEEK_SET); + fseeko64(ctx->file, ctx->infoblockoffset, SEEK_SET); fread(&ctx->infoheader, 1, sizeof(romfs_infoheader), ctx->file); if (getle32(ctx->infoheader.headersize) != sizeof(romfs_infoheader)) @@ -83,13 +83,13 @@ void romfs_process(romfs_context* ctx, u32 actions) if (ctx->dirblock) { - fseek(ctx->file, dirblockoffset, SEEK_SET); + fseeko64(ctx->file, dirblockoffset, SEEK_SET); fread(ctx->dirblock, 1, dirblocksize, ctx->file); } if (ctx->fileblock) { - fseek(ctx->file, fileblockoffset, SEEK_SET); + fseeko64(ctx->file, fileblockoffset, SEEK_SET); fread(ctx->fileblock, 1, fileblocksize, ctx->file); } @@ -295,13 +295,8 @@ void romfs_extract_datafile(romfs_context* ctx, u64 offset, u64 size, filepath* goto clean; offset += ctx->datablockoffset; - if ( (offset >> 32) ) - { - fprintf(stderr, "Error, support for 64-bit offset not yet implemented.\n"); - goto clean; - } - fseek(ctx->file, offset, SEEK_SET); + fseeko64(ctx->file, offset, SEEK_SET); outfile = fopen(path->pathname, "wb"); if (outfile == 0) { @@ -344,9 +339,9 @@ void romfs_print(romfs_context* ctx) fprintf(stdout, "Header size: 0x%08X\n", getle32(ctx->infoheader.headersize)); for(i=0; i<4; i++) { - fprintf(stdout, "Section %d offset: 0x%08X\n", i, ctx->offset + 0x1000 + getle32(ctx->infoheader.section[i].offset)); + fprintf(stdout, "Section %d offset: 0x%08"PRIX64"\n", i, ctx->offset + 0x1000 + getle32(ctx->infoheader.section[i].offset)); fprintf(stdout, "Section %d size: 0x%08X\n", i, getle32(ctx->infoheader.section[i].size)); } - fprintf(stdout, "Data offset: 0x%08X\n", ctx->offset + 0x1000 + getle32(ctx->infoheader.dataoffset)); + fprintf(stdout, "Data offset: 0x%08"PRIX64"\n", ctx->offset + 0x1000 + getle32(ctx->infoheader.dataoffset)); } diff --git a/ctrtool/romfs.h b/ctrtool/romfs.h index 9325635..fa84bdf 100644 --- a/ctrtool/romfs.h +++ b/ctrtool/romfs.h @@ -56,8 +56,8 @@ typedef struct { FILE* file; settings* usersettings; - u32 offset; - u32 size; + u64 offset; + u64 size; romfs_header header; romfs_infoheader infoheader; u8* dirblock; @@ -73,8 +73,8 @@ typedef struct void romfs_init(romfs_context* ctx); void romfs_set_file(romfs_context* ctx, FILE* file); -void romfs_set_offset(romfs_context* ctx, u32 offset); -void romfs_set_size(romfs_context* ctx, u32 size); +void romfs_set_offset(romfs_context* ctx, u64 offset); +void romfs_set_size(romfs_context* ctx, u64 size); void romfs_set_usersettings(romfs_context* ctx, settings* usersettings); void romfs_test(romfs_context* ctx); int romfs_dirblock_read(romfs_context* ctx, u32 diroffset, u32 dirsize, void* buffer); diff --git a/ctrtool/tik.c b/ctrtool/tik.c index 2f3c4ef..ce582c3 100644 --- a/ctrtool/tik.c +++ b/ctrtool/tik.c @@ -16,7 +16,7 @@ void tik_set_file(tik_context* ctx, FILE* file) ctx->file = file; } -void tik_set_offset(tik_context* ctx, u32 offset) +void tik_set_offset(tik_context* ctx, u64 offset) { ctx->offset = offset; } @@ -76,7 +76,7 @@ void tik_process(tik_context* ctx, u32 actions) goto clean; } - fseek(ctx->file, ctx->offset, SEEK_SET); + fseeko64(ctx->file, ctx->offset, SEEK_SET); fread((u8*)&ctx->tik, 1, sizeof(eticket), ctx->file); tik_decrypt_titlekey(ctx, ctx->titlekey); diff --git a/ctrtool/tik.h b/ctrtool/tik.h index 78b93f0..edd72c5 100644 --- a/ctrtool/tik.h +++ b/ctrtool/tik.h @@ -41,7 +41,7 @@ typedef struct typedef struct { FILE* file; - u32 offset; + u64 offset; u32 size; u8 titlekey[16]; eticket tik; @@ -51,7 +51,7 @@ typedef struct void tik_init(tik_context* ctx); void tik_set_file(tik_context* ctx, FILE* file); -void tik_set_offset(tik_context* ctx, u32 offset); +void tik_set_offset(tik_context* ctx, u64 offset); void tik_set_size(tik_context* ctx, u32 size); void tik_set_usersettings(tik_context* ctx, settings* usersettings); void tik_get_decrypted_titlekey(tik_context* ctx, u8 decryptedkey[0x10]); diff --git a/ctrtool/tmd.c b/ctrtool/tmd.c index af5691f..bcb687f 100644 --- a/ctrtool/tmd.c +++ b/ctrtool/tmd.c @@ -17,7 +17,7 @@ void tmd_set_file(tmd_context* ctx, FILE* file) ctx->file = file; } -void tmd_set_offset(tmd_context* ctx, u32 offset) +void tmd_set_offset(tmd_context* ctx, u64 offset) { ctx->offset = offset; } @@ -39,7 +39,7 @@ void tmd_process(tmd_context* ctx, u32 actions) if (ctx->buffer) { - fseek(ctx->file, ctx->offset, SEEK_SET); + fseeko64(ctx->file, ctx->offset, SEEK_SET); fread(ctx->buffer, 1, ctx->size, ctx->file); if (actions & InfoFlag) diff --git a/ctrtool/tmd.h b/ctrtool/tmd.h index 6272429..d9701a7 100644 --- a/ctrtool/tmd.h +++ b/ctrtool/tmd.h @@ -74,7 +74,7 @@ typedef struct typedef struct { FILE* file; - u32 offset; + u64 offset; u32 size; u8* buffer; u8 content_hash_stat[64]; @@ -89,7 +89,7 @@ extern "C" { void tmd_init(tmd_context* ctx); void tmd_set_file(tmd_context* ctx, FILE* file); -void tmd_set_offset(tmd_context* ctx, u32 offset); +void tmd_set_offset(tmd_context* ctx, u64 offset); void tmd_set_size(tmd_context* ctx, u32 size); void tmd_set_usersettings(tmd_context* ctx, settings* usersettings); void tmd_print(tmd_context* ctx); diff --git a/ctrtool/types.h b/ctrtool/types.h index bade7f1..9234fe1 100644 --- a/ctrtool/types.h +++ b/ctrtool/types.h @@ -2,16 +2,17 @@ #define __TYPES_H__ #include +#include -typedef unsigned char u8; -typedef unsigned short u16; -typedef unsigned int u32; -typedef unsigned long long u64; +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; +typedef uint64_t u64; -typedef signed char s8; -typedef signed short s16; -typedef signed int s32; -typedef signed long long s64; +typedef int8_t s8; +typedef int16_t s16; +typedef int32_t s32; +typedef int64_t s64; enum flags { diff --git a/ctrtool/utils.c b/ctrtool/utils.c index a7f2897..c043586 100644 --- a/ctrtool/utils.c +++ b/ctrtool/utils.c @@ -1,13 +1,13 @@ #include #include +#include +#include #include "utils.h" #ifdef _WIN32 #include -#else -#include -#include +#include #endif @@ -20,7 +20,7 @@ u32 align(u32 offset, u32 alignment) u64 align64(u64 offset, u32 alignment) { - u64 mask = ~(alignment-1); + u64 mask = ~(u64)(alignment-1); return (offset + (alignment-1)) & mask; } @@ -91,19 +91,15 @@ void putle32(u8* p, u32 n) void readkeyfile(u8* key, const char* keyfname) { + u32 keysize = _fsize(keyfname); FILE* f = fopen(keyfname, "rb"); - u32 keysize = 0; - + if (0 == f) { fprintf(stdout, "Error opening key file\n"); goto clean; } - fseek(f, 0, SEEK_END); - keysize = ftell(f); - fseek(f, 0, SEEK_SET); - if (keysize != 16) { fprintf(stdout, "Error key size mismatch, got %d, expected %d\n", keysize, 16); @@ -190,3 +186,20 @@ int makedir(const char* dir) return mkdir(dir, 0777); #endif } + +u64 _fsize(const char *filename) +{ +#ifdef _WIN32 + struct _stat64 st; + if (_stat64(filename, &st) != 0) + return 0; + else + return st.st_size; +#else + struct stat st; + if (stat(filename, &st) != 0) + return 0; + else + return st.st_size; +#endif +} diff --git a/ctrtool/utils.h b/ctrtool/utils.h index 31a06fb..519a95e 100644 --- a/ctrtool/utils.h +++ b/ctrtool/utils.h @@ -35,6 +35,12 @@ int key_load(char *name, u8 *out_buf); int makedir(const char* dir); +u64 _fsize(const char *filename); + +#ifndef _WIN32 +extern int fseeko64 (FILE *__stream, __off64_t __off, int __whence); +#endif + #ifdef __cplusplus } #endif