Add fw dumping
- also fatfs is stupid - also close files properly on a failed copy - also check for errors during folder readouts - also make sure holding vol- doesn't dump the keys anyway
This commit is contained in:
@@ -20,6 +20,7 @@ MenuEntry_t mainMenuEntries[] = {
|
||||
{.optionUnion = COLORTORGB(COLOR_YELLOW), .name = "Emummc"},
|
||||
{.B = 255, .G = 255, .name = "Test Controllers"},
|
||||
{.R = 255, .name = "Cause an exception"},
|
||||
{.optionUnion = COLORTORGB(COLOR_BLUE), .name = "Dump Firmware"},
|
||||
{.optionUnion = COLORTORGB(COLOR_ORANGE), .name = "View dumped keys"},
|
||||
{.R = 255, .name = "Reboot to payload"}
|
||||
};
|
||||
@@ -73,6 +74,7 @@ menuPaths mainMenuPaths[] = {
|
||||
HandleEMUMMC,
|
||||
TestControllers,
|
||||
CrashTE,
|
||||
DumpSysFw,
|
||||
ViewKeys,
|
||||
RebootToPayload
|
||||
};
|
||||
|
||||
@@ -3,6 +3,20 @@
|
||||
#include "../gfx/gfxutils.h"
|
||||
#include "../gfx/menu.h"
|
||||
#include "../hid/hid.h"
|
||||
#include <libs/fatfs/ff.h>
|
||||
#include "../keys/keys.h"
|
||||
#include "../keys/nca.h"
|
||||
#include <storage/nx_sd.h>
|
||||
#include "../fs/fsutils.h"
|
||||
#include <utils/util.h>
|
||||
#include "../storage/mountmanager.h"
|
||||
#include "../err.h"
|
||||
#include <utils/sprintf.h>
|
||||
#include <mem/heap.h>
|
||||
#include "../tegraexplorer/tconf.h"
|
||||
#include "../fs/readers/folderReader.h"
|
||||
#include <string.h>
|
||||
#include "../fs/fscopy.h"
|
||||
|
||||
void TestControllers(){
|
||||
gfx_clearscreen();
|
||||
@@ -26,4 +40,101 @@ extern int launch_payload(char *path);
|
||||
|
||||
void RebootToPayload(){
|
||||
launch_payload("atmosphere/reboot_payload.bin");
|
||||
}
|
||||
|
||||
void DumpSysFw(){
|
||||
char sysPath[25 + 36 + 3 + 1]; // 24 for "bis:/Contents/registered", 36 for ncaName.nca, 3 for /00, and 1 to make sure :)
|
||||
char *baseSdPath;
|
||||
|
||||
u32 timer = get_tmr_s();
|
||||
|
||||
if (!sd_mount())
|
||||
return;
|
||||
|
||||
if (connectMMC(MMC_CONN_EMMC))
|
||||
return;
|
||||
|
||||
if (!TConf.keysDumped)
|
||||
return;
|
||||
|
||||
ErrCode_t err = mountMMCPart("SYSTEM");
|
||||
if (err.err){
|
||||
DrawError(err);
|
||||
return;
|
||||
}
|
||||
|
||||
baseSdPath = malloc(36 + 16);
|
||||
sprintf(baseSdPath, "sd:/tegraexplorer/Firmware/%d (%s)", TConf.pkg1ver, TConf.pkg1ID);
|
||||
int baseSdPathLen = strlen(baseSdPath);
|
||||
|
||||
f_mkdir("sd:/tegraexplorer");
|
||||
f_mkdir("sd:/tegraexplorer/Firmware");
|
||||
|
||||
gfx_clearscreen();
|
||||
|
||||
gfx_printf("Pkg1 id: '%s', kb %d\n", TConf.pkg1ID, TConf.pkg1ver);
|
||||
if (FileExists(baseSdPath)){
|
||||
SETCOLOR(COLOR_ORANGE, COLOR_DEFAULT);
|
||||
gfx_printf("Destination already exists. Replace? ");
|
||||
if (!MakeYesNoHorzMenu(3, COLOR_DEFAULT)){
|
||||
free(baseSdPath);
|
||||
return;
|
||||
}
|
||||
RESETCOLOR;
|
||||
gfx_printf("\nReminder! delete the folder. i can't delete recursively yet");
|
||||
gfx_putc('\n');
|
||||
}
|
||||
|
||||
f_mkdir(baseSdPath);
|
||||
|
||||
gfx_printf("Out: %s\nReading entries...\n", baseSdPath);
|
||||
int readRes = 0;
|
||||
Vector_t fileVec = ReadFolder("bis:/Contents/registered", &readRes);
|
||||
if (readRes){
|
||||
DrawError(newErrCode(readRes));
|
||||
free(baseSdPath);
|
||||
return;
|
||||
}
|
||||
|
||||
gfx_printf("Starting dump...\n");
|
||||
SETCOLOR(COLOR_GREEN, COLOR_DEFAULT);
|
||||
|
||||
int res = 0;
|
||||
int total = 1;
|
||||
vecDefArray(FSEntry_t*, fsEntries, fileVec);
|
||||
for (int i = 0; i < fileVec.count; i++){
|
||||
sprintf(sysPath, (fsEntries[i].isDir) ? "%s/%s/00" : "%s/%s", "bis:/Contents/registered", fsEntries[i].name);
|
||||
int contentType = GetNcaType(sysPath);
|
||||
|
||||
if (contentType < 0){
|
||||
res = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
char *sdPath = malloc(baseSdPathLen + 45);
|
||||
sprintf(sdPath, "%s/%s", baseSdPath, fsEntries[i].name);
|
||||
if (contentType == Meta)
|
||||
memcpy(sdPath + strlen(sdPath) - 4, ".cnmt.nca", 10);
|
||||
|
||||
gfx_printf("[%3d / %3d] %s\r", total, fileVec.count, fsEntries[i].name);
|
||||
total++;
|
||||
err = FileCopy(sysPath, sdPath, 0);
|
||||
free(sdPath);
|
||||
if (err.err){
|
||||
DrawError(err);
|
||||
res = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
clearFileVector(&fileVec);
|
||||
|
||||
RESETCOLOR;
|
||||
|
||||
if (res){
|
||||
gfx_printf("\nDump failed...\n");
|
||||
}
|
||||
|
||||
gfx_printf("\n\nDone! Time taken: %ds\nPress any key to exit", get_tmr_s() - timer);
|
||||
free(baseSdPath);
|
||||
hidWait();
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
void RebootToPayload();
|
||||
void TestControllers();
|
||||
void TestControllers();
|
||||
void DumpSysFw();
|
||||
Reference in New Issue
Block a user