[ctrtool] Fixes issue #60

This commit is contained in:
jakcron
2018-01-12 21:00:53 +08:00
parent bbd9a90d8a
commit acb110323e
3 changed files with 96 additions and 10 deletions
+1 -1
View File
@@ -315,7 +315,7 @@ void exefs_print(exefs_context* ctx)
u32 sectsize;
fprintf(stdout, "\nExeFS:\n");
for(i=0; i<8; i++)
for(i=0; i<EXEFS_SECTION_NUM; i++)
{
exefs_sectionheader* section = (exefs_sectionheader*)(ctx->header.section + i);
+4 -3
View File
@@ -7,6 +7,7 @@
#include "filepath.h"
#include "settings.h"
#define EXEFS_SECTION_NUM 8
typedef struct
{
@@ -18,9 +19,9 @@ typedef struct
typedef struct
{
exefs_sectionheader section[8];
exefs_sectionheader section[EXEFS_SECTION_NUM];
u8 reserved[0x80];
u8 hashes[8][0x20];
u8 hashes[EXEFS_SECTION_NUM][0x20];
} exefs_header;
typedef struct
@@ -35,7 +36,7 @@ typedef struct
exefs_header header;
ctr_aes_context aes;
ctr_sha256_context sha;
int hashcheck[8];
int hashcheck[EXEFS_SECTION_NUM];
int compressedflag;
int encrypted;
} exefs_context;
+91 -6
View File
@@ -182,6 +182,7 @@ void ncch_save(ncch_context* ctx, u32 type, u32 flags)
FILE* fout = 0;
filepath* path = 0;
u8 buffer[16*1024];
exefs_header exefs_hdr;
if (0 == ncch_extract_prepare(ctx, type, flags))
@@ -215,22 +216,106 @@ void ncch_save(ncch_context* ctx, u32 type, u32 flags)
case NCCHTYPE_PLAINRGN: fprintf(stdout, "Saving Plain Region...\n"); break;
}
while(1)
// special crypto considerations for exefs when two keys are used
if (type == NCCHTYPE_EXEFS && ctx->header.flags[3] > 0 && ctx->encrypted)
{
u32 read_len;
if (0 == ncch_extract_buffer(ctx, buffer, sizeof(buffer), &read_len, type == NCCHTYPE_LOGO || type == NCCHTYPE_PLAINRGN))
// read header
if (0 == ncch_extract_buffer(ctx, (u8*)&exefs_hdr, sizeof(exefs_hdr), &read_len, 0))
goto clean;
if (read_len == 0)
break;
if (read_len != fwrite(buffer, 1, read_len, fout))
if (read_len != fwrite(&exefs_hdr, 1, read_len, fout))
{
fprintf(stdout, "Error writing output file\n");
goto clean;
}
for (int i = 0; i < 8; i++)
{
// get section size
u32 section_size = getle32(exefs_hdr.section[i].size);
u32 section_padding = align(section_size, 0x200)-section_size;
// skip empty sections
if (section_size == 0)
continue;
// select correct key
if (strncmp((char*)exefs_hdr.section[i].name, "icon", 8) == 0 || strncmp((char*)exefs_hdr.section[i].name, "banner", 8) == 0)
ctr_init_key(&ctx->aes, ctx->key[0]);
else
ctr_init_key(&ctx->aes, ctx->key[1]);
// set counter
u8 ctr[16];
ncch_get_counter(ctx, ctr, NCCHTYPE_EXEFS);
ctr_init_counter(&ctx->aes, ctr);
ctr_add_counter(&ctx->aes, (getle32(exefs_hdr.section[i].offset) + sizeof(exefs_header)) / 0x10);
// extract data
while (section_size > 0)
{
read_len = sizeof(buffer);
if (read_len > section_size)
read_len = section_size;
if (read_len != fread(buffer, 1, read_len, ctx->file))
{
fprintf(stdout, "Error reading input file\n");
goto clean;
}
ctr_crypt_counter(&ctx->aes, buffer, buffer, read_len);
if (read_len != fwrite(buffer, 1, read_len, fout))
{
fprintf(stdout, "Error writing output file\n");
goto clean;
}
section_size -= read_len;
}
// skip the padding
if (section_padding)
{
fseeko64(ctx->file, section_padding, SEEK_CUR);
memset(buffer, 0, section_padding);
if (section_padding != fwrite(buffer, 1, section_padding, fout))
{
fprintf(stdout, "Error writing output file\n");
goto clean;
}
}
ctx->extractsize -= section_size + section_padding;
}
}
else
{
while (1)
{
u32 read_len;
if (0 == ncch_extract_buffer(ctx, buffer, sizeof(buffer), &read_len, (type == NCCHTYPE_LOGO || type == NCCHTYPE_PLAINRGN)))
goto clean;
if (read_len == 0)
break;
if (read_len != fwrite(buffer, 1, read_len, fout))
{
fprintf(stdout, "Error writing output file\n");
goto clean;
}
}
}
clean:
if (fout)
fclose(fout);