Do things properly

This commit is contained in:
Aurora 2016-11-06 14:45:45 +01:00
parent 1cc64a0fbc
commit 594881c6ce

View File

@ -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);
} }