forked from Mirror/GodMode9
Allow .code extraction for .3ds files
This commit is contained in:
parent
1a9bf41c9d
commit
2e07189a1b
@ -55,7 +55,7 @@
|
|||||||
#define FTYPE_RENAMABLE(tp) (tp&(GAME_NCCH|GAME_NCSD|GAME_CIA|GAME_NDS|GAME_GBA))
|
#define FTYPE_RENAMABLE(tp) (tp&(GAME_NCCH|GAME_NCSD|GAME_CIA|GAME_NDS|GAME_GBA))
|
||||||
#define FTYPE_TRANSFERABLE(tp) ((u64) (tp&(IMG_FAT|FLAG_CTR)) == (u64) (IMG_FAT|FLAG_CTR))
|
#define FTYPE_TRANSFERABLE(tp) ((u64) (tp&(IMG_FAT|FLAG_CTR)) == (u64) (IMG_FAT|FLAG_CTR))
|
||||||
#define FTYPE_NCSDFIXABLE(tp) (tp&(HDR_NAND|NOIMG_NAND))
|
#define FTYPE_NCSDFIXABLE(tp) (tp&(HDR_NAND|NOIMG_NAND))
|
||||||
#define FTYPE_HASCODE(tp) ((u64) (tp&(GAME_NCCH|FLAG_CXI)) == (u64) (GAME_NCCH|FLAG_CXI))
|
#define FTYPE_HASCODE(tp) (((u64) (tp&(GAME_NCCH|FLAG_CXI)) == (u64) (GAME_NCCH|FLAG_CXI))|(tp&GAME_NCSD))
|
||||||
#define FTYPE_ISDISADIFF(tp) (tp&(SYS_DIFF|SYS_DISA))
|
#define FTYPE_ISDISADIFF(tp) (tp&(SYS_DIFF|SYS_DISA))
|
||||||
#define FTYPE_RESTORABLE(tp) (tp&(IMG_NAND))
|
#define FTYPE_RESTORABLE(tp) (tp&(IMG_NAND))
|
||||||
#define FTYPE_EBACKUP(tp) (tp&(IMG_NAND))
|
#define FTYPE_EBACKUP(tp) (tp&(IMG_NAND))
|
||||||
|
@ -1498,16 +1498,26 @@ u32 DumpCxiSrlFromTmdFile(const char* path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
u32 ExtractCodeFromCxiFile(const char* path, const char* path_out, char* extstr) {
|
u32 ExtractCodeFromCxiFile(const char* path, const char* path_out, char* extstr) {
|
||||||
|
u64 filetype = IdentifyFileType(path);
|
||||||
char dest[256];
|
char dest[256];
|
||||||
if (!path_out && (fvx_rmkdir(OUTPUT_PATH) != FR_OK)) return 1;
|
if (!path_out && (fvx_rmkdir(OUTPUT_PATH) != FR_OK)) return 1;
|
||||||
strncpy(dest, path_out ? path_out : OUTPUT_PATH, 256);
|
strncpy(dest, path_out ? path_out : OUTPUT_PATH, 256);
|
||||||
if (!CheckWritePermissions(dest)) return 1;
|
if (!CheckWritePermissions(dest)) return 1;
|
||||||
|
|
||||||
|
// NCSD handling
|
||||||
|
u32 ncch_offset = 0;
|
||||||
|
if (filetype & GAME_NCSD) {
|
||||||
|
NcsdHeader ncsd;
|
||||||
|
if (LoadNcsdHeader(&ncsd, path) == 0)
|
||||||
|
ncch_offset = ncsd.partitions[0].offset * NCSD_MEDIA_UNIT;
|
||||||
|
else return 1;
|
||||||
|
}
|
||||||
|
|
||||||
// load all required headers
|
// load all required headers
|
||||||
NcchHeader ncch;
|
NcchHeader ncch;
|
||||||
NcchExtHeader exthdr;
|
NcchExtHeader exthdr;
|
||||||
ExeFsHeader exefs;
|
ExeFsHeader exefs;
|
||||||
if (LoadNcchHeaders(&ncch, &exthdr, &exefs, path, 0) != 0) return 1;
|
if (LoadNcchHeaders(&ncch, &exthdr, &exefs, path, ncch_offset) != 0) return 1;
|
||||||
|
|
||||||
// find ".code" or ".firm" inside the ExeFS header
|
// find ".code" or ".firm" inside the ExeFS header
|
||||||
u32 code_size = 0;
|
u32 code_size = 0;
|
||||||
@ -1526,7 +1536,7 @@ u32 ExtractCodeFromCxiFile(const char* path, const char* path_out, char* extstr)
|
|||||||
if (exthdr.flag & 0x1) {
|
if (exthdr.flag & 0x1) {
|
||||||
u8 footer[8];
|
u8 footer[8];
|
||||||
if (code_size < 8) return 1;
|
if (code_size < 8) return 1;
|
||||||
if ((fvx_qread(path, footer, code_offset + code_size - 8, 8, NULL) != FR_OK) ||
|
if ((fvx_qread(path, footer, ncch_offset + code_offset + code_size - 8, 8, NULL) != FR_OK) ||
|
||||||
(DecryptNcch(footer, code_offset + code_size - 8, 8, &ncch, &exefs) != 0))
|
(DecryptNcch(footer, code_offset + code_size - 8, 8, &ncch, &exefs) != 0))
|
||||||
return 1;
|
return 1;
|
||||||
u32 unc_size = GetCodeLzssUncompressedSize(footer, code_size);
|
u32 unc_size = GetCodeLzssUncompressedSize(footer, code_size);
|
||||||
@ -1541,7 +1551,7 @@ u32 ExtractCodeFromCxiFile(const char* path, const char* path_out, char* extstr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// load .code
|
// load .code
|
||||||
if ((fvx_qread(path, code, code_offset, code_size, NULL) != FR_OK) ||
|
if ((fvx_qread(path, code, ncch_offset + code_offset, code_size, NULL) != FR_OK) ||
|
||||||
(DecryptNcch(code, code_offset, code_size, &ncch, &exefs) != 0)) {
|
(DecryptNcch(code, code_offset, code_size, &ncch, &exefs) != 0)) {
|
||||||
free(code);
|
free(code);
|
||||||
return 1;
|
return 1;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user