mirror of
https://github.com/d0k3/GodMode9.git
synced 2025-06-26 13:42:47 +00:00
Improved naming routines for building CIAs and de/encryption
This commit is contained in:
parent
41a25cee16
commit
e510ac76c4
@ -13,46 +13,26 @@
|
|||||||
#define CRYPTO_DECRYPT NCCH_NOCRYPTO
|
#define CRYPTO_DECRYPT NCCH_NOCRYPTO
|
||||||
#define CRYPTO_ENCRYPT NCCH_STDCRYPTO
|
#define CRYPTO_ENCRYPT NCCH_STDCRYPTO
|
||||||
|
|
||||||
u32 GetOutputPath(char* dest, const char* path, const char* ext) {
|
u64 GetTitleId(const char* path) {
|
||||||
// special handling for input from title directories (somewhat hacky)
|
u32 filetype = IdentifyFileType(path);
|
||||||
if (strncmp(path + 1, ":/title/", 8) == 0) {
|
UINT br;
|
||||||
u32 tid_high, tid_low, app_id;
|
if (filetype & GAME_TMD) {
|
||||||
char drv;
|
TitleMetaData* tmd = (TitleMetaData*) (void*) TEMP_BUFFER;
|
||||||
if (((sscanf(path, "%c:/title/%08lx/%08lx/content/%08lx", &drv, &tid_high, &tid_low, &app_id) == 4) &&
|
|
||||||
(strnlen(path, 256) == (1+1+1) + (5+1) + (8+1) + (8+1) + (7+1) + (8+1+3))) ||
|
|
||||||
((sscanf(path, "%c:/title/%08lx/%08lx/content/00000000/%08lx", &drv, &tid_high, &tid_low, &app_id) == 4) &&
|
|
||||||
(strnlen(path, 256) == (1+1+1) + (5+1) + (8+1) + (8+1) + (7+1) + (8+1) + (8+1+3)))) { // confused? ^_^
|
|
||||||
if (!ext) snprintf(dest, 256, "%s/%08lx%08lx.%08lx.app", OUTPUT_PATH, tid_high, tid_low, app_id);
|
|
||||||
else snprintf(dest, 256, "%s/%08lx%08lx.%s", OUTPUT_PATH, tid_high, tid_low, ext);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// tmd file handling (outside of title dirs, still hacky)
|
|
||||||
if (ext && (strnlen(path, 256) >= 3) && (strncasecmp(path + strnlen(path, 256) - 3, "tmd", 3)) == 0) {
|
|
||||||
// minimum size TMD
|
|
||||||
const u8 magic[] = { TMD_SIG_TYPE };
|
|
||||||
TitleMetaData* tmd = (TitleMetaData*) TEMP_BUFFER;
|
|
||||||
UINT br;
|
|
||||||
if ((fvx_qread(path, tmd, 0, TMD_SIZE_MIN, &br) == FR_OK) &&
|
if ((fvx_qread(path, tmd, 0, TMD_SIZE_MIN, &br) == FR_OK) &&
|
||||||
(memcmp(tmd->sig_type, magic, sizeof(magic)) == 0) &&
|
(br == TMD_SIZE_MIN)) return getbe64(tmd->title_id);
|
||||||
(br == TMD_SIZE_MIN)) {
|
} else if (filetype & GAME_NCCH) {
|
||||||
snprintf(dest, 256, "%s/%016llx.%s", OUTPUT_PATH, getbe64(tmd->title_id), ext);
|
NcchHeader* ncch = (NcchHeader*) (void*) TEMP_BUFFER;
|
||||||
return 0;
|
if ((fvx_qread(path, ncch, 0, sizeof(NcchHeader), &br) == FR_OK) &&
|
||||||
}
|
(br == sizeof(NcchHeader))) return ncch->programId;
|
||||||
}
|
} else if (filetype & GAME_NCSD) {
|
||||||
|
NcsdHeader* ncsd = (NcsdHeader*) (void*) TEMP_BUFFER;
|
||||||
// handling for everything else
|
if ((fvx_qread(path, ncsd, 0, sizeof(NcsdHeader), &br) == FR_OK) &&
|
||||||
char* name = strrchr(path, '/');
|
(br == sizeof(NcsdHeader))) return ncsd->mediaId;
|
||||||
if (!name) return 1;
|
} else if (filetype & GAME_NDS) {
|
||||||
snprintf(dest, 256, "%s/%s", OUTPUT_PATH, ++name);
|
TwlHeader* twl = (TwlHeader*) (void*) TEMP_BUFFER;
|
||||||
if (ext) { // replace extension
|
if ((fvx_qread(path, twl, 0, sizeof(TwlHeader), &br) == FR_OK) &&
|
||||||
char* dot = strrchr(dest, '.');
|
(br == sizeof(TwlHeader))) return twl->title_id;
|
||||||
if (!dot || ((dot - dest) <= (int) strnlen(OUTPUT_PATH, 256) + 1))
|
} // ignored: CIA, ticket
|
||||||
dot = dest + strnlen(dest, 256);
|
|
||||||
snprintf(dot, 16, ".%s", ext);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -998,8 +978,12 @@ u32 CryptGameFile(const char* path, bool inplace, bool encrypt) {
|
|||||||
char* destptr = (char*) path;
|
char* destptr = (char*) path;
|
||||||
u32 ret = 0;
|
u32 ret = 0;
|
||||||
|
|
||||||
if (!inplace) {
|
if (!inplace) { // build output name
|
||||||
if (GetOutputPath(dest, path, NULL) != 0) return 1;
|
char* name = strrchr(path, '/');
|
||||||
|
if (!name) return 1;
|
||||||
|
if ((strncmp(path + 1, ":/title/", 8) == 0) && (filetype & (GAME_NCCH))) {
|
||||||
|
snprintf(dest, 256, "%s/%016llx.%s", OUTPUT_PATH, GetTitleId(path), ++name);
|
||||||
|
} else snprintf(dest, 256, "%s/%s", OUTPUT_PATH, ++name);
|
||||||
destptr = dest;
|
destptr = dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1351,8 +1335,20 @@ u32 BuildCiaFromGameFile(const char* path, bool force_legit) {
|
|||||||
char dest[256];
|
char dest[256];
|
||||||
u32 ret = 0;
|
u32 ret = 0;
|
||||||
|
|
||||||
// destination path
|
// build output name
|
||||||
if (GetOutputPath(dest, path, force_legit ? "legit.cia" : "cia") != 0) return 1;
|
char* name = strrchr(path, '/');
|
||||||
|
if (!name) return 1;
|
||||||
|
if (filetype & GAME_TMD) {
|
||||||
|
snprintf(dest, 256, "%s/%016llx", OUTPUT_PATH, GetTitleId(path));
|
||||||
|
} else if ((strncmp(path + 1, ":/title/", 8) == 0) && (filetype & (GAME_NCCH))) {
|
||||||
|
snprintf(dest, 256, "%s/%016llx.%s", OUTPUT_PATH, GetTitleId(path), ++name);
|
||||||
|
} else snprintf(dest, 256, "%s/%s", OUTPUT_PATH, ++name);
|
||||||
|
// replace extension
|
||||||
|
char* dot = strrchr(dest, '.');
|
||||||
|
if (!dot || (dot < strrchr(dest, '/')))
|
||||||
|
dot = dest + strnlen(dest, 256);
|
||||||
|
snprintf(dot, 16, ".%s", force_legit ? "legit.cia" : "cia");
|
||||||
|
|
||||||
if (!CheckWritePermissions(dest)) return 1;
|
if (!CheckWritePermissions(dest)) return 1;
|
||||||
f_unlink(dest); // remove the file if it already exists
|
f_unlink(dest); // remove the file if it already exists
|
||||||
|
|
||||||
|
@ -12,3 +12,4 @@ u32 CheckHealthAndSafetyInject(const char* hsdrv);
|
|||||||
u32 InjectHealthAndSafety(const char* path, const char* destdrv);
|
u32 InjectHealthAndSafety(const char* path, const char* destdrv);
|
||||||
u32 BuildTitleKeyInfo(const char* path, bool dec, bool dump);
|
u32 BuildTitleKeyInfo(const char* path, bool dec, bool dump);
|
||||||
u32 BuildSeedInfo(const char* path, bool dump);
|
u32 BuildSeedInfo(const char* path, bool dump);
|
||||||
|
u64 GetTitleId(const char* path);
|
||||||
|
@ -899,7 +899,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, DirStruct* cur
|
|||||||
else if ((filetype & BIN_KEYDB) && (CryptAesKeyDb(path, inplace, false) == 0)) n_success++;
|
else if ((filetype & BIN_KEYDB) && (CryptAesKeyDb(path, inplace, false) == 0)) n_success++;
|
||||||
else { // on failure: set cursor on failed title, break;
|
else { // on failure: set cursor on failed title, break;
|
||||||
TruncateString(pathstr, path, 32, 8);
|
TruncateString(pathstr, path, 32, 8);
|
||||||
ShowPrompt(false, "%s\nDecryption failed%s", pathstr, (filetype & (GAME_NCCH|GAME_NCSD|GAME_CIA)) ? "\n\nHint: Did you provide\n" KEYDB_NAME " & " SEEDDB_NAME"?" : "");
|
ShowPrompt(false, "%s\nDecryption failed%s", pathstr, (filetype & (GAME_NCCH|GAME_NCSD|GAME_CIA)) ? "\n \nHint: Did you provide\n" KEYDB_NAME " & " SEEDDB_NAME"?" : "");
|
||||||
*cursor = i;
|
*cursor = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -916,7 +916,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, DirStruct* cur
|
|||||||
u32 ret = (filetype & BIN_KEYDB) ? CryptAesKeyDb(curr_entry->path, inplace, false) :
|
u32 ret = (filetype & BIN_KEYDB) ? CryptAesKeyDb(curr_entry->path, inplace, false) :
|
||||||
CryptGameFile(curr_entry->path, inplace, false);
|
CryptGameFile(curr_entry->path, inplace, false);
|
||||||
if (inplace || (ret != 0)) ShowPrompt(false, "%s\nDecryption %s", pathstr, (ret == 0) ? "success" : (filetype & (GAME_NCCH|GAME_NCSD|GAME_CIA)) ?
|
if (inplace || (ret != 0)) ShowPrompt(false, "%s\nDecryption %s", pathstr, (ret == 0) ? "success" : (filetype & (GAME_NCCH|GAME_NCSD|GAME_CIA)) ?
|
||||||
"failed\n\nHint: Did you provide\n" KEYDB_NAME " & " SEEDDB_NAME"?" : "failed");
|
"failed\n \nHint: Did you provide\n" KEYDB_NAME " & " SEEDDB_NAME"?" : "failed");
|
||||||
else ShowPrompt(false, "%s\nDecrypted to %s", pathstr, OUTPUT_PATH);
|
else ShowPrompt(false, "%s\nDecrypted to %s", pathstr, OUTPUT_PATH);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1107,7 +1107,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, DirStruct* cur
|
|||||||
user_select = (n_opt > 1) ? (int) ShowSelectPrompt(n_opt, optionstr, pathstr) : n_opt;
|
user_select = (n_opt > 1) ? (int) ShowSelectPrompt(n_opt, optionstr, pathstr) : n_opt;
|
||||||
if (user_select) {
|
if (user_select) {
|
||||||
ShowPrompt(false, "%s\nH&S inject %s", pathstr,
|
ShowPrompt(false, "%s\nH&S inject %s", pathstr,
|
||||||
(InjectHealthAndSafety(curr_entry->path, destdrv[user_select-1]) == 0) ? "success" : "failed\n\nHint: Did you provide\n" KEYDB_NAME "?");
|
(InjectHealthAndSafety(curr_entry->path, destdrv[user_select-1]) == 0) ? "success" : "failed\n \nHint: Did you provide\n" KEYDB_NAME "?");
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
} else if (user_select == ctrtransfer) { // -> transfer CTRNAND image to SysNAND
|
} else if (user_select == ctrtransfer) { // -> transfer CTRNAND image to SysNAND
|
||||||
|
Loading…
x
Reference in New Issue
Block a user