mirror of
https://github.com/DarkStore-3DS/Project_CTR.git
synced 2026-07-05 16:59:02 +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;
|
u32 sectsize;
|
||||||
|
|
||||||
fprintf(stdout, "\nExeFS:\n");
|
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);
|
exefs_sectionheader* section = (exefs_sectionheader*)(ctx->header.section + i);
|
||||||
|
|
||||||
|
|||||||
+4
-3
@@ -7,6 +7,7 @@
|
|||||||
#include "filepath.h"
|
#include "filepath.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
|
|
||||||
|
#define EXEFS_SECTION_NUM 8
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@@ -18,9 +19,9 @@ typedef struct
|
|||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
exefs_sectionheader section[8];
|
exefs_sectionheader section[EXEFS_SECTION_NUM];
|
||||||
u8 reserved[0x80];
|
u8 reserved[0x80];
|
||||||
u8 hashes[8][0x20];
|
u8 hashes[EXEFS_SECTION_NUM][0x20];
|
||||||
} exefs_header;
|
} exefs_header;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
@@ -35,7 +36,7 @@ typedef struct
|
|||||||
exefs_header header;
|
exefs_header header;
|
||||||
ctr_aes_context aes;
|
ctr_aes_context aes;
|
||||||
ctr_sha256_context sha;
|
ctr_sha256_context sha;
|
||||||
int hashcheck[8];
|
int hashcheck[EXEFS_SECTION_NUM];
|
||||||
int compressedflag;
|
int compressedflag;
|
||||||
int encrypted;
|
int encrypted;
|
||||||
} exefs_context;
|
} exefs_context;
|
||||||
|
|||||||
+91
-6
@@ -182,6 +182,7 @@ void ncch_save(ncch_context* ctx, u32 type, u32 flags)
|
|||||||
FILE* fout = 0;
|
FILE* fout = 0;
|
||||||
filepath* path = 0;
|
filepath* path = 0;
|
||||||
u8 buffer[16*1024];
|
u8 buffer[16*1024];
|
||||||
|
exefs_header exefs_hdr;
|
||||||
|
|
||||||
|
|
||||||
if (0 == ncch_extract_prepare(ctx, type, flags))
|
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;
|
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;
|
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;
|
goto clean;
|
||||||
|
|
||||||
if (read_len == 0)
|
if (read_len != fwrite(&exefs_hdr, 1, read_len, fout))
|
||||||
break;
|
|
||||||
|
|
||||||
if (read_len != fwrite(buffer, 1, read_len, fout))
|
|
||||||
{
|
{
|
||||||
fprintf(stdout, "Error writing output file\n");
|
fprintf(stdout, "Error writing output file\n");
|
||||||
goto clean;
|
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:
|
clean:
|
||||||
if (fout)
|
if (fout)
|
||||||
fclose(fout);
|
fclose(fout);
|
||||||
|
|||||||
Reference in New Issue
Block a user