1
0
Fork 0
mirror of https://github.com/suchmememanyskill/TegraExplorer.git synced 2024-11-26 05:42:07 +00:00

Include a (bad) method to dump with .cnmt.nca

This commit is contained in:
SuchMemeManySkill 2020-07-14 17:38:56 +02:00
parent 81cf8c201c
commit b42b52eb43
11 changed files with 204 additions and 63 deletions

View file

@ -116,3 +116,5 @@ extern gpt_entry_rule gpt_fs_rules[];
extern menu_entry mmcmenu_start[];
extern menu_entry mmcmenu_filemenu[];
extern menu_entry fwDump_typeMenu[];

View file

@ -92,4 +92,11 @@ menu_entry mmcmenu_filemenu[] = {
{NULL, COLOR_VIOLET, {ISSKIP | ISMENU}},
{"\nBack", COLOR_WHITE, {ISMENU}},
{"Dump to SD", COLOR_YELLOW, {ISMENU}}
};
menu_entry fwDump_typeMenu[] = {
{"Back\n", COLOR_WHITE, {ISMENU}},
{"Firmware format type:", COLOR_WHITE, {ISMENU | ISSKIP}},
{"Daybreak (prod.keys required!)", COLOR_BLUE, {ISMENU}},
{"ChoiNX", COLOR_VIOLET, {ISMENU}}
};

View file

@ -218,9 +218,6 @@ int dump_biskeys(){
//sdmmc_storage_set_mmc_partition(&storage, 0);
//nx_emmc_gpt_parse(&sys_gpt, &storage);
se_aes_key_set(8, bis_key[2] + 0x00, 0x10);
se_aes_key_set(9, bis_key[2] + 0x10, 0x10);
pkg1inf.ver = pkg1_id->kb;
strcpy(pkg1inf.id, pkg1_id->id);

View file

@ -0,0 +1,62 @@
#include "keys.h"
#include "../../utils/types.h"
#include "../../libs/fatfs/ff.h"
#include "../../sec/se.h"
#include "../../mem/heap.h"
#include "../gfx/gfxutils.h"
#include "../../config/ini.h"
#include "../common/common.h"
#include <string.h>
char *getKey(const char *search, link_t *inilist){
LIST_FOREACH_ENTRY(ini_sec_t, ini_sec, inilist, link){
if (ini_sec->type == INI_CHOICE){
LIST_FOREACH_ENTRY(ini_kv_t, kv, &ini_sec->kvs, link)
{
if (!strcmp(search, kv->key))
return kv->val;
}
}
}
return NULL;
}
u8 getHexSingle(const char c) {
if (c >= '0' && c <= '9')
return c - '0';
if (c >= 'a' && c <= 'f')
return c - 'a' + 10;
}
u8 *getHex(const char *in){
u32 len = strlen(in), count = 0;
u8 *out = calloc(len / 2, sizeof(u8));
for (u32 i = 0; i < len; i += 2){
out[count++] = (u8)(getHexSingle(in[i]) << 4) | (getHexSingle(in[i + 1]));
}
return out;
}
u8 *GetKey(const char *keypath, const char *keyName){
LIST_INIT(inilist);
char *key;
u8 *hex = NULL;
if (!ini_parse(&inilist, keypath, false)){
gfx_errDisplay("GetKey", ERR_INI_PARSE_FAIL, 1);
goto out_free;
}
if ((key = getKey(keyName, &inilist)) == NULL){
gfx_errDisplay("GetKey", ERR_INI_PARSE_FAIL, 2);
goto out_free;
}
hex = getHex(key);
out_free:;
list_empty(&inilist);
return hex;
}

View file

@ -0,0 +1,4 @@
#pragma once
#include "../../utils/types.h"
u8 *GetKey(const char *keypath, const char *keyName);

View file

@ -0,0 +1,46 @@
#include "nca.h"
#include "keys.h"
#include "../../utils/types.h"
#include "../../libs/fatfs/ff.h"
#include "../../sec/se.h"
#include "../../mem/heap.h"
#include "../gfx/gfxutils.h"
#include "../../config/ini.h"
#include "../common/common.h"
#include <string.h>
int SetHeaderKey(){
u8 *header_key = GetKey("sd:/switch/prod.keys", "header_key");
if (header_key == NULL)
return -1;
se_aes_key_set(4, header_key + 0x00, 0x10);
se_aes_key_set(5, header_key + 0x10, 0x10);
return 0;
}
int GetNcaType(char *ncaPath){
FIL fp;
u32 read_bytes = 0;
if (f_open(&fp, ncaPath, FA_READ | FA_OPEN_EXISTING))
return -1;
u8 *dec_header = (u8*)malloc(0x600);
if (f_lseek(&fp, 0x200) || f_read(&fp, dec_header, 32, &read_bytes) || read_bytes != 32){
f_close(&fp);
free(dec_header);
return -1;
}
se_aes_xts_crypt(5,4,0,1,dec_header + 0x200, dec_header, 32, 1);
u8 ContentType = dec_header[0x205];
f_close(&fp);
free(dec_header);
return ContentType;
}

View file

@ -0,0 +1,4 @@
#pragma once
int GetNcaType(char *ncaPath);
int SetHeaderKey();

View file

@ -1,4 +1,5 @@
#include "savesign.h"
#include "keys.h"
#include "../../utils/types.h"
#include "../../libs/fatfs/ff.h"
#include "../../sec/se.h"
@ -62,62 +63,15 @@ out_free:;
return success;
}
char *getKey(const char *search, link_t *inilist){
LIST_FOREACH_ENTRY(ini_sec_t, ini_sec, inilist, link){
if (ini_sec->type == INI_CHOICE){
LIST_FOREACH_ENTRY(ini_kv_t, kv, &ini_sec->kvs, link)
{
if (!strcmp(search, kv->key))
return kv->val;
}
}
}
return NULL;
}
u8 getHexSingle(const char c) {
if (c >= '0' && c <= '9')
return c - '0';
if (c >= 'a' && c <= 'f')
return c - 'a' + 10;
}
u8 *getHex(const char *in){
u32 len = strlen(in), count = 0;
u8 *out = calloc(len / 2, sizeof(u8));
for (u32 i = 0; i < len; i += 2){
out[count++] = (u8)(getHexSingle(in[i]) << 4) | (getHexSingle(in[i + 1]));
}
return out;
}
bool save_sign(const char *keypath, const char *savepath){
LIST_INIT(inilist);
char *key;
u8 *hex;
bool success = false;
u8 *key = GetKey(keypath, "save_mac_key");
if (!ini_parse(&inilist, keypath, false)){
gfx_errDisplay("save_sign", ERR_INI_PARSE_FAIL, 1);
goto out_free;
if (key == NULL){
return false;
}
if ((key = getKey("save_mac_key", &inilist)) == NULL){
gfx_errDisplay("save_sign", ERR_INI_PARSE_FAIL, 2);
goto out_free;
}
if (!save_commit(savepath, key))
return false;
hex = getHex(key);
if (!save_commit(savepath, hex))
goto out_free;
success = true;
out_free:;
list_empty(&inilist);
return success;
return true;
}

View file

@ -60,7 +60,10 @@ void MainMenu_Tools(){
displaygpio();
break;
case TOOLS_DUMPFIRMWARE:
dumpfirmware(SYSMMC);
res = menu_make(fwDump_typeMenu, 4, "-- Fw Type --");
if (res >= 2)
dumpfirmware(SYSMMC, (res == 2));
break;
}
}

View file

@ -17,6 +17,7 @@
#include "../fs/fsutils.h"
#include "../../mem/heap.h"
#include "../utils/utils.h"
#include "../fs/nca.h"
extern bool sd_mount();
extern void sd_unmount();
@ -93,7 +94,9 @@ void displaygpio(){
}
}
int dumpfirmware(int mmc){
// bad code ahead aaaa
int dumpfirmware(int mmc, bool daybreak){
DIR dir;
FILINFO fno;
bool fail = false;
@ -107,6 +110,22 @@ int dumpfirmware(int mmc){
connect_mmc(mmc);
mount_mmc("SYSTEM", 2);
if (daybreak){
if (!fsutil_checkfile("sd:/switch/prod.keys")){
SWAPCOLOR(COLOR_RED);
gfx_printf("prod.keys not found.\nPress any button to exit");
hidWait();
return true;
}
if (SetHeaderKey()){
SWAPCOLOR(COLOR_RED);
gfx_printf("Failed to find header key.\nPress any button to exit");
hidWait();
return true;
}
}
gfx_printf("PKG1 version: %d\n", pkg1.ver);
gfx_printf("Creating folders...\n");
@ -115,7 +134,24 @@ int dumpfirmware(int mmc){
sdbase = calloc(32 + strlen(pkg1.id), sizeof(char));
sprintf(sdbase, "sd:/tegraexplorer/Firmware/%d (%s)", pkg1.ver, pkg1.id);
gfx_printf("Out: %s\n", sdbase);
if (fsutil_checkfile(sdbase)){
SWAPCOLOR(COLOR_RED);
gfx_printf("Destination folder already exists.\nPress X to delete this folder, any other button to cancel\nPath: %s", sdbase);
Inputs *input = hidWait();
if (!input->x){
free(sdbase);
return true;
}
else {
SWAPCOLOR(COLOR_WHITE);
gfx_printf("\nDeleting folder..\n");
fsact_del_recursive(sdbase);
}
}
gfx_printf("\rOut: %s\n", sdbase);
f_mkdir(sdbase);
if ((ret = f_opendir(&dir, sysbase)))
@ -127,16 +163,39 @@ int dumpfirmware(int mmc){
printerrors = 0;
while(!f_readdir(&dir, &fno) && fno.fname[0] && !fail){
utils_copystring(fsutil_getnextloc(sdbase, fno.fname), &sdpath);
utils_copystring(fsutil_getnextloc(sysbase, fno.fname), &syspathtemp);
if (fno.fattrib & AM_DIR){
utils_copystring(fsutil_getnextloc(syspathtemp, "00"), &syspath);
free(syspathtemp);
}
else
syspath = syspathtemp;
if (daybreak){
u8 ContentType = GetNcaType(syspath);
if (ContentType < 0){
fail = true;
continue;
}
char *temp;
utils_copystring(fsutil_getnextloc(sdbase, fno.fname), &temp);
if (ContentType == 0x01){
sdpath = calloc(strlen(temp) + 6, 1);
strcpy(sdpath, temp);
memcpy(sdpath + strlen(temp) - 4, ".cnmt.nca", 10);
free(temp);
}
else {
sdpath = temp;
}
}
else
utils_copystring(fsutil_getnextloc(sdbase, fno.fname), &sdpath);
ret = fsact_copy(syspath, sdpath, 0);
gfx_printf("%d %s\r", ++amount, fno.fname);
@ -145,7 +204,9 @@ int dumpfirmware(int mmc){
fail = true;
free(sdpath);
free(syspath);
free(syspathtemp);
if (syspath != syspathtemp)
free(syspath);
}
printerrors = 1;

View file

@ -1,6 +1,7 @@
#pragma once
#include "../../utils/types.h"
void displayinfo();
void displaygpio();
int format(int mode);
int dumpfirmware(int mmc);
int dumpfirmware(int mmc, bool daybreak);