mirror of
https://github.com/d0k3/GodMode9.git
synced 2025-06-26 21:52:48 +00:00
remove remaining uses of brute-force ticket.db parsing
This commit is contained in:
parent
127008a274
commit
8ffe774f77
@ -1,9 +1,16 @@
|
|||||||
#include "ticketdb.h"
|
#include "ticketdb.h"
|
||||||
#include "disadiff.h"
|
#include "vbdri.h"
|
||||||
#include "support.h"
|
#include "support.h"
|
||||||
#include "aes.h"
|
#include "aes.h"
|
||||||
#include "ff.h"
|
#include "vff.h"
|
||||||
|
#include "fsinit.h"
|
||||||
|
|
||||||
|
const char* virtual_tickdb_dirs[] = {
|
||||||
|
"homebrew",
|
||||||
|
"eshop",
|
||||||
|
"system",
|
||||||
|
"unknown",
|
||||||
|
};
|
||||||
|
|
||||||
u32 CryptTitleKey(TitleKeyEntry* tik, bool encrypt, bool devkit) {
|
u32 CryptTitleKey(TitleKeyEntry* tik, bool encrypt, bool devkit) {
|
||||||
// From https://github.com/profi200/Project_CTR/blob/master/makerom/pki/prod.h#L19
|
// From https://github.com/profi200/Project_CTR/blob/master/makerom/pki/prod.h#L19
|
||||||
@ -52,43 +59,56 @@ u32 GetTitleKey(u8* titlekey, Ticket* ticket) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ticket* TicketFromTickDbChunk(u8* chunk, u8* title_id, bool legit_pls) {
|
|
||||||
// chunk must be aligned to 0x200 byte in file and at least 0x400 byte big
|
|
||||||
Ticket* tick = (Ticket*) (void*) (chunk + 0x18);
|
|
||||||
if ((getle32(chunk + 0x10) == 0) || (getle32(chunk + 0x14) != GetTicketSize(tick))) return NULL;
|
|
||||||
if (ValidateTicket(tick) != 0) return NULL; // ticket not validated
|
|
||||||
if (title_id && (memcmp(title_id, tick->title_id, 8) != 0)) return NULL; // title id not matching
|
|
||||||
if (legit_pls && (ValidateTicketSignature(tick) != 0)) return NULL; // legit check using RSA sig
|
|
||||||
|
|
||||||
return tick;
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 FindTicket(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 char* path_db = TICKDB_PATH(emunand); // EmuNAND / SysNAND
|
||||||
u8* data = (u8*) malloc(TICKDB_AREA_SIZE);
|
|
||||||
if (!data) return 1;
|
|
||||||
|
|
||||||
// read and decode ticket.db DIFF partition
|
if (!InitImgFS(path_db))
|
||||||
if (ReadDisaDiffIvfcLvl4(path_db, NULL, TICKDB_AREA_OFFSET, TICKDB_AREA_SIZE, data) != TICKDB_AREA_SIZE) {
|
|
||||||
free(data);
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
char tid_string[17];
|
||||||
|
u64 tid = getbe64(title_id);
|
||||||
|
snprintf(tid_string, 17, "%016llX", tid);
|
||||||
|
|
||||||
|
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(NULL);
|
||||||
|
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(NULL);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((fvx_qread(tik_path, *ticket, 0, size, NULL) != FR_OK) ||
|
||||||
|
(force_legit && (ValidateTicketSignature(*ticket) != 0))) {
|
||||||
|
free(*ticket);
|
||||||
|
InitImgFS(NULL);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
InitImgFS(NULL);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fvx_closedir(&dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse the decoded data for a ticket
|
InitImgFS(NULL);
|
||||||
bool found = false;
|
return 1;
|
||||||
for (u32 i = 0; !found && (i <= TICKDB_AREA_SIZE - 0x400); i += 0x200) {
|
|
||||||
Ticket* tick = TicketFromTickDbChunk(data + i, title_id, force_legit);
|
|
||||||
if (!tick) continue;
|
|
||||||
u32 size = GetTicketSize(tick);
|
|
||||||
Ticket* newtick = (Ticket*)malloc(size);
|
|
||||||
if (!newtick) break;
|
|
||||||
memcpy(newtick, tick, size);
|
|
||||||
*ticket = newtick;
|
|
||||||
found = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(data);
|
|
||||||
return (found) ? 0 : 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 FindTitleKey(Ticket* ticket, u8* title_id) {
|
u32 FindTitleKey(Ticket* ticket, u8* title_id) {
|
||||||
|
@ -35,7 +35,6 @@ typedef struct {
|
|||||||
|
|
||||||
|
|
||||||
u32 GetTitleKey(u8* titlekey, Ticket* ticket);
|
u32 GetTitleKey(u8* titlekey, Ticket* ticket);
|
||||||
Ticket* TicketFromTickDbChunk(u8* chunk, u8* title_id, bool legit_pls);
|
|
||||||
u32 FindTicket(Ticket** ticket, u8* title_id, bool force_legit, bool emunand);
|
u32 FindTicket(Ticket** ticket, u8* title_id, bool force_legit, bool emunand);
|
||||||
u32 FindTitleKey(Ticket* ticket, u8* title_id);
|
u32 FindTitleKey(Ticket* ticket, u8* title_id);
|
||||||
u32 AddTitleKeyToInfo(TitleKeysInfo* tik_info, TitleKeyEntry* tik_entry, bool decrypted_in, bool decrypted_out, bool devkit);
|
u32 AddTitleKeyToInfo(TitleKeysInfo* tik_info, TitleKeyEntry* tik_entry, bool decrypted_in, bool decrypted_out, bool devkit);
|
||||||
|
@ -2351,24 +2351,46 @@ u32 BuildTitleKeyInfo(const char* path, bool dec, bool dump) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
} else if (filetype & SYS_TICKDB) {
|
} else if (filetype & SYS_TICKDB) {
|
||||||
u8* data = (u8*) malloc(TICKDB_AREA_SIZE);
|
if (!InitImgFS(path_in))
|
||||||
if (!data) return 1;
|
return 1;
|
||||||
|
|
||||||
// read and decode ticket.db DIFF partition
|
DIR dir;
|
||||||
if (ReadDisaDiffIvfcLvl4(path_in, NULL, TICKDB_AREA_OFFSET, TICKDB_AREA_SIZE, data) != TICKDB_AREA_SIZE) {
|
FILINFO fno;
|
||||||
free(data);
|
TicketCommon ticket;
|
||||||
|
char tik_path[64];
|
||||||
|
|
||||||
|
if (fvx_opendir(&dir, "T:/eshop") != FR_OK) {
|
||||||
|
InitImgFS(NULL);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse the decoded data for valid tickets
|
while ((fvx_readdir(&dir, &fno) == FR_OK) && *(fno.fname)) {
|
||||||
for (u32 i = 0; i <= TICKDB_AREA_SIZE - 0x400; i += 0x200) {
|
snprintf(tik_path, 64, "T:/eshop/%s", fno.fname);
|
||||||
Ticket* ticket = TicketFromTickDbChunk(data + i, NULL, true);
|
if (fvx_qread(tik_path, &ticket, 0, TICKET_COMMON_SIZE, NULL) != FR_OK)
|
||||||
if (!ticket || (ticket->commonkey_idx >= 2) || !getbe64(ticket->ticket_id)) continue;
|
continue;
|
||||||
if (TIKDB_SIZE(tik_info) + 32 > STD_BUFFER_SIZE) break; // no error message
|
if (TIKDB_SIZE(tik_info) + 32 > STD_BUFFER_SIZE) break; // no error message
|
||||||
AddTicketToInfo(tik_info, ticket, dec); // ignore result
|
AddTicketToInfo(tik_info, (Ticket*) &ticket, dec); // ignore result
|
||||||
}
|
}
|
||||||
|
|
||||||
free(data);
|
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);
|
||||||
|
|
||||||
|
InitImgFS(NULL);
|
||||||
} else if (filetype & BIN_TIKDB) {
|
} else if (filetype & BIN_TIKDB) {
|
||||||
TitleKeysInfo* tik_info_merge = (TitleKeysInfo*) malloc(STD_BUFFER_SIZE);
|
TitleKeysInfo* tik_info_merge = (TitleKeysInfo*) malloc(STD_BUFFER_SIZE);
|
||||||
if (!tik_info_merge) return 1;
|
if (!tik_info_merge) return 1;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user