Improved CTRNAND transfer method

This commit is contained in:
d0k3 2017-03-23 16:00:17 +01:00
parent 4dba221bfd
commit a0e65c01bc
4 changed files with 65 additions and 53 deletions

View File

@ -53,7 +53,7 @@
// GodMode9 version // GodMode9 version
#define VERSION "1.0.6" #define VERSION "1.0.7"
// Maximum payload size (arbitrary value!) // Maximum payload size (arbitrary value!)
#define SELF_MAX_SIZE (320 * 1024) // 320kB #define SELF_MAX_SIZE (320 * 1024) // 320kB

View File

@ -692,10 +692,10 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, DirStruct* cur
(filetype & GAME_NCCH ) ? "NCCH image options..." : (filetype & GAME_NCCH ) ? "NCCH image options..." :
(filetype & GAME_EXEFS) ? "Mount as EXEFS image" : (filetype & GAME_EXEFS) ? "Mount as EXEFS image" :
(filetype & GAME_ROMFS) ? "Mount as ROMFS image" : (filetype & GAME_ROMFS) ? "Mount as ROMFS image" :
(filetype & GAME_TMD) ? "TMD file options..." : (filetype & GAME_TMD ) ? "TMD file options..." :
(filetype & GAME_BOSS) ? "BOSS file options..." : (filetype & GAME_BOSS ) ? "BOSS file options..." :
(filetype & GAME_NUSCDN)? "Decrypt NUS/CDN file" : (filetype & GAME_NUSCDN)? "Decrypt NUS/CDN file" :
(filetype & SYS_FIRM) ? "FIRM image options..." : (filetype & SYS_FIRM ) ? "FIRM image options..." :
(filetype & SYS_TICKDB) ? "Mount as ticket.db" : (filetype & SYS_TICKDB) ? "Mount as ticket.db" :
(filetype & BIN_NCCHNFO)? "NCCHinfo options..." : (filetype & BIN_NCCHNFO)? "NCCHinfo options..." :
(filetype & BIN_LAUNCH) ? "Launch as arm9 payload" : "???"; (filetype & BIN_LAUNCH) ? "Launch as arm9 payload" : "???";
@ -794,7 +794,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, DirStruct* cur
int build = (buildable) ? ++n_opt : -1; int build = (buildable) ? ++n_opt : -1;
int build_legit = (buildable_legit) ? ++n_opt : -1; int build_legit = (buildable_legit) ? ++n_opt : -1;
int verify = (verificable) ? ++n_opt : -1; int verify = (verificable) ? ++n_opt : -1;
int ctradapt = (transferable) ? ++n_opt : -1; int ctrtransfer = (transferable) ? ++n_opt : -1;
int hsinject = (hsinjectable) ? ++n_opt : -1; int hsinject = (hsinjectable) ? ++n_opt : -1;
int xorpad = (xorpadable) ? ++n_opt : -1; int xorpad = (xorpadable) ? ++n_opt : -1;
int xorpad_inplace = (xorpadable) ? ++n_opt : -1; int xorpad_inplace = (xorpadable) ? ++n_opt : -1;
@ -807,7 +807,7 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, DirStruct* cur
if (build > 0) optionstr[build-1] = (build_legit < 0) ? "Build CIA from file" : "Build CIA (standard)"; if (build > 0) optionstr[build-1] = (build_legit < 0) ? "Build CIA from file" : "Build CIA (standard)";
if (build_legit > 0) optionstr[build_legit-1] = "Build CIA (legit)"; if (build_legit > 0) optionstr[build_legit-1] = "Build CIA (legit)";
if (verify > 0) optionstr[verify-1] = "Verify file"; if (verify > 0) optionstr[verify-1] = "Verify file";
if (ctradapt > 0) optionstr[ctradapt-1] = "Adapt image to SysNAND"; if (ctrtransfer > 0) optionstr[ctrtransfer-1] = "Transfer image to CTRNAND";
if (hsinject > 0) optionstr[hsinject-1] = "Inject to H&S"; if (hsinject > 0) optionstr[hsinject-1] = "Inject to H&S";
if (xorpad > 0) optionstr[xorpad-1] = "Build XORpads (SD output)"; if (xorpad > 0) optionstr[xorpad-1] = "Build XORpads (SD output)";
if (xorpad_inplace > 0) optionstr[xorpad_inplace-1] = "Build XORpads (inplace)"; if (xorpad_inplace > 0) optionstr[xorpad_inplace-1] = "Build XORpads (inplace)";
@ -1010,9 +1010,22 @@ u32 FileHandlerMenu(char* current_path, u32* cursor, u32* scroll, DirStruct* cur
(InjectHealthAndSafety(curr_entry->path, destdrv[user_select-1]) == 0) ? "success" : "failed"); (InjectHealthAndSafety(curr_entry->path, destdrv[user_select-1]) == 0) ? "success" : "failed");
} }
return 0; return 0;
} else if (user_select == ctradapt) { // -> adapt CTRNAND image to SysNAND } else if (user_select == ctrtransfer) { // -> adapt CTRNAND image to SysNAND
ShowPrompt(false, "%s\n%s", pathstr, char* destdrv[2] = { NULL };
(AdaptCtrNandImage(curr_entry->path) == 0) ? "Image adapted to SysNAND" : "Image modification failed"); n_opt = 0;
if (DriveType("1:")) {
optionstr[n_opt] = "Transfer to SysNAND";
destdrv[n_opt++] = "1:";
}
if (DriveType("4:")) {
optionstr[n_opt] = "Transfer to EmuNAND";
destdrv[n_opt++] = "4:";
}
user_select = (n_opt > 1) ? (int) ShowSelectPrompt(n_opt, optionstr, pathstr) : n_opt;
if (user_select) {
ShowPrompt(false, "%s\nCTRNAND transfer %s", pathstr,
(TransferCtrNandImage(curr_entry->path, destdrv[user_select-1]) == 0) ? "success" : "failed");
}
return 0; return 0;
} else if (user_select == restore) { // -> restore SysNAND (A9LH preserving) } else if (user_select == restore) { // -> restore SysNAND (A9LH preserving)
ShowPrompt(false, "%s\nNAND restore %s", pathstr, ShowPrompt(false, "%s\nNAND restore %s", pathstr,

View File

@ -4,72 +4,71 @@
#include "fsinit.h" #include "fsinit.h"
#include "fsperm.h" #include "fsperm.h"
#include "image.h" #include "image.h"
#include "gameutil.h"
#include "essentials.h" #include "essentials.h"
#include "ui.h" #include "ui.h"
u32 AdaptCtrNandImage(const char* path) {
if (!CheckWritePermissions(path)) return 1;
// a little warning... u32 TransferCtrNandImage(const char* path_img, const char* drv) {
if (!ShowPrompt(true, "This will alter the provided image\nto make it transferable to your NAND.")) if (!CheckWritePermissions(drv)) return 1;
return 1;
// backup current mount path, mount new path // backup current mount path, mount new path
char path_store[256] = { 0 }; char path_store[256] = { 0 };
char* path_bak = NULL; char* path_bak = NULL;
strncpy(path_store, GetMountPath(), 256); strncpy(path_store, GetMountPath(), 256);
if (*path_store) path_bak = path_store; if (*path_store) path_bak = path_store;
if (!InitImgFS(path)) { if (!InitImgFS(path_img)) {
InitImgFS(path_bak); InitImgFS(path_bak);
return 1; return 1;
} }
// fixing CMACs // CTRNAND preparations
ShowString("Fixing .db CMACs, please wait...");
if ((FixFileCmac("7:/dbs/ticket.db") != 0) ||
(FixFileCmac("7:/dbs/certs.db") != 0) ||
(FixFileCmac("7:/dbs/title.db") != 0)) {
ShowPrompt(false, "Error: .db file missing.");
InitImgFS(path_bak);
return 1;
}
FixFileCmac("7:/dbs/import.db");
FixFileCmac("7:/dbs/tmp_t.db");
FixFileCmac("7:/dbs/tmp_i.db");
// cleanup this image
ShowString("Cleaning up image, please wait...");
// special handling for out of region images
SecureInfo* secnfo_img = (SecureInfo*) TEMP_BUFFER; SecureInfo* secnfo_img = (SecureInfo*) TEMP_BUFFER;
SecureInfo* secnfo_loc = (SecureInfo*) (TEMP_BUFFER + 0x200); SecureInfo* secnfo_loc = (SecureInfo*) (TEMP_BUFFER + 0x200);
char* path_secnfo_a = (char*) (TEMP_BUFFER + 0x400);
char* path_secnfo_b = (char*) (TEMP_BUFFER + 0x420);
char* path_secnfo_c = (char*) (TEMP_BUFFER + 0x440);
char* path_tickdb = (char*) (TEMP_BUFFER + 0x460);
char* path_tickdb_bak = (char*) (TEMP_BUFFER + 0x480);
snprintf(path_secnfo_a, 32, "%s/rw/sys/SecureInfo_A", drv);
snprintf(path_secnfo_b, 32, "%s/rw/sys/SecureInfo_B", drv);
snprintf(path_secnfo_c, 32, "%s/rw/sys/SecureInfo_C", drv);
snprintf(path_tickdb, 32, "%s/dbs/ticket.db", drv);
snprintf(path_tickdb_bak, 32, "%s/dbs/ticket.bak", drv);
// special handling for out of region images (create SecureInfo_C)
if (((FileGetData("7:/rw/sys/SecureInfo_A", (u8*) secnfo_img, sizeof(SecureInfo), 0) == sizeof(SecureInfo)) || if (((FileGetData("7:/rw/sys/SecureInfo_A", (u8*) secnfo_img, sizeof(SecureInfo), 0) == sizeof(SecureInfo)) ||
(FileGetData("7:/rw/sys/SecureInfo_B", (u8*) secnfo_img, sizeof(SecureInfo), 0) == sizeof(SecureInfo))) && (FileGetData("7:/rw/sys/SecureInfo_B", (u8*) secnfo_img, sizeof(SecureInfo), 0) == sizeof(SecureInfo))) &&
((FileGetData("1:/rw/sys/SecureInfo_A", (u8*) secnfo_loc, sizeof(SecureInfo), 0) == sizeof(SecureInfo)) || ((FileGetData(path_secnfo_a, (u8*) secnfo_loc, sizeof(SecureInfo), 0) == sizeof(SecureInfo)) ||
(FileGetData("1:/rw/sys/SecureInfo_B", (u8*) secnfo_loc, sizeof(SecureInfo), 0) == sizeof(SecureInfo))) && (FileGetData(path_secnfo_b, (u8*) secnfo_loc, sizeof(SecureInfo), 0) == sizeof(SecureInfo))) &&
(secnfo_img->region != secnfo_loc->region)) { (secnfo_img->region != secnfo_loc->region)) {
secnfo_loc->region = secnfo_img->region; secnfo_loc->region = secnfo_img->region;
FileSetData("1:/rw/sys/SecureInfo_C", (u8*) secnfo_loc, sizeof(SecureInfo), 0, true); FileSetData(path_secnfo_c, (u8*) secnfo_loc, sizeof(SecureInfo), 0, true);
} }
// actual cleanup // make a backup of ticket.db
PathDelete("7:/private/movable.sed"); PathDelete(path_tickdb_bak);
PathDelete("7:/rw/sys/LocalFriendCodeSeed_B"); PathRename(path_tickdb, "ticket.bak");
PathDelete("7:/rw/sys/LocalFriendCodeSeed_A");
PathDelete("7:/rw/sys/SecureInfo_A");
PathDelete("7:/rw/sys/SecureInfo_B");
PathDelete("7:/data");
// inject all required files to image // actual transfer - db files / titles / H&S inject markfile
const char* dbnames[] = { "ticket.db", "certs.db", "title.db", "import.db", "tmp_t.db", "tmp_i.db" };
char path_to[32];
char path_from[32];
char path_dbs[32];
u32 flags = OVERWRITE_ALL; u32 flags = OVERWRITE_ALL;
if (!PathCopy("7:/private", "1:/private/movable.sed", &flags) || snprintf(path_dbs, 32, "%s/dbs", drv);
!(PathCopy("7:/rw/sys", "1:/rw/sys/LocalFriendCodeSeed_B", &flags) || for (u32 i = 0; i < sizeof(dbnames) / sizeof(char*); i++) {
PathCopy("7:/rw/sys", "1:/rw/sys/LocalFriendCodeSeed_A", &flags)) || snprintf(path_to, 32, "%s/dbs/%s", drv, dbnames[i]);
!(PathCopy("7:/rw/sys", "1:/rw/sys/SecureInfo_A", &flags) || snprintf(path_from, 32, "7:/dbs/%s", dbnames[i]);
PathCopy("7:/rw/sys", "1:/rw/sys/SecureInfo_B", &flags))) { PathDelete(path_to);
ShowPrompt(false, "Error: Failed transfering data."); PathCopy(path_dbs, path_from, &flags);
InitImgFS(path_bak); FixFileCmac(path_to);
return 1;
} }
PathCopy("7:", "1:/data", &flags); snprintf(path_to, 32, "%s/" HSINJECT_MARKFILE, drv);
PathDelete(path_to);
ShowString("Cleaning up titles, please wait...");
snprintf(path_to, 32, "%s/title", drv);
snprintf(path_from, 32, "7:/title");
PathDelete(path_to);
PathCopy(drv, path_from, &flags);
InitImgFS(path_bak); InitImgFS(path_bak);
return 0; return 0;

View File

@ -2,4 +2,4 @@
#include "common.h" #include "common.h"
u32 AdaptCtrNandImage(const char* path); u32 TransferCtrNandImage(const char* path_img, const char* drv);