Do things properly
This commit is contained in:
parent
1cc64a0fbc
commit
594881c6ce
@ -7,17 +7,15 @@
|
|||||||
|
|
||||||
static CFWInfo info;
|
static CFWInfo info;
|
||||||
|
|
||||||
static void patchMemory(u8 *start, u32 size, const void *pattern, u32 patSize, int offset, const void *replace, u32 repSize, u32 count)
|
static u32 patchMemory(u8 *start, u32 size, const void *pattern, u32 patSize, int offset, const void *replace, u32 repSize, u32 count)
|
||||||
{
|
{
|
||||||
for(u32 i = 0; i < count; i++)
|
u32 i;
|
||||||
|
|
||||||
|
for(i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
u8 *found = memsearch(start, pattern, size, patSize);
|
u8 *found = memsearch(start, pattern, size, patSize);
|
||||||
|
|
||||||
if(found == NULL)
|
if(found == NULL) break;
|
||||||
{
|
|
||||||
if(!i) svcBreak(USERBREAK_ASSERT);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(found + offset, replace, repSize);
|
memcpy(found + offset, replace, repSize);
|
||||||
|
|
||||||
@ -28,6 +26,8 @@ static void patchMemory(u8 *start, u32 size, const void *pattern, u32 patSize, i
|
|||||||
size -= at + patSize;
|
size -= at + patSize;
|
||||||
start = found + patSize;
|
start = found + patSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Result fileOpen(IFile *file, FS_ArchiveID archiveId, const char *path, int flags)
|
static Result fileOpen(IFile *file, FS_ArchiveID archiveId, const char *path, int flags)
|
||||||
@ -327,6 +327,7 @@ static inline void patchCfgGetRegion(u8 *code, u32 size, u8 regionId, u32 CFGUHa
|
|||||||
void patchCode(u64 progId, u16 progVer, u8 *code, u32 size)
|
void patchCode(u64 progId, u16 progVer, u8 *code, u32 size)
|
||||||
{
|
{
|
||||||
loadCFWInfo();
|
loadCFWInfo();
|
||||||
|
u32 res = 0;
|
||||||
|
|
||||||
if(((progId == 0x0004003000008F02LL || //USA Home Menu
|
if(((progId == 0x0004003000008F02LL || //USA Home Menu
|
||||||
progId == 0x0004003000008202LL || //JPN Home Menu
|
progId == 0x0004003000008202LL || //JPN Home Menu
|
||||||
@ -337,36 +338,36 @@ void patchCode(u64 progId, u16 progVer, u8 *code, u32 size)
|
|||||||
progId == 0x000400300000A102LL || //CHN Home Menu
|
progId == 0x000400300000A102LL || //CHN Home Menu
|
||||||
progId == 0x000400300000B102LL) //TWN Home Menu
|
progId == 0x000400300000B102LL) //TWN Home Menu
|
||||||
{
|
{
|
||||||
static const u8 regionFreePattern[] = {
|
static const u8 pattern[] = {
|
||||||
0x0A, 0x0C, 0x00, 0x10
|
0x0A, 0x0C, 0x00, 0x10
|
||||||
},
|
},
|
||||||
regionFreePatch[] = {
|
patch[] = {
|
||||||
0x01, 0x00, 0xA0, 0xE3, 0x1E, 0xFF, 0x2F, 0xE1
|
0x01, 0x00, 0xA0, 0xE3, 0x1E, 0xFF, 0x2F, 0xE1
|
||||||
};
|
};
|
||||||
|
|
||||||
//Patch SMDH region checks
|
//Patch SMDH region checks
|
||||||
patchMemory(code, size,
|
if(!patchMemory(code, size,
|
||||||
regionFreePattern,
|
pattern,
|
||||||
sizeof(regionFreePattern), -31,
|
sizeof(pattern), -31,
|
||||||
regionFreePatch,
|
patch,
|
||||||
sizeof(regionFreePatch), 1
|
sizeof(patch), 1
|
||||||
);
|
)) res++;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if(progId == 0x0004013000003202LL) //FRIENDS
|
else if(progId == 0x0004013000003202LL) //FRIENDS
|
||||||
{
|
{
|
||||||
static const u8 fpdVerPattern[] = {
|
static const u8 pattern[] = {
|
||||||
0x42, 0xE0, 0x1E, 0xFF
|
0x42, 0xE0, 0x1E, 0xFF
|
||||||
};
|
};
|
||||||
|
|
||||||
u8 mostRecentFpdVer = 8;
|
u8 mostRecentFpdVer = 8;
|
||||||
|
|
||||||
u8 *off = memsearch(code, fpdVerPattern, size, sizeof(fpdVerPattern));
|
u8 *off = memsearch(code, pattern, size, sizeof(pattern));
|
||||||
|
|
||||||
if(off == NULL) svcBreak(USERBREAK_ASSERT);
|
if(off == NULL) res++;
|
||||||
|
|
||||||
//Allow online access to work with old friends modules
|
//Allow online access to work with old friends modules
|
||||||
if(off[0xA] < mostRecentFpdVer) off[0xA] = mostRecentFpdVer;
|
else if(off[0xA] < mostRecentFpdVer) off[0xA] = mostRecentFpdVer;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if((progId == 0x0004001000021000LL || //USA MSET
|
else if((progId == 0x0004001000021000LL || //USA MSET
|
||||||
@ -377,18 +378,18 @@ void patchCode(u64 progId, u16 progVer, u8 *code, u32 size)
|
|||||||
progId == 0x0004001000028000LL) //TWN MSET
|
progId == 0x0004001000028000LL) //TWN MSET
|
||||||
&& CONFIG(PATCHVERSTRING))
|
&& CONFIG(PATCHVERSTRING))
|
||||||
{
|
{
|
||||||
static const u16 verPattern[] = u"Ve";
|
static const u16 pattern[] = u"Ve";
|
||||||
static u16 *verString;
|
static u16 *patch;
|
||||||
u32 verStringSize = 0,
|
u32 patchSize = 0,
|
||||||
currentNand = BOOTCFG_NAND;
|
currentNand = BOOTCFG_NAND;
|
||||||
|
|
||||||
u16 customVerString[19];
|
u16 customVerString[19];
|
||||||
loadCustomVerString(customVerString, &verStringSize, currentNand);
|
loadCustomVerString(customVerString, &patchSize, currentNand);
|
||||||
|
|
||||||
if(verStringSize != 0) verString = customVerString;
|
if(patchSize != 0) patch = customVerString;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
verStringSize = 8;
|
patchSize = 8;
|
||||||
u32 currentFirm = BOOTCFG_FIRM;
|
u32 currentFirm = BOOTCFG_FIRM;
|
||||||
|
|
||||||
static u16 *verStringsNands[] = { u" Sys",
|
static u16 *verStringsNands[] = { u" Sys",
|
||||||
@ -407,37 +408,39 @@ void patchCode(u64 progId, u16 progVer, u8 *code, u32 size)
|
|||||||
u"SyE3",
|
u"SyE3",
|
||||||
u"SyE4" };
|
u"SyE4" };
|
||||||
|
|
||||||
verString = (currentFirm != 0) == (currentNand != 0) ? verStringsNands[currentNand] :
|
patch = (currentFirm != 0) == (currentNand != 0) ? verStringsNands[currentNand] :
|
||||||
(!currentNand ? verStringsSysEmu[currentFirm - 1] : verStringsEmuSys[currentNand - 1]);
|
(!currentNand ? verStringsSysEmu[currentFirm - 1] : verStringsEmuSys[currentNand - 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Patch Ver. string
|
//Patch Ver. string
|
||||||
patchMemory(code, size,
|
if(!patchMemory(code, size,
|
||||||
verPattern,
|
pattern,
|
||||||
sizeof(verPattern) - 2, 0,
|
sizeof(pattern) - 2, 0,
|
||||||
verString,
|
patch,
|
||||||
verStringSize, 1
|
patchSize, 1
|
||||||
);
|
)) res++;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if(progId == 0x0004013000008002LL) //NS
|
else if(progId == 0x0004013000008002LL) //NS
|
||||||
{
|
{
|
||||||
if(progVer > 4)
|
if(progVer > 4)
|
||||||
{
|
{
|
||||||
static const u8 stopCartUpdatesPattern[] = {
|
static const u8 pattern[] = {
|
||||||
0x0C, 0x18, 0xE1, 0xD8
|
0x0C, 0x18, 0xE1, 0xD8
|
||||||
},
|
},
|
||||||
stopCartUpdatesPatch[] = {
|
patch[] = {
|
||||||
0x0B, 0x18, 0x21, 0xC8
|
0x0B, 0x18, 0x21, 0xC8
|
||||||
};
|
};
|
||||||
|
|
||||||
//Disable updates from foreign carts (makes carts region-free)
|
//Disable updates from foreign carts (makes carts region-free)
|
||||||
patchMemory(code, size,
|
u32 ret = patchMemory(code, size,
|
||||||
stopCartUpdatesPattern,
|
pattern,
|
||||||
sizeof(stopCartUpdatesPattern), 0,
|
sizeof(pattern), 0,
|
||||||
stopCartUpdatesPatch,
|
patch,
|
||||||
sizeof(stopCartUpdatesPatch), 2
|
sizeof(patch), 2
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if(ret == 0 || (ret == 1 && progVer > 0xB)) res++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(LOADERFLAG(ISN3DS))
|
if(LOADERFLAG(ISN3DS))
|
||||||
@ -452,112 +455,114 @@ void patchCode(u64 progId, u16 progVer, u8 *code, u32 size)
|
|||||||
|
|
||||||
u32 *off = (u32 *)memsearch(code, cfgN3dsCpuPattern, size, sizeof(cfgN3dsCpuPattern));
|
u32 *off = (u32 *)memsearch(code, cfgN3dsCpuPattern, size, sizeof(cfgN3dsCpuPattern));
|
||||||
|
|
||||||
if(off == NULL) svcBreak(USERBREAK_ASSERT);
|
if(off == NULL) res++;
|
||||||
|
else
|
||||||
//Patch N3DS CPU Clock and L2 cache setting
|
{
|
||||||
*(off - 4) = 0xE1A00000;
|
//Patch N3DS CPU Clock and L2 cache setting
|
||||||
*(off + 3) = 0xE3A00000 | cpuSetting;
|
*(off - 4) = 0xE1A00000;
|
||||||
|
*(off + 3) = 0xE3A00000 | cpuSetting;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if(progId == 0x0004013000001702LL) //CFG
|
else if(progId == 0x0004013000001702LL) //CFG
|
||||||
{
|
{
|
||||||
static const u8 secureinfoSigCheckPattern[] = {
|
static const u8 pattern[] = {
|
||||||
0x06, 0x46, 0x10, 0x48
|
0x06, 0x46, 0x10, 0x48
|
||||||
},
|
},
|
||||||
secureinfoSigCheckPatch[] = {
|
patch[] = {
|
||||||
0x00, 0x26
|
0x00, 0x26
|
||||||
};
|
};
|
||||||
|
|
||||||
//Disable SecureInfo signature check
|
//Disable SecureInfo signature check
|
||||||
patchMemory(code, size,
|
if(!patchMemory(code, size,
|
||||||
secureinfoSigCheckPattern,
|
pattern,
|
||||||
sizeof(secureinfoSigCheckPattern), 0,
|
sizeof(pattern), 0,
|
||||||
secureinfoSigCheckPatch,
|
patch,
|
||||||
sizeof(secureinfoSigCheckPatch), 1
|
sizeof(patch), 1
|
||||||
);
|
)) res++;
|
||||||
|
|
||||||
if(secureInfoExists())
|
if(secureInfoExists())
|
||||||
{
|
{
|
||||||
static const u16 secureinfoFilenamePattern[] = u"SecureInfo_",
|
static const u16 pattern[] = u"Sec",
|
||||||
secureinfoFilenamePatch[] = u"C";
|
patch[] = u"C";
|
||||||
|
|
||||||
//Use SecureInfo_C
|
//Use SecureInfo_C
|
||||||
patchMemory(code, size,
|
if(patchMemory(code, size,
|
||||||
secureinfoFilenamePattern,
|
pattern,
|
||||||
sizeof(secureinfoFilenamePattern) - 2,
|
sizeof(pattern) - 2, 22,
|
||||||
sizeof(secureinfoFilenamePattern) - 2,
|
patch,
|
||||||
secureinfoFilenamePatch,
|
sizeof(patch) - 2, 2
|
||||||
sizeof(secureinfoFilenamePatch) - 2, 2
|
) != 2) res++;
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if(progId == 0x0004013000003702LL && progVer > 0) //RO
|
else if(progId == 0x0004013000003702LL && progVer > 0) //RO
|
||||||
{
|
{
|
||||||
static const u8 sigCheckPattern[] = {
|
static const u8 pattern[] = {
|
||||||
0x20, 0xA0, 0xE1, 0x8B
|
0x20, 0xA0, 0xE1, 0x8B
|
||||||
},
|
},
|
||||||
sha256ChecksPattern1[] = {
|
pattern2[] = {
|
||||||
0xE1, 0x30, 0x40, 0x2D
|
0xE1, 0x30, 0x40, 0x2D
|
||||||
},
|
},
|
||||||
sha256ChecksPattern2[] = {
|
pattern3[] = {
|
||||||
0x2D, 0xE9, 0x01, 0x70
|
0x2D, 0xE9, 0x01, 0x70
|
||||||
},
|
},
|
||||||
stub[] = {
|
patch[] = {
|
||||||
0x00, 0x00, 0xA0, 0xE3, 0x1E, 0xFF, 0x2F, 0xE1 //mov r0, #0; bx lr
|
0x00, 0x00, 0xA0, 0xE3, 0x1E, 0xFF, 0x2F, 0xE1 //mov r0, #0; bx lr
|
||||||
};
|
};
|
||||||
|
|
||||||
//Disable CRR0 signature (RSA2048 with SHA256) check
|
//Disable CRR0 signature (RSA2048 with SHA256) check
|
||||||
patchMemory(code, size,
|
if(!patchMemory(code, size,
|
||||||
sigCheckPattern,
|
pattern,
|
||||||
sizeof(sigCheckPattern), -9,
|
sizeof(pattern), -9,
|
||||||
stub,
|
patch,
|
||||||
sizeof(stub), 1
|
sizeof(patch), 1
|
||||||
);
|
)) res++;
|
||||||
|
|
||||||
//Disable CRO0/CRR0 SHA256 hash checks (section hashes, and hash table)
|
//Disable CRO0/CRR0 SHA256 hash checks (section hashes, and hash table)
|
||||||
patchMemory(code, size,
|
if(!patchMemory(code, size,
|
||||||
sha256ChecksPattern1,
|
pattern2,
|
||||||
sizeof(sha256ChecksPattern1), 1,
|
sizeof(pattern2), 1,
|
||||||
stub,
|
patch,
|
||||||
sizeof(stub), 1
|
sizeof(patch), 1
|
||||||
);
|
)) res++;
|
||||||
|
|
||||||
patchMemory(code, size,
|
if(!patchMemory(code, size,
|
||||||
sha256ChecksPattern2,
|
pattern3,
|
||||||
sizeof(sha256ChecksPattern2), -2,
|
sizeof(pattern3), -2,
|
||||||
stub,
|
patch,
|
||||||
sizeof(stub), 1
|
sizeof(patch), 1
|
||||||
);
|
)) res++;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if(progId == 0x0004003000008A02LL && MULTICONFIG(DEVOPTIONS) == 1) //ErrDisp
|
else if(progId == 0x0004003000008A02LL && MULTICONFIG(DEVOPTIONS) == 1) //ErrDisp
|
||||||
{
|
{
|
||||||
static const u8 unitinfoCheckPattern1[] = {
|
static const u8 pattern[] = {
|
||||||
0x00, 0xD0, 0xE5, 0xDB
|
0x00, 0xD0, 0xE5, 0xDB
|
||||||
},
|
},
|
||||||
unitinfoCheckPattern2[] = {
|
pattern2[] = {
|
||||||
0x14, 0x00, 0xD0, 0xE5, 0x01
|
0x14, 0x00, 0xD0, 0xE5, 0x01
|
||||||
},
|
},
|
||||||
unitinfoCheckPatch[] = {
|
patch[] = {
|
||||||
0x00, 0x00, 0xA0, 0xE3
|
0x00, 0x00, 0xA0, 0xE3
|
||||||
};
|
};
|
||||||
|
|
||||||
patchMemory(code, size,
|
//Patch UNITINFO checks to make ErrDisp more verbose
|
||||||
unitinfoCheckPattern1,
|
if(!patchMemory(code, size,
|
||||||
sizeof(unitinfoCheckPattern1), -1,
|
pattern,
|
||||||
unitinfoCheckPatch,
|
sizeof(pattern), -1,
|
||||||
sizeof(unitinfoCheckPatch), 1
|
patch,
|
||||||
);
|
sizeof(patch), 1
|
||||||
|
)) res++;
|
||||||
|
|
||||||
patchMemory(code, size,
|
if(patchMemory(code, size,
|
||||||
unitinfoCheckPattern2,
|
pattern2,
|
||||||
sizeof(unitinfoCheckPattern2), 0,
|
sizeof(pattern2), 0,
|
||||||
unitinfoCheckPatch,
|
patch,
|
||||||
sizeof(unitinfoCheckPatch), 3
|
sizeof(patch), 3
|
||||||
);
|
) != 3) res++;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if(CONFIG(USELANGEMUANDCODE) && (u32)((progId & 0xFFFFFFF000000000LL) >> 0x24) == 0x0004000)
|
else if(CONFIG(USELANGEMUANDCODE) && (u32)((progId & 0xFFFFFFF000000000LL) >> 0x24) == 0x0004000)
|
||||||
@ -575,11 +580,14 @@ void patchCode(u64 progId, u16 progVer, u8 *code, u32 size)
|
|||||||
u32 CFGUHandleOffset;
|
u32 CFGUHandleOffset;
|
||||||
u8 *CFGU_GetConfigInfoBlk2_endPos = getCfgOffsets(code, size, &CFGUHandleOffset);
|
u8 *CFGU_GetConfigInfoBlk2_endPos = getCfgOffsets(code, size, &CFGUHandleOffset);
|
||||||
|
|
||||||
if(CFGU_GetConfigInfoBlk2_endPos != NULL)
|
if(CFGU_GetConfigInfoBlk2_endPos == NULL) res++;
|
||||||
|
else
|
||||||
{
|
{
|
||||||
if(languageId != 0xFF) patchCfgGetLanguage(code, size, languageId, CFGU_GetConfigInfoBlk2_endPos);
|
if(languageId != 0xFF) patchCfgGetLanguage(code, size, languageId, CFGU_GetConfigInfoBlk2_endPos);
|
||||||
if(regionId != 0xFF) patchCfgGetRegion(code, size, regionId, CFGUHandleOffset);
|
if(regionId != 0xFF) patchCfgGetRegion(code, size, regionId, CFGUHandleOffset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(res != 0) svcBreak(USERBREAK_ASSERT);
|
||||||
}
|
}
|
Reference in New Issue
Block a user