Better detection routines for H&S injects

This commit is contained in:
d0k3 2017-04-05 02:24:32 +02:00
parent 995f57ab23
commit f856211773
4 changed files with 38 additions and 36 deletions

View File

@ -1545,20 +1545,9 @@ u32 BuildNcchInfoXorpads(const char* destdir, const char* path) {
return ret;
}
u32 CheckHealthAndSafetyInject(const char* hsdrv) {
char path_mrk[32] = { 0 };
snprintf(path_mrk, 32, "%s/%s", hsdrv, HSINJECT_MARKFILE);
return (f_stat(path_mrk, NULL) == FR_OK) ? 0 : 1;
}
u32 InjectHealthAndSafety(const char* path, const char* destdrv) {
u32 GetHealthAndSafetyPaths(const char* drv, char* path_cxi, char* path_bak) {
const u32 tidlow_hs_o3ds[] = { 0x00020300, 0x00021300, 0x00022300, 0, 0x00026300, 0x00027300, 0x00028300 };
const u32 tidlow_hs_n3ds[] = { 0x20020300, 0x20021300, 0x20022300, 0, 0, 0x20027300, 0 };
NcchHeader ncch;
// write permissions
if (!CheckWritePermissions(destdrv))
return 1;
// get H&S title id low
u32 tidlow_hs = 0;
@ -1567,7 +1556,7 @@ u32 InjectHealthAndSafety(const char* path, const char* destdrv) {
u8 secinfo[0x111];
u32 region = 0xFF;
UINT br;
snprintf(path_secinfo, 32, "%s/rw/sys/SecureInfo_%c", destdrv, secchar);
snprintf(path_secinfo, 32, "%s/rw/sys/SecureInfo_%c", drv, secchar);
if ((fvx_qread(path_secinfo, secinfo, 0, 0x111, &br) != FR_OK) ||
(br != 0x111))
continue;
@ -1580,26 +1569,48 @@ u32 InjectHealthAndSafety(const char* path, const char* destdrv) {
if (!tidlow_hs) return 1;
// build paths
char path_cxi[64] = { 0 };
char path_bak[64] = { 0 };
char path_mrk[32] = { 0 };
snprintf(path_mrk, 32, "%s/%s", destdrv, HSINJECT_MARKFILE);
if (path_cxi) *path_cxi = '\0';
if (path_bak) *path_bak = '\0';
for (u32 i = 0; i < 8; i++) { // 8 is an arbitrary number
TitleMetaData* tmd = (TitleMetaData*) TEMP_BUFFER;
TmdContentChunk* chunk = (TmdContentChunk*) (tmd + 1);
char path_tmd[64];
snprintf(path_tmd, 64, "%s/title/00040010/%08lx/content/%08lx.tmd", destdrv, tidlow_hs, i);
snprintf(path_tmd, 64, "%s/title/00040010/%08lx/content/%08lx.tmd", drv, tidlow_hs, i);
if (LoadTmdFile(tmd, path_tmd) != 0) continue;
if (!getbe16(tmd->content_count)) return 1;
snprintf(path_cxi, 64, "%s/title/00040010/%08lx/content/%08lx.app", destdrv, tidlow_hs, getbe32(chunk->id));
snprintf(path_bak, 64, "%s/title/00040010/%08lx/content/%08lx.bak", destdrv, tidlow_hs, getbe32(chunk->id));
if (path_cxi) snprintf(path_cxi, 64, "%s/title/00040010/%08lx/content/%08lx.app", drv, tidlow_hs, getbe32(chunk->id));
if (path_bak) snprintf(path_bak, 64, "%s/title/00040010/%08lx/content/%08lx.bak", drv, tidlow_hs, getbe32(chunk->id));
break;
}
if (!(*path_cxi)) return 1;
return ((path_cxi && !*path_cxi) || (path_bak && !*path_bak)) ? 1 : 0;
}
u32 CheckHealthAndSafetyInject(const char* hsdrv) {
char path_bak[64] = { 0 };
return ((GetHealthAndSafetyPaths(hsdrv, NULL, path_bak) == 0) &&
(f_stat(path_bak, NULL) == FR_OK)) ? 0 : 1;
}
u32 InjectHealthAndSafety(const char* path, const char* destdrv) {
NcchHeader ncch;
// write permissions
if (!CheckWritePermissions(destdrv))
return 1;
// legacy stuff - remove mark file
char path_mrk[32] = { 0 };
snprintf(path_mrk, 32, "%s/%s", destdrv, "__gm9_hsbak.pth");
f_unlink(path_mrk);
// get H&S paths
char path_cxi[64] = { 0 };
char path_bak[64] = { 0 };
if (GetHealthAndSafetyPaths(destdrv, path_cxi, path_bak) != 0) return 1;
if (!path) { // if path == NULL -> restore H&S from backup
if (f_stat(path_bak, NULL) != FR_OK) return 1;
f_unlink(path_mrk);
f_unlink(path_cxi);
f_rename(path_bak, path_cxi);
return 0;
@ -1611,15 +1622,13 @@ u32 InjectHealthAndSafety(const char* path, const char* destdrv) {
return 1;
// check crypto, get sig
u64 tid_hs = ((u64) 0x00040010 << 32) | tidlow_hs;
u16 crypto = NCCH_NOCRYPTO;
u8 sig[0x100];
if ((LoadNcchHeaders(&ncch, NULL, NULL, path_cxi, 0) != 0) ||
(SetupNcchCrypto(&ncch, NCCH_NOCRYPTO) != 0) || !(NCCH_IS_CXI(&ncch)) ||
(ncch.programId != tid_hs) || (ncch.partitionId != tid_hs))
(SetupNcchCrypto(&ncch, NCCH_NOCRYPTO) != 0) || !(NCCH_IS_CXI(&ncch)))
return 1;
crypto = NCCH_GET_CRYPTO(&ncch);
u8 sig[0x100];
memcpy(sig, ncch.signature, 0x100);
u16 crypto = NCCH_GET_CRYPTO(&ncch);
u64 tid_hs = ncch.programId;
// make a backup copy if there is not already one (point of no return)
if (f_stat(path_bak, NULL) != FR_OK) {
@ -1649,9 +1658,6 @@ u32 InjectHealthAndSafety(const char* path, const char* destdrv) {
if (ret != 0) { // in case of failure: try recover
f_unlink(path_cxi);
f_rename(path_bak, path_cxi);
} else { // in case of success: mark this ctrnand as H&S injected
UINT bw;
fvx_qwrite(path_mrk, path_bak, 0, strnlen(path_bak, 63) + 1, &bw);
}
return ret;

View File

@ -2,8 +2,6 @@
#include "common.h"
#define HSINJECT_MARKFILE "__gm9_hsbak.pth"
u32 VerifyGameFile(const char* path);
u32 CheckEncryptedGameFile(const char* path);
u32 CryptGameFile(const char* path, bool inplace, bool encrypt);

View File

@ -55,7 +55,7 @@ u32 GetTwlTitle(char* desc, const TwlIconData* twl_icon) {
u32 GetTwlIcon(u8* icon, const TwlIconData* twl_icon) {
const u32 h = TWLICON_DIM_ICON; // fixed size
const u32 w = TWLICON_DIM_ICON; // fixed size
u16* palette = twl_icon->palette;
const u16* palette = twl_icon->palette;
u8* pix4 = (u8*) twl_icon->icon;
for (u32 y = 0; y < h; y += 8) {
for (u32 x = 0; x < w; x += 8) {

View File

@ -62,8 +62,6 @@ u32 TransferCtrNandImage(const char* path_img, const char* drv) {
PathCopy(path_dbs, path_from, &flags);
FixFileCmac(path_to);
}
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");