From 145bf6de547b23786f5af00e77d599aab07b2cee Mon Sep 17 00:00:00 2001 From: d0k3 Date: Wed, 28 Oct 2020 00:00:18 +0100 Subject: [PATCH] Improve ticket searching functions This is applies to encTitlekeys.db / decTitlekeys.bin builders as well as to to legit CIA building --- arm9/source/game/bdri.c | 1 + arm9/source/game/ticketdb.c | 66 ++++++++++-------------------------- arm9/source/utils/gameutil.c | 59 ++++++++++++-------------------- 3 files changed, 41 insertions(+), 85 deletions(-) diff --git a/arm9/source/game/bdri.c b/arm9/source/game/bdri.c index 0002d24..f945704 100644 --- a/arm9/source/game/bdri.c +++ b/arm9/source/game/bdri.c @@ -737,6 +737,7 @@ u32 ReadTicketFromDB(const char* path, const u8* title_id, Ticket** ticket) { TicketEntry* te = NULL; u32 entry_size; + *ticket = NULL; if (fvx_open(&file, path, FA_READ | FA_OPEN_EXISTING) != FR_OK) return 1; diff --git a/arm9/source/game/ticketdb.c b/arm9/source/game/ticketdb.c index 8160652..743a635 100644 --- a/arm9/source/game/ticketdb.c +++ b/arm9/source/game/ticketdb.c @@ -1,17 +1,11 @@ #include "ticketdb.h" -#include "vbdri.h" +#include "bdri.h" #include "support.h" #include "aes.h" -#include "vff.h" #include "fsinit.h" #include "image.h" -const char* virtual_tickdb_dirs[] = { - "homebrew", - "eshop", - "system", - "unknown", -}; +#define PART_PATH "D:/partitionA.bin" u32 CryptTitleKey(TitleKeyEntry* tik, bool encrypt, bool devkit) { // From https://github.com/profi200/Project_CTR/blob/master/makerom/pki/prod.h#L19 @@ -65,55 +59,31 @@ u32 FindTicket(Ticket** ticket, u8* title_id, bool force_legit, bool emunand) { char path_store[256] = { 0 }; char* path_bak = NULL; + // just to be safe + *ticket = NULL; + + // store previous mount path strncpy(path_store, GetMountPath(), 256); if (*path_store) path_bak = path_store; if (!InitImgFS(path_db)) return 1; - char tid_string[17]; - u64 tid = getbe64(title_id); - snprintf(tid_string, 17, "%016llX", tid); + // search ticket in database + if (ReadTicketFromDB(PART_PATH, title_id, ticket) != 0) { + InitImgFS(path_bak); + return 1; + } - DIR dir; - FILINFO fno; - char dir_path[12]; - char tik_path[64]; - - for (u32 i = force_legit ? 1 : 0; i < 4; i++) { - snprintf(dir_path, 12, "T:/%s", virtual_tickdb_dirs[i]); - - if (fvx_opendir(&dir, dir_path) != FR_OK) { - InitImgFS(path_bak); - return 1; - } - - while ((fvx_readdir(&dir, &fno) == FR_OK) && *(fno.fname)) { - if (strncmp(tid_string, fno.fname, 16) == 0) { - snprintf(tik_path, 64, "%s/%s", dir_path, fno.fname); - - u32 size = fvx_qsize(tik_path); - if (!(*ticket = malloc(size))) { - InitImgFS(path_bak); - return 1; - } - - if ((fvx_qread(tik_path, *ticket, 0, size, NULL) != FR_OK) || - (force_legit && (ValidateTicketSignature(*ticket) != 0))) { - free(*ticket); - InitImgFS(path_bak); - return 1; - } - - InitImgFS(path_bak); - return 0; - } - } - - fvx_closedir(&dir); + // (optional) validate ticket signature + if (force_legit && (ValidateTicketSignature(*ticket) != 0)) { + free(*ticket); + *ticket = NULL; + InitImgFS(path_bak); + return 1; } InitImgFS(path_bak); - return 1; + return 0; } u32 FindTitleKey(Ticket* ticket, u8* title_id) { diff --git a/arm9/source/utils/gameutil.c b/arm9/source/utils/gameutil.c index e449d3b..f5e8fc3 100644 --- a/arm9/source/utils/gameutil.c +++ b/arm9/source/utils/gameutil.c @@ -15,6 +15,9 @@ #define CRYPTO_DECRYPT NCCH_NOCRYPTO #define CRYPTO_ENCRYPT NCCH_STDCRYPTO +// partitionA path +#define PART_PATH "D:/partitionA.bin" + u32 GetNcchHeaders(NcchHeader* ncch, NcchExtHeader* exthdr, ExeFsHeader* exefs, FIL* file, bool nocrypto) { u32 offset_ncch = fvx_tell(file); UINT btr; @@ -1455,14 +1458,14 @@ u32 UninstallGameData(u64 tid64, bool remove_tie, bool remove_ticket, bool remov if (remove_ticket) { char path_ticketdb[256]; if ((GetInstallDbsPath(path_ticketdb, drv, "ticket.db") != 0) || !InitImgFS(path_ticketdb) || - ((RemoveTicketFromDB("D:/partitionA.bin", title_id)) != 0)) ret = 1; + ((RemoveTicketFromDB(PART_PATH, title_id)) != 0)) ret = 1; } // title database if (remove_tie) { char path_titledb[256]; if ((GetInstallDbsPath(path_titledb, drv, "title.db") != 0) || !InitImgFS(path_titledb) || - ((RemoveTitleInfoEntryFromDB("D:/partitionA.bin", title_id)) != 0)) ret = 1; + ((RemoveTitleInfoEntryFromDB(PART_PATH, title_id)) != 0)) ret = 1; } // restore old mount path @@ -1676,14 +1679,14 @@ u32 InstallCiaSystemData(CiaStub* cia, const char* drv) { // title database if (!InitImgFS(path_titledb) || - ((AddTitleInfoEntryToDB("D:/partitionA.bin", title_id, &tie, true)) != 0)) { + ((AddTitleInfoEntryToDB(PART_PATH, title_id, &tie, true)) != 0)) { InitImgFS(path_bak); return 1; } // ticket database if (!InitImgFS(path_ticketdb) || - ((AddTicketToDB("D:/partitionA.bin", title_id, (Ticket*) ticket, true)) != 0)) { + ((AddTicketToDB(PART_PATH, title_id, (Ticket*) ticket, true)) != 0)) { InitImgFS(path_bak); return 1; } @@ -3004,45 +3007,27 @@ u32 BuildTitleKeyInfo(const char* path, bool dec, bool dump) { return 1; } } else if (filetype & SYS_TICKDB) { - if (!InitImgFS(path_in)) - return 1; + u32 num_entries = GetNumTickets(PART_PATH); + if (!num_entries) return 1; + u8* title_ids = (u8*) malloc(num_entries * 8); + if (!title_ids) return 1; - DIR dir; - FILINFO fno; - TicketCommon ticket; - char tik_path[64]; - - if (fvx_opendir(&dir, "T:/eshop") != FR_OK) { + if (!InitImgFS(path_in) || (ListTicketTitleIDs(PART_PATH, title_ids, num_entries) != 0)) { + free(title_ids); InitImgFS(NULL); return 1; } - while ((fvx_readdir(&dir, &fno) == FR_OK) && *(fno.fname)) { - snprintf(tik_path, 64, "T:/eshop/%s", fno.fname); - if (fvx_qread(tik_path, &ticket, 0, TICKET_COMMON_SIZE, NULL) != FR_OK) - continue; - if (TIKDB_SIZE(tik_info) + 32 > STD_BUFFER_SIZE) break; // no error message - AddTicketToInfo(tik_info, (Ticket*) &ticket, dec); // ignore result + // read and validate all tickets, add validated to info + for (u32 i = 0; i < num_entries; i++) { + Ticket* ticket; + if (ReadTicketFromDB(PART_PATH, title_ids + (i * 8), &ticket) != 0) continue; + if (ValidateTicketSignature(ticket) == 0) + AddTicketToInfo(tik_info, ticket, dec); // ignore result + free(ticket); } - - fvx_closedir(&dir); - - if (fvx_opendir(&dir, "T:/system") != FR_OK) { - InitImgFS(NULL); - return 1; - } - - while ((fvx_readdir(&dir, &fno) == FR_OK) && *(fno.fname)) { - snprintf(tik_path, 64, "T:/system/%s", fno.fname); - if ((fvx_qread(tik_path, &ticket, 0, TICKET_COMMON_SIZE, NULL) != FR_OK) || - (ValidateTicketSignature((Ticket*) &ticket) != 0)) - continue; - if (TIKDB_SIZE(tik_info) + 32 > STD_BUFFER_SIZE) break; // no error message - AddTicketToInfo(tik_info, (Ticket*) &ticket, dec); // ignore result - } - - fvx_closedir(&dir); - + + free(title_ids); InitImgFS(NULL); } else if (filetype & BIN_TIKDB) { TitleKeysInfo* tik_info_merge = (TitleKeysInfo*) malloc(STD_BUFFER_SIZE);