mirror of
https://github.com/DarkStore-3DS/Project_CTR.git
synced 2026-07-03 00:39:14 +00:00
[ctrtool] Fixes issue #60
This commit is contained in:
+1
-1
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user