mirror of
https://github.com/rvtr/TDT.git
synced 2025-10-31 13:51:07 -04:00
Add prod and updater (debugger) support
This commit is contained in:
parent
4e84d280f6
commit
de6ccd9f60
@ -365,7 +365,7 @@ bool install(char* tadPath, bool systemTitle)
|
|||||||
|
|
||||||
//start installation
|
//start installation
|
||||||
clearScreen(&bottomScreen);
|
clearScreen(&bottomScreen);
|
||||||
char* fpath = decryptTad(tadPath);
|
char* fpath = openTad(tadPath);
|
||||||
|
|
||||||
tDSiHeader* h = getRomHeader(fpath);
|
tDSiHeader* h = getRomHeader(fpath);
|
||||||
|
|
||||||
@ -374,7 +374,7 @@ bool install(char* tadPath, bool systemTitle)
|
|||||||
iprintf("\x1B[31m"); //red
|
iprintf("\x1B[31m"); //red
|
||||||
iprintf("Error: ");
|
iprintf("Error: ");
|
||||||
iprintf("\x1B[33m"); //yellow
|
iprintf("\x1B[33m"); //yellow
|
||||||
iprintf("Could not open file.\n");
|
iprintf("Could not decrypt TAD.\n");
|
||||||
iprintf("\x1B[47m"); //white
|
iprintf("\x1B[47m"); //white
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
@ -385,7 +385,6 @@ bool install(char* tadPath, bool systemTitle)
|
|||||||
if (_patchGameCode(h))
|
if (_patchGameCode(h))
|
||||||
fixHeader = true;
|
fixHeader = true;
|
||||||
|
|
||||||
result = decryptTad(fpath);
|
|
||||||
//title id must be one of these
|
//title id must be one of these
|
||||||
if (h->tid_high == 0x00030004 || // DSiWare
|
if (h->tid_high == 0x00030004 || // DSiWare
|
||||||
h->tid_high == 0x00030005 || // "Unimportant" system titles
|
h->tid_high == 0x00030005 || // "Unimportant" system titles
|
||||||
@ -396,14 +395,17 @@ bool install(char* tadPath, bool systemTitle)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
iprintf("\x1B[31m"); //red
|
iprintf("\x1B[31m"); //red
|
||||||
iprintf("Error: ");
|
iprintf("TID Error: ");
|
||||||
iprintf("\x1B[33m"); //yellow
|
iprintf("\x1B[33m"); //yellow
|
||||||
iprintf("This is not a DSi rom.\n");
|
iprintf("Could not decrypt TAD.\n%s", fpath);
|
||||||
iprintf("\x1B[47m"); //white
|
iprintf("\x1B[47m"); //white
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
// I am going to remove patching because it results in bad TMDs that the launcher auto deletes.
|
||||||
|
// Comment these back in if you really want, but know that 99% of dev apps will not install right with patching.
|
||||||
|
|
||||||
//offer to patch system titles to normal DSiWare on SysNAND
|
//offer to patch system titles to normal DSiWare on SysNAND
|
||||||
|
/*
|
||||||
if(!sdnandMode && h->tid_high != 0x00030004 && h->tid_high != 0x00030017) //do not allow patching home menus to be normal DSiWare! This will trigger "ERROR! - 0x0000000000000008 HWINFO_SECURE" on prototype launchers. May also cause issues on the prod versions.
|
if(!sdnandMode && h->tid_high != 0x00030004 && h->tid_high != 0x00030017) //do not allow patching home menus to be normal DSiWare! This will trigger "ERROR! - 0x0000000000000008 HWINFO_SECURE" on prototype launchers. May also cause issues on the prod versions.
|
||||||
{
|
{
|
||||||
if(choiceBox("This is set as a system/dev\ntitle, would you like to patch\nit to be a normal DSiWare?\n\nThis is safer, but invalidates\nRSA checks and may not work.\n\nIf the title is homebrew this isstrongly recommended.") == YES)
|
if(choiceBox("This is set as a system/dev\ntitle, would you like to patch\nit to be a normal DSiWare?\n\nThis is safer, but invalidates\nRSA checks and may not work.\n\nIf the title is homebrew this isstrongly recommended.") == YES)
|
||||||
@ -412,8 +414,10 @@ bool install(char* tadPath, bool systemTitle)
|
|||||||
fixHeader = true;
|
fixHeader = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
//offer to patch home menus to be system titles on SysNAND
|
//offer to patch home menus to be system titles on SysNAND
|
||||||
|
/*
|
||||||
if(!sdnandMode && h->tid_high == 0x00030017)
|
if(!sdnandMode && h->tid_high == 0x00030017)
|
||||||
{
|
{
|
||||||
if(choiceBox("This title is a home menu.\nWould you like to patch it to bea system title?\n\nThis is safer and prevents your\nhome menu from being hidden.") == YES)
|
if(choiceBox("This title is a home menu.\nWould you like to patch it to bea system title?\n\nThis is safer and prevents your\nhome menu from being hidden.") == YES)
|
||||||
@ -422,6 +426,7 @@ bool install(char* tadPath, bool systemTitle)
|
|||||||
fixHeader = true;
|
fixHeader = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
//no system titles without Unlaunch
|
//no system titles without Unlaunch
|
||||||
if (!unlaunchFound && h->tid_high != 0x00030004)
|
if (!unlaunchFound && h->tid_high != 0x00030004)
|
||||||
@ -538,6 +543,7 @@ bool install(char* tadPath, bool systemTitle)
|
|||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
//system title patch
|
//system title patch
|
||||||
|
/*
|
||||||
if (systemTitle)
|
if (systemTitle)
|
||||||
{
|
{
|
||||||
iprintf("System Title Patch...");
|
iprintf("System Title Patch...");
|
||||||
@ -549,8 +555,10 @@ bool install(char* tadPath, bool systemTitle)
|
|||||||
|
|
||||||
fixHeader = true;
|
fixHeader = true;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
//check that there's space on nand
|
//check that there's space on nand
|
||||||
|
/*
|
||||||
if (!_checkDsiSpace(installSize, (h->tid_high != 0x00030004)))
|
if (!_checkDsiSpace(installSize, (h->tid_high != 0x00030004)))
|
||||||
{
|
{
|
||||||
if (sdnandMode && choicePrint("Install as system title?"))
|
if (sdnandMode && choicePrint("Install as system title?"))
|
||||||
@ -563,6 +571,7 @@ bool install(char* tadPath, bool systemTitle)
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
//check for saves
|
//check for saves
|
||||||
char pubPath[PATH_MAX];
|
char pubPath[PATH_MAX];
|
||||||
@ -858,5 +867,11 @@ complete:
|
|||||||
if (!sdnandMode)
|
if (!sdnandMode)
|
||||||
nandio_lock_writing();
|
nandio_lock_writing();
|
||||||
|
|
||||||
|
remove("sd:/_nds/tadtests/tmp/temp.tmd");
|
||||||
|
remove("sd:/_nds/tadtests/tmp/temp.tik");
|
||||||
|
remove("sd:/_nds/tadtests/tmp/temp.srl.enc");
|
||||||
|
remove("sd:/_nds/tadtests/tmp/temp.srl");
|
||||||
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -203,7 +203,7 @@ int main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
else if (!unlaunchPatches)
|
else if (!unlaunchPatches)
|
||||||
{
|
{
|
||||||
messageBox("Unlaunch's Launcher Patches are\nnot enabled. You will need these\nif you patch any TADs.\n\n\x1B[46mhttps://dsi.cfw.guide/\x1B[47m");
|
messageBox("Unlaunch's Launcher Patches are\nnot enabled. You will need these\nto boot any TADs.\n\n\x1B[46mhttps://dsi.cfw.guide/\x1B[47m");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
129
arm9/src/tad.c
129
arm9/src/tad.c
@ -31,16 +31,17 @@
|
|||||||
If for whatever reason you want to make TADs, see here:
|
If for whatever reason you want to make TADs, see here:
|
||||||
https://randommeaninglesscharacters.com/dsidev/man/maketad.html
|
https://randommeaninglesscharacters.com/dsidev/man/maketad.html
|
||||||
*/
|
*/
|
||||||
const unsigned char commonKey[3][16] = {
|
const unsigned char devKey[] = {
|
||||||
// DEV
|
0xA1, 0x60, 0x4A, 0x6A, 0x71, 0x23, 0xB5, 0x29,
|
||||||
{0xA1, 0x60, 0x4A, 0x6A, 0x71, 0x23, 0xB5, 0x29,
|
0xAE, 0x8B, 0xEC, 0x32, 0xC8, 0x16, 0xFC, 0xAA
|
||||||
0xAE, 0x8B, 0xEC, 0x32, 0xC8, 0x16, 0xFC, 0xAA},
|
};
|
||||||
// PROD
|
const unsigned char prodKey[] = {
|
||||||
{0xAF, 0x1B, 0xF5, 0x16, 0xA8, 0x07, 0xD2, 0x1A,
|
0xAF, 0x1B, 0xF5, 0x16, 0xA8, 0x07, 0xD2, 0x1A,
|
||||||
0xEA, 0x45, 0x98, 0x4F, 0x04, 0x74, 0x28, 0x61},
|
0xEA, 0x45, 0x98, 0x4F, 0x04, 0x74, 0x28, 0x61
|
||||||
// DEBUGGER
|
};
|
||||||
{0xA2, 0xFD, 0xDD, 0xF2 ,0xE4, 0x23, 0x57, 0x4A,
|
const unsigned char debuggerKey[] = {
|
||||||
0xE7, 0xED, 0x86, 0x57, 0xB5, 0xAB, 0x19, 0xD3}
|
0xA2, 0xFD, 0xDD, 0xF2 ,0xE4, 0x23, 0x57, 0x4A,
|
||||||
|
0xE7, 0xED, 0x86, 0x57, 0xB5, 0xAB, 0x19, 0xD3
|
||||||
};
|
};
|
||||||
// Content IV be fine as a hardcoded string. Content IV is based off of the content index. (index # with zerobyte padding)
|
// Content IV be fine as a hardcoded string. Content IV is based off of the content index. (index # with zerobyte padding)
|
||||||
// All TADs I've seen only ever had a single content. It might be a good idea to add something down the line in case a
|
// All TADs I've seen only ever had a single content. It might be a good idea to add something down the line in case a
|
||||||
@ -69,7 +70,11 @@ typedef struct {
|
|||||||
uint32_t srlOffset;
|
uint32_t srlOffset;
|
||||||
uint32_t metaOffset;
|
uint32_t metaOffset;
|
||||||
} Tad;
|
} Tad;
|
||||||
bool tadSuccess;
|
unsigned char srlCompany[2];
|
||||||
|
unsigned char srlTidLow[4];
|
||||||
|
unsigned char srlTidHigh[4];
|
||||||
|
unsigned char srlVerLow[1];
|
||||||
|
unsigned char srlVerHigh[1];
|
||||||
|
|
||||||
uint32_t swap_endian_u32(uint32_t x) {
|
uint32_t swap_endian_u32(uint32_t x) {
|
||||||
return (x >> 24) | ((x >> 8) & 0xff00) | ((x << 8) & 0xff0000) | (x << 24);
|
return (x >> 24) | ((x >> 8) & 0xff00) | ((x << 8) & 0xff0000) | (x << 24);
|
||||||
@ -79,8 +84,7 @@ uint16_t swap_endian_u16(uint16_t x) {
|
|||||||
return (x >> 8) | (x << 8);
|
return (x >> 8) | (x << 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t round_up( const u32 v, const u32 align )
|
uint32_t round_up( const u32 v, const u32 align ) {
|
||||||
{
|
|
||||||
u32 r = ((v + align - 1) / align) * align;
|
u32 r = ((v + align - 1) / align) * align;
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -91,8 +95,7 @@ void decrypt_cbc(const unsigned char* key, const unsigned char* iv, const unsign
|
|||||||
aes_crypt_cbc(&ctx, AES_DECRYPT, dataSize, iv, encryptedData, decryptedData);
|
aes_crypt_cbc(&ctx, AES_DECRYPT, dataSize, iv, encryptedData, decryptedData);
|
||||||
}
|
}
|
||||||
|
|
||||||
int decryptTad(char const* src)
|
int openTad(char const* src) {
|
||||||
{
|
|
||||||
if (!src) return 1;
|
if (!src) return 1;
|
||||||
|
|
||||||
FILE *file = fopen(src, "rb");
|
FILE *file = fopen(src, "rb");
|
||||||
@ -139,7 +142,6 @@ int decryptTad(char const* src)
|
|||||||
|
|
||||||
Header header;
|
Header header;
|
||||||
fread(&header, sizeof(Header), 1, file);
|
fread(&header, sizeof(Header), 1, file);
|
||||||
fclose(file);
|
|
||||||
iprintf("Parsing TAD header...\n");
|
iprintf("Parsing TAD header...\n");
|
||||||
Tad tad;
|
Tad tad;
|
||||||
tad.hdrOffset = 0;
|
tad.hdrOffset = 0;
|
||||||
@ -153,6 +155,16 @@ int decryptTad(char const* src)
|
|||||||
// TODO: Make sure offset calculation and alignment is correct by comparing that to total size
|
// TODO: Make sure offset calculation and alignment is correct by comparing that to total size
|
||||||
//iprintf(" hdrSize: %lu\n", swap_endian_u32(header.hdrSize));
|
//iprintf(" hdrSize: %lu\n", swap_endian_u32(header.hdrSize));
|
||||||
//iprintf(" hdrOffset: %lu\n", tad.hdrOffset);
|
//iprintf(" hdrOffset: %lu\n", tad.hdrOffset);
|
||||||
|
|
||||||
|
// Commenting this block out makes the TAD decrypt improperly. Truly a programming moment.
|
||||||
|
// 18803 = "Is". This is the standard TAD type.
|
||||||
|
if (swap_endian_u16(header.tadType) == 18803) {
|
||||||
|
//iprintf(" tadType: 'Is'\n");
|
||||||
|
} else {
|
||||||
|
iprintf(" tadType: UNKNOWN\nERROR: unexpected TAD type\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
//iprintf(" tadVersion: %u\n", swap_endian_u16(header.tadVersion));
|
//iprintf(" tadVersion: %u\n", swap_endian_u16(header.tadVersion));
|
||||||
//iprintf(" certSize: %lu\n", swap_endian_u32(header.certSize));
|
//iprintf(" certSize: %lu\n", swap_endian_u32(header.certSize));
|
||||||
//iprintf(" certOffset: %lu\n", tad.certOffset);
|
//iprintf(" certOffset: %lu\n", tad.certOffset);
|
||||||
@ -167,6 +179,11 @@ int decryptTad(char const* src)
|
|||||||
//iprintf(" metaSize: %lu\n", swap_endian_u32(header.metaSize));
|
//iprintf(" metaSize: %lu\n", swap_endian_u32(header.metaSize));
|
||||||
//iprintf(" metaOffset: %lu\n", tad.metaOffset);
|
//iprintf(" metaOffset: %lu\n", tad.metaOffset);
|
||||||
|
|
||||||
|
fseek(file, tad.tmdOffset+396, SEEK_SET);
|
||||||
|
fread(srlTidHigh, 1, 4, file);
|
||||||
|
fread(srlTidLow, 1, 4, file);
|
||||||
|
fclose(file);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Copy the contents of the TAD to the SD card.
|
Copy the contents of the TAD to the SD card.
|
||||||
|
|
||||||
@ -178,13 +195,13 @@ int decryptTad(char const* src)
|
|||||||
|
|
||||||
iprintf("Copying output files...\n");
|
iprintf("Copying output files...\n");
|
||||||
// Sorry for copy pasting, I'll make this a routine later
|
// Sorry for copy pasting, I'll make this a routine later
|
||||||
//iprintf(" Copying TMD...\n");
|
iprintf(" Copying TMD...\n");
|
||||||
copyFilePart(src, tad.tmdOffset, swap_endian_u32(header.tmdSize), "sd:/_nds/tadtests/tmp/temp.tmd");
|
copyFilePart(src, tad.tmdOffset, swap_endian_u32(header.tmdSize), "sd:/_nds/tadtests/tmp/temp.tmd");
|
||||||
|
|
||||||
//iprintf(" Copying ticket...\n");
|
iprintf(" Copying ticket...\n");
|
||||||
copyFilePart(src, tad.ticketOffset, swap_endian_u32(header.ticketSize), "sd:/_nds/tadtests/tmp/temp.tik");
|
copyFilePart(src, tad.ticketOffset, swap_endian_u32(header.ticketSize), "sd:/_nds/tadtests/tmp/temp.tik");
|
||||||
|
|
||||||
//iprintf(" Copying SRL...\n");
|
iprintf(" Copying SRL...\n");
|
||||||
copyFilePart(src, tad.srlOffset, swap_endian_u32(header.srlSize), "sd:/_nds/tadtests/tmp/temp.srl.enc");
|
copyFilePart(src, tad.srlOffset, swap_endian_u32(header.srlSize), "sd:/_nds/tadtests/tmp/temp.srl.enc");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -211,7 +228,7 @@ int decryptTad(char const* src)
|
|||||||
fclose(ticket);
|
fclose(ticket);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This is SRL decryption. AES-CBC.
|
This is SRL decryption (AES-CBC).
|
||||||
|
|
||||||
Common key + title key IV to decrypt title key, title key + content IV to decrypt content
|
Common key + title key IV to decrypt title key, title key + content IV to decrypt content
|
||||||
|
|
||||||
@ -225,31 +242,72 @@ int decryptTad(char const* src)
|
|||||||
https://problemkaputt.de/gbatek.htm#dscartridgeheader
|
https://problemkaputt.de/gbatek.htm#dscartridgeheader
|
||||||
https://gist.github.com/rvtr/f1069530129b7a57967e3fc4b30866b4#file-decrypt_tad-py-L84
|
https://gist.github.com/rvtr/f1069530129b7a57967e3fc4b30866b4#file-decrypt_tad-py-L84
|
||||||
*/
|
*/
|
||||||
//iprintf(" Decrypting title key...\n");
|
bool keyFail;
|
||||||
unsigned char title_key_dec[16];
|
iprintf("Trying dev common key...\n");
|
||||||
decrypt_cbc(commonKey[0], title_key_iv, title_key_enc, sizeof(title_key_enc), 16, title_key_dec);
|
keyFail = decryptTad(devKey, title_key_iv, title_key_enc, content_iv, swap_endian_u32(header.srlSize), srlTidLow);
|
||||||
//printf(" Title key decrypted!\n");
|
|
||||||
/* for (int i = 0; i < 16; i++) {printf("%02X", title_key_dec[i]);} */
|
|
||||||
|
|
||||||
|
if (keyFail == TRUE) {
|
||||||
|
remove("sd:/_nds/tadtests/tmp/temp.srl");
|
||||||
|
iprintf("Key fail!\n\nTrying debugger common key...\n");
|
||||||
|
keyFail = decryptTad(debuggerKey, title_key_iv, title_key_enc, content_iv, swap_endian_u32(header.srlSize), srlTidLow);
|
||||||
|
}
|
||||||
|
if (keyFail == TRUE) {
|
||||||
|
remove("sd:/_nds/tadtests/tmp/temp.srl");
|
||||||
|
iprintf("Key fail!\n\nTrying prod common key...\n");
|
||||||
|
keyFail = decryptTad(prodKey, title_key_iv, title_key_enc, content_iv, swap_endian_u32(header.srlSize), srlTidLow);
|
||||||
|
}
|
||||||
|
if (keyFail == TRUE) {
|
||||||
|
remove("sd:/_nds/tadtests/tmp/temp.srl");
|
||||||
|
iprintf("All keys failed!\n");
|
||||||
|
return "ERROR";
|
||||||
|
}
|
||||||
|
return "sd:/_nds/tadtests/tmp/temp.srl";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool decryptTad(unsigned char* commonKey,
|
||||||
|
unsigned char* title_key_iv,
|
||||||
|
unsigned char* title_key_enc,
|
||||||
|
unsigned char* content_iv,
|
||||||
|
int srlSize,
|
||||||
|
unsigned char* srlTidLow) {
|
||||||
|
unsigned char title_key_dec[16];
|
||||||
|
unsigned char title_key_iv_bak[16];
|
||||||
unsigned char srl_buffer_enc[16];
|
unsigned char srl_buffer_enc[16];
|
||||||
unsigned char srl_buffer_dec[16];
|
unsigned char srl_buffer_dec[16];
|
||||||
|
|
||||||
|
// Backup IV because PolarSSL will overwrite it
|
||||||
|
memcpy( title_key_iv_bak, title_key_iv, 16 );
|
||||||
|
|
||||||
FILE *srlFile_enc = fopen("sd:/_nds/tadtests/tmp/temp.srl.enc", "rb");
|
FILE *srlFile_enc = fopen("sd:/_nds/tadtests/tmp/temp.srl.enc", "rb");
|
||||||
fseek(srlFile_enc, 0, SEEK_SET);
|
fseek(srlFile_enc, 0, SEEK_SET);
|
||||||
FILE *srlFile_dec = fopen("sd:/_nds/tadtests/tmp/temp.srl", "wb");
|
FILE *srlFile_dec = fopen("sd:/_nds/tadtests/tmp/temp.srl", "wb");
|
||||||
fseek(srlFile_dec, 0, SEEK_SET);
|
fseek(srlFile_dec, 0, SEEK_SET);
|
||||||
|
|
||||||
//iprintf("\n Decrypting SRL chunks...\n");
|
iprintf(" Decrypting SRL in chunks..\n");
|
||||||
for (int i = 0; i < swap_endian_u32(header.srlSize);) {
|
decrypt_cbc(commonKey, title_key_iv, title_key_enc, 16, 16, title_key_dec);
|
||||||
|
int i=0;
|
||||||
|
bool keyFail = FALSE;
|
||||||
|
while (i < srlSize && keyFail == FALSE) {
|
||||||
fread(srl_buffer_enc, 1, 16, srlFile_enc);
|
fread(srl_buffer_enc, 1, 16, srlFile_enc);
|
||||||
decrypt_cbc(title_key_dec, content_iv, srl_buffer_enc, 16, 16, srl_buffer_dec);
|
decrypt_cbc(title_key_dec, content_iv, srl_buffer_enc, 16, 16, srl_buffer_dec);
|
||||||
fwrite(srl_buffer_dec, 1, 16, srlFile_dec);
|
fwrite(srl_buffer_dec, 1, 16, srlFile_dec);
|
||||||
printProgressBar( ((float)i / (float)swap_endian_u32(header.srlSize)) );
|
printProgressBar( ((float)i / (float)srlSize) );
|
||||||
|
if (i == 560) {
|
||||||
|
if (srl_buffer_dec[3] != srlTidLow[0] ||
|
||||||
|
srl_buffer_dec[2] != srlTidLow[1] ||
|
||||||
|
srl_buffer_dec[1] != srlTidLow[2] ||
|
||||||
|
srl_buffer_dec[0] != srlTidLow[3] ) {
|
||||||
|
keyFail = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
i=i+16;
|
i=i+16;
|
||||||
}
|
}
|
||||||
fclose(srlFile_enc);
|
|
||||||
fclose(srlFile_dec);
|
fclose(srlFile_dec);
|
||||||
return "sd:/_nds/tadtests/tmp/temp.srl";
|
fclose(srlFile_enc);
|
||||||
|
// Restore IV
|
||||||
|
memcpy( title_key_iv, title_key_iv_bak, 16 );
|
||||||
|
return keyFail;
|
||||||
}
|
}
|
||||||
|
|
||||||
void printTadInfo(char const* fpath)
|
void printTadInfo(char const* fpath)
|
||||||
@ -257,13 +315,6 @@ void printTadInfo(char const* fpath)
|
|||||||
clearScreen(&topScreen);
|
clearScreen(&topScreen);
|
||||||
if (!fpath) return;
|
if (!fpath) return;
|
||||||
|
|
||||||
|
|
||||||
unsigned char srlCompany[2];
|
|
||||||
unsigned char srlTidLow[4];
|
|
||||||
unsigned char srlTidHigh[4];
|
|
||||||
unsigned char srlVerLow[1];
|
|
||||||
unsigned char srlVerHigh[1];
|
|
||||||
|
|
||||||
FILE *file = fopen(fpath, "rb");
|
FILE *file = fopen(fpath, "rb");
|
||||||
Header header;
|
Header header;
|
||||||
fread(&header, sizeof(Header), 1, file);
|
fread(&header, sizeof(Header), 1, file);
|
||||||
@ -314,5 +365,5 @@ void printTadInfo(char const* fpath)
|
|||||||
|
|
||||||
//print full file path
|
//print full file path
|
||||||
iprintf("\n\n%s\n", fpath);
|
iprintf("\n\n%s\n", fpath);
|
||||||
|
fclose(file);
|
||||||
}
|
}
|
||||||
@ -4,6 +4,12 @@
|
|||||||
#include <nds/ndstypes.h>
|
#include <nds/ndstypes.h>
|
||||||
#include <nds/memory.h>
|
#include <nds/memory.h>
|
||||||
|
|
||||||
int decryptTad(char const* src);
|
int openTad(char const* src);
|
||||||
|
bool decryptTad(unsigned char* commonKey,
|
||||||
|
unsigned char* title_key_iv,
|
||||||
|
unsigned char* title_key_enc,
|
||||||
|
unsigned char* content_iv,
|
||||||
|
int srlSize,
|
||||||
|
unsigned char* srlTidLow);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
Loading…
Reference in New Issue
Block a user