forked from Mirror/GodMode9
Better detection routines for H&S injects
This commit is contained in:
parent
995f57ab23
commit
f856211773
@ -1545,20 +1545,9 @@ u32 BuildNcchInfoXorpads(const char* destdir, const char* path) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 CheckHealthAndSafetyInject(const char* hsdrv) {
|
u32 GetHealthAndSafetyPaths(const char* drv, char* path_cxi, char* path_bak) {
|
||||||
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) {
|
|
||||||
const u32 tidlow_hs_o3ds[] = { 0x00020300, 0x00021300, 0x00022300, 0, 0x00026300, 0x00027300, 0x00028300 };
|
const u32 tidlow_hs_o3ds[] = { 0x00020300, 0x00021300, 0x00022300, 0, 0x00026300, 0x00027300, 0x00028300 };
|
||||||
const u32 tidlow_hs_n3ds[] = { 0x20020300, 0x20021300, 0x20022300, 0, 0, 0x20027300, 0 };
|
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
|
// get H&S title id low
|
||||||
u32 tidlow_hs = 0;
|
u32 tidlow_hs = 0;
|
||||||
@ -1567,7 +1556,7 @@ u32 InjectHealthAndSafety(const char* path, const char* destdrv) {
|
|||||||
u8 secinfo[0x111];
|
u8 secinfo[0x111];
|
||||||
u32 region = 0xFF;
|
u32 region = 0xFF;
|
||||||
UINT br;
|
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) ||
|
if ((fvx_qread(path_secinfo, secinfo, 0, 0x111, &br) != FR_OK) ||
|
||||||
(br != 0x111))
|
(br != 0x111))
|
||||||
continue;
|
continue;
|
||||||
@ -1580,26 +1569,48 @@ u32 InjectHealthAndSafety(const char* path, const char* destdrv) {
|
|||||||
if (!tidlow_hs) return 1;
|
if (!tidlow_hs) return 1;
|
||||||
|
|
||||||
// build paths
|
// build paths
|
||||||
char path_cxi[64] = { 0 };
|
if (path_cxi) *path_cxi = '\0';
|
||||||
char path_bak[64] = { 0 };
|
if (path_bak) *path_bak = '\0';
|
||||||
char path_mrk[32] = { 0 };
|
|
||||||
snprintf(path_mrk, 32, "%s/%s", destdrv, HSINJECT_MARKFILE);
|
|
||||||
for (u32 i = 0; i < 8; i++) { // 8 is an arbitrary number
|
for (u32 i = 0; i < 8; i++) { // 8 is an arbitrary number
|
||||||
TitleMetaData* tmd = (TitleMetaData*) TEMP_BUFFER;
|
TitleMetaData* tmd = (TitleMetaData*) TEMP_BUFFER;
|
||||||
TmdContentChunk* chunk = (TmdContentChunk*) (tmd + 1);
|
TmdContentChunk* chunk = (TmdContentChunk*) (tmd + 1);
|
||||||
char path_tmd[64];
|
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 (LoadTmdFile(tmd, path_tmd) != 0) continue;
|
||||||
if (!getbe16(tmd->content_count)) return 1;
|
if (!getbe16(tmd->content_count)) return 1;
|
||||||
snprintf(path_cxi, 64, "%s/title/00040010/%08lx/content/%08lx.app", 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));
|
||||||
snprintf(path_bak, 64, "%s/title/00040010/%08lx/content/%08lx.bak", destdrv, 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;
|
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 (!path) { // if path == NULL -> restore H&S from backup
|
||||||
if (f_stat(path_bak, NULL) != FR_OK) return 1;
|
if (f_stat(path_bak, NULL) != FR_OK) return 1;
|
||||||
f_unlink(path_mrk);
|
|
||||||
f_unlink(path_cxi);
|
f_unlink(path_cxi);
|
||||||
f_rename(path_bak, path_cxi);
|
f_rename(path_bak, path_cxi);
|
||||||
return 0;
|
return 0;
|
||||||
@ -1611,15 +1622,13 @@ u32 InjectHealthAndSafety(const char* path, const char* destdrv) {
|
|||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
// check crypto, get sig
|
// 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) ||
|
if ((LoadNcchHeaders(&ncch, NULL, NULL, path_cxi, 0) != 0) ||
|
||||||
(SetupNcchCrypto(&ncch, NCCH_NOCRYPTO) != 0) || !(NCCH_IS_CXI(&ncch)) ||
|
(SetupNcchCrypto(&ncch, NCCH_NOCRYPTO) != 0) || !(NCCH_IS_CXI(&ncch)))
|
||||||
(ncch.programId != tid_hs) || (ncch.partitionId != tid_hs))
|
|
||||||
return 1;
|
return 1;
|
||||||
crypto = NCCH_GET_CRYPTO(&ncch);
|
u8 sig[0x100];
|
||||||
memcpy(sig, ncch.signature, 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)
|
// make a backup copy if there is not already one (point of no return)
|
||||||
if (f_stat(path_bak, NULL) != FR_OK) {
|
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
|
if (ret != 0) { // in case of failure: try recover
|
||||||
f_unlink(path_cxi);
|
f_unlink(path_cxi);
|
||||||
f_rename(path_bak, 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;
|
return ret;
|
||||||
|
@ -2,8 +2,6 @@
|
|||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
#define HSINJECT_MARKFILE "__gm9_hsbak.pth"
|
|
||||||
|
|
||||||
u32 VerifyGameFile(const char* path);
|
u32 VerifyGameFile(const char* path);
|
||||||
u32 CheckEncryptedGameFile(const char* path);
|
u32 CheckEncryptedGameFile(const char* path);
|
||||||
u32 CryptGameFile(const char* path, bool inplace, bool encrypt);
|
u32 CryptGameFile(const char* path, bool inplace, bool encrypt);
|
||||||
|
@ -55,7 +55,7 @@ u32 GetTwlTitle(char* desc, const TwlIconData* twl_icon) {
|
|||||||
u32 GetTwlIcon(u8* icon, const TwlIconData* twl_icon) {
|
u32 GetTwlIcon(u8* icon, const TwlIconData* twl_icon) {
|
||||||
const u32 h = TWLICON_DIM_ICON; // fixed size
|
const u32 h = TWLICON_DIM_ICON; // fixed size
|
||||||
const u32 w = 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;
|
u8* pix4 = (u8*) twl_icon->icon;
|
||||||
for (u32 y = 0; y < h; y += 8) {
|
for (u32 y = 0; y < h; y += 8) {
|
||||||
for (u32 x = 0; x < w; x += 8) {
|
for (u32 x = 0; x < w; x += 8) {
|
||||||
|
@ -62,8 +62,6 @@ u32 TransferCtrNandImage(const char* path_img, const char* drv) {
|
|||||||
PathCopy(path_dbs, path_from, &flags);
|
PathCopy(path_dbs, path_from, &flags);
|
||||||
FixFileCmac(path_to);
|
FixFileCmac(path_to);
|
||||||
}
|
}
|
||||||
snprintf(path_to, 32, "%s/" HSINJECT_MARKFILE, drv);
|
|
||||||
PathDelete(path_to);
|
|
||||||
ShowString("Cleaning up titles, please wait...");
|
ShowString("Cleaning up titles, please wait...");
|
||||||
snprintf(path_to, 32, "%s/title", drv);
|
snprintf(path_to, 32, "%s/title", drv);
|
||||||
snprintf(path_from, 32, "7:/title");
|
snprintf(path_from, 32, "7:/title");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user