Fix ticket.db parser

This commit is contained in:
d0k3 2016-12-20 13:10:07 +01:00
parent b98bba9a6f
commit 2a5a738765
4 changed files with 36 additions and 33 deletions

View File

@ -801,13 +801,13 @@ u32 BuildCiaFromTmdFile(const char* path_tmd, const char* path_cia, bool force_l
Ticket* ticket = &(cia->ticket); Ticket* ticket = &(cia->ticket);
bool src_emunand = ((*path_tmd == 'B') || (*path_tmd == '4')); bool src_emunand = ((*path_tmd == 'B') || (*path_tmd == '4'));
if (force_legit) { if (force_legit) {
if (GetTicket(ticket, title_id, true, src_emunand) != 0) { if (FindTicket(ticket, title_id, true, src_emunand) != 0) {
ShowPrompt(false, "ID %016llX\nLegit ticket not found.", getbe64(title_id)); ShowPrompt(false, "ID %016llX\nLegit ticket not found.", getbe64(title_id));
return 1; return 1;
} }
} else { } else {
if ((SearchTitleKeysBin(ticket, title_id) != 0) && if ((FindTitleKey(ticket, title_id) != 0) &&
(GetTicket(ticket, title_id, false, src_emunand) == 0) && (FindTicket(ticket, title_id, false, src_emunand) == 0) &&
(getbe32(ticket->console_id) || getbe32(ticket->eshop_id))) { (getbe32(ticket->console_id) || getbe32(ticket->eshop_id))) {
// if ticket found: wipe private data // if ticket found: wipe private data
memset(ticket->console_id, 0, 4); // zero out console id memset(ticket->console_id, 0, 4); // zero out console id
@ -889,7 +889,7 @@ u32 BuildCiaFromNcchFile(const char* path_ncch, const char* path_cia) {
return 1; return 1;
// optional stuff (proper titlekey / meta data) // optional stuff (proper titlekey / meta data)
SearchTitleKeysBin((&cia->ticket), title_id); FindTitleKey((&cia->ticket), title_id);
if (exthdr && (BuildCiaMeta(meta, exthdr, NULL) == 0) && if (exthdr && (BuildCiaMeta(meta, exthdr, NULL) == 0) &&
(LoadExeFsFile(meta->smdh, path_ncch, 0, "icon", sizeof(meta->smdh)) == 0) && (LoadExeFsFile(meta->smdh, path_ncch, 0, "icon", sizeof(meta->smdh)) == 0) &&
(InsertCiaMeta(path_cia, meta) == 0)) (InsertCiaMeta(path_cia, meta) == 0))
@ -954,7 +954,7 @@ u32 BuildCiaFromNcsdFile(const char* path_ncsd, const char* path_cia) {
} }
// optional stuff (proper titlekey / meta data) // optional stuff (proper titlekey / meta data)
SearchTitleKeysBin(&(cia->ticket), title_id); FindTitleKey(&(cia->ticket), title_id);
if ((BuildCiaMeta(meta, exthdr, NULL) == 0) && if ((BuildCiaMeta(meta, exthdr, NULL) == 0) &&
(LoadExeFsFile(meta->smdh, path_ncsd, NCSD_CNT0_OFFSET, "icon", sizeof(meta->smdh)) == 0) && (LoadExeFsFile(meta->smdh, path_ncsd, NCSD_CNT0_OFFSET, "icon", sizeof(meta->smdh)) == 0) &&
(InsertCiaMeta(path_cia, meta) == 0)) (InsertCiaMeta(path_cia, meta) == 0))

View File

@ -70,43 +70,38 @@ u32 GetTitleKey(u8* titlekey, Ticket* ticket) {
return 0; return 0;
} }
u32 GetTicket(Ticket* ticket, u8* title_id, bool force_legit, bool emunand) { u32 FindTicket(Ticket* ticket, u8* title_id, bool force_legit, bool emunand) {
const char* path_db = TICKDB_PATH(emunand); // EmuNAND / SysNAND
const u32 area_offsets[] = { TICKDB_AREA_OFFSETS }; const u32 area_offsets[] = { TICKDB_AREA_OFFSETS };
const char* path_db = emunand ? "4:/dbs/ticket.db" : "1:/dbs/ticket.db"; // EmuNAND / SysNAND
u8 data[0x400]; u8 data[0x400];
FIL file; FIL file;
UINT btr; UINT btr;
// find active partition / offset // parse file, sector by sector
if (f_open(&file, path_db, FA_READ | FA_OPEN_EXISTING) != FR_OK) if (f_open(&file, path_db, FA_READ | FA_OPEN_EXISTING) != FR_OK)
return 1; return 1;
f_lseek(&file, 0);
if (f_read(&file, data, 0x200, &btr) != FR_OK) {
f_close(&file);
return 1;
}
f_lseek(&file, (getle32(data + 0x130)) ? area_offsets[1] : area_offsets[0]);
// parse file, sector by sector
bool found = false; bool found = false;
for (u32 i = 0; !found && (i < TICKDB_AREA_SIZE); i++) { for (u32 p = 0; p < 2; p++) {
Ticket* tick = (Ticket*) (data + 0x18); u32 area_offset = area_offsets[p];
if (f_read(&file, data, 0x200, &btr) != FR_OK) break; for (u32 i = 0; !found && (i < TICKDB_AREA_SIZE); i += 0x200) {
if ((getle32(data + 0x10) == 0) || (getle32(data + 0x14) != sizeof(Ticket))) continue; Ticket* tick = (Ticket*) (data + 0x18);
if (ValidateTicket(tick) != 0) continue; // partial ticket only f_lseek(&file, area_offset + i);
if (f_read(&file, data + 0x200, 0x200, &btr) != FR_OK) break; i++; // read the remainder of the ticket if ((f_read(&file, data, 0x400, &btr) != FR_OK) || (btr != 0x400)) break;
if (memcmp(title_id, tick->title_id, 8) != 0) continue; // title id not matching if ((getle32(data + 0x10) == 0) || (getle32(data + 0x14) != sizeof(Ticket))) continue;
if (force_legit && (getbe64(tick->ticket_id) == 0)) continue; // legit check if (ValidateTicket(tick) != 0) continue; // ticket not validated
memcpy(ticket, tick, sizeof(Ticket)); if (memcmp(title_id, tick->title_id, 8) != 0) continue; // title id not matching
found = true; if (force_legit && (getbe64(tick->ticket_id) == 0)) continue; // legit check
break; memcpy(ticket, tick, sizeof(Ticket));
found = true;
break;
}
} }
f_close(&file); f_close(&file);
return (found) ? 0 : 1; return (found) ? 0 : 1;
} }
u32 SearchTitleKeysBin(Ticket* ticket, u8* title_id) { u32 FindTitleKey(Ticket* ticket, u8* title_id) {
bool found = false; bool found = false;
// search for a titlekey inside encTitleKeys.bin / decTitleKeys.bin // search for a titlekey inside encTitleKeys.bin / decTitleKeys.bin
// when found, add it to the ticket // when found, add it to the ticket

View File

@ -11,9 +11,17 @@
#define TIKDB_NAME_ENC "encTitleKeys.bin" #define TIKDB_NAME_ENC "encTitleKeys.bin"
#define TIKDB_NAME_DEC "decTitleKeys.bin" #define TIKDB_NAME_DEC "decTitleKeys.bin"
#define TICKDB_AREA_OFFSETS 0x001C0C00, 0x0137F000 #define TICKDB_PATH(emu) ((emu) ? "4:/dbs/ticket.db" : "1:/dbs/ticket.db") // EmuNAND / SysNAND
#define TICKDB_AREA_OFFSETS 0x0137F000, 0x001C0C00 // second partition is more likely to be in use
#define TICKDB_AREA_SIZE 0x00200000 // the actual area size is around 0x0010C600 #define TICKDB_AREA_SIZE 0x00200000 // the actual area size is around 0x0010C600
#define TICKDB_MAGIC 0x44, 0x49, 0x46, 0x46, 0x00, 0x00, 0x03, 0x00, \
0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x30, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x2C, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x00, 0xEE, 0x37, 0x02, 0x00, 0x00, 0x00, 0x00
// from: https://github.com/profi200/Project_CTR/blob/02159e17ee225de3f7c46ca195ff0f9ba3b3d3e4/ctrtool/tik.h#L15-L39 // from: https://github.com/profi200/Project_CTR/blob/02159e17ee225de3f7c46ca195ff0f9ba3b3d3e4/ctrtool/tik.h#L15-L39
typedef struct { typedef struct {
u8 sig_type[4]; u8 sig_type[4];
@ -47,6 +55,6 @@ typedef struct {
u32 ValidateTicket(Ticket* ticket); u32 ValidateTicket(Ticket* ticket);
u32 GetTitleKey(u8* titlekey, Ticket* ticket); u32 GetTitleKey(u8* titlekey, Ticket* ticket);
u32 GetTicket(Ticket* ticket, u8* title_id, bool force_legit, bool emunand); u32 FindTicket(Ticket* ticket, u8* title_id, bool force_legit, bool emunand);
u32 SearchTitleKeysBin(Ticket* ticket, u8* title_id); u32 FindTitleKey(Ticket* ticket, u8* title_id);
u32 BuildFakeTicket(Ticket* ticket, u8* title_id); u32 BuildFakeTicket(Ticket* ticket, u8* title_id);

View File

@ -590,7 +590,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, DirStruct* cur
(drvtype & DRV_FAT) && (drvtype & DRV_FAT) &&
(strncmp(clipboard->entry[0].path, curr_entry->path, 256) != 0)) ? (strncmp(clipboard->entry[0].path, curr_entry->path, 256) != 0)) ?
(int) ++n_opt : -1; (int) ++n_opt : -1;
int searchdrv = (drvtype & DRV_SEARCH) ? ++n_opt : -1; int searchdrv = (DriveType(current_path) & DRV_SEARCH) ? ++n_opt : -1;
if (special > 0) optionstr[special-1] = if (special > 0) optionstr[special-1] =
(filetype == IMG_NAND ) ? "Mount as NAND image" : (filetype == IMG_NAND ) ? "Mount as NAND image" :
(filetype == IMG_FAT ) ? "Mount as FAT image" : (filetype == IMG_FAT ) ? "Mount as FAT image" :