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);
bool src_emunand = ((*path_tmd == 'B') || (*path_tmd == '4'));
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));
return 1;
}
} else {
if ((SearchTitleKeysBin(ticket, title_id) != 0) &&
(GetTicket(ticket, title_id, false, src_emunand) == 0) &&
if ((FindTitleKey(ticket, title_id) != 0) &&
(FindTicket(ticket, title_id, false, src_emunand) == 0) &&
(getbe32(ticket->console_id) || getbe32(ticket->eshop_id))) {
// if ticket found: wipe private data
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;
// optional stuff (proper titlekey / meta data)
SearchTitleKeysBin((&cia->ticket), title_id);
FindTitleKey((&cia->ticket), title_id);
if (exthdr && (BuildCiaMeta(meta, exthdr, NULL) == 0) &&
(LoadExeFsFile(meta->smdh, path_ncch, 0, "icon", sizeof(meta->smdh)) == 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)
SearchTitleKeysBin(&(cia->ticket), title_id);
FindTitleKey(&(cia->ticket), title_id);
if ((BuildCiaMeta(meta, exthdr, NULL) == 0) &&
(LoadExeFsFile(meta->smdh, path_ncsd, NCSD_CNT0_OFFSET, "icon", sizeof(meta->smdh)) == 0) &&
(InsertCiaMeta(path_cia, meta) == 0))

View File

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

View File

@ -11,9 +11,17 @@
#define TIKDB_NAME_ENC "encTitleKeys.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_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
typedef struct {
u8 sig_type[4];
@ -47,6 +55,6 @@ typedef struct {
u32 ValidateTicket(Ticket* ticket);
u32 GetTitleKey(u8* titlekey, Ticket* ticket);
u32 GetTicket(Ticket* ticket, u8* title_id, bool force_legit, bool emunand);
u32 SearchTitleKeysBin(Ticket* ticket, u8* title_id);
u32 FindTicket(Ticket* ticket, u8* title_id, bool force_legit, bool emunand);
u32 FindTitleKey(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) &&
(strncmp(clipboard->entry[0].path, curr_entry->path, 256) != 0)) ?
(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] =
(filetype == IMG_NAND ) ? "Mount as NAND image" :
(filetype == IMG_FAT ) ? "Mount as FAT image" :