void initScreens(void) { static bool needToSetup = true; if(needToSetup) { memcpy((void *)ARM11_PARAMETERS_ADDRESS, fbs, sizeof(fbs)); invokeArm11Function(SETUP_FRAMEBUFFERS); if(!ARESCREENSINITIALIZED) { *(vu32 *)ARM11_PARAMETERS_ADDRESS = brightness[MULTICONFIG(BRIGHTNESS)]; invokeArm11Function(INIT_SCREENS); //Turn on backlight i2cWriteRegister(I2C_DEV_MCU, 0x22, 0x2A); } else updateBrightness(MULTICONFIG(BRIGHTNESS)); clearScreens(true); needToSetup = false; } clearScreens(false); swapFramebuffers(false); }
void patchCode(u64 progId, u16 progVer, u8 *code, u32 size) { loadCFWInfo(); if(((progId == 0x0004003000008F02LL || //USA Home Menu progId == 0x0004003000008202LL || //JPN Home Menu progId == 0x0004003000009802LL) //EUR Home Menu && progVer > 4) || (progId == 0x000400300000A902LL //KOR Home Menu && progVer > 0) || progId == 0x000400300000A102LL || //CHN Home Menu progId == 0x000400300000B102LL) //TWN Home Menu { static const u8 pattern[] = { 0x0A, 0x0C, 0x00, 0x10 }, patch[] = { 0x01, 0x00, 0xA0, 0xE3, 0x1E, 0xFF, 0x2F, 0xE1 }; //Patch SMDH region checks if(!patchMemory(code, size, pattern, sizeof(pattern), -31, patch, sizeof(patch), 1 )) goto error; } else if(progId == 0x0004013000003202LL) //FRIENDS { static const u8 pattern[] = { 0x42, 0xE0, 0x1E, 0xFF }; u8 mostRecentFpdVer = 8; u8 *off = memsearch(code, pattern, size, sizeof(pattern)); if(off == NULL) goto error; //Allow online access to work with old friends modules if(off[0xA] < mostRecentFpdVer) off[0xA] = mostRecentFpdVer; } else if((progId == 0x0004001000021000LL || //USA MSET progId == 0x0004001000020000LL || //JPN MSET progId == 0x0004001000022000LL || //EUR MSET progId == 0x0004001000026000LL || //CHN MSET progId == 0x0004001000027000LL || //KOR MSET progId == 0x0004001000028000LL) //TWN MSET && CONFIG(PATCHVERSTRING)) { static const u16 pattern[] = u"Ve"; static u16 *patch; u32 patchSize = 0, currentNand = BOOTCFG_NAND; u16 customVerString[19]; loadCustomVerString(customVerString, &patchSize, currentNand); if(patchSize != 0) patch = customVerString; else { patchSize = 8; u32 currentFirm = BOOTCFG_FIRM; static u16 *verStringsNands[] = { u" Sys", u" Emu", u"Emu2", u"Emu3", u"Emu4" }, *verStringsEmuSys[] = { u"EmuS", u"Em2S", u"Em3S", u"Em4S" }, *verStringsSysEmu[] = { u"SysE", u"SyE2", u"SyE3", u"SyE4" }; patch = (currentFirm != 0) == (currentNand != 0) ? verStringsNands[currentNand] : (!currentNand ? verStringsSysEmu[currentFirm - 1] : verStringsEmuSys[currentNand - 1]); } //Patch Ver. string if(!patchMemory(code, size, pattern, sizeof(pattern) - 2, 0, patch, patchSize, 1 )) goto error; } else if(progId == 0x0004013000008002LL) //NS { if(progVer > 4) { static const u8 pattern[] = { 0x0C, 0x18, 0xE1, 0xD8 }, patch[] = { 0x0B, 0x18, 0x21, 0xC8 }; //Disable updates from foreign carts (makes carts region-free) u32 ret = patchMemory(code, size, pattern, sizeof(pattern), 0, patch, sizeof(patch), 2 ); if(ret == 0 || (ret == 1 && progVer > 0xB)) goto error; } if(LOADERFLAG(ISN3DS)) { u32 cpuSetting = MULTICONFIG(NEWCPU); if(cpuSetting != 0) { static const u8 pattern[] = { 0x0C, 0x00, 0x94, 0x15 }; u32 *off = (u32 *)memsearch(code, pattern, size, sizeof(pattern)); if(off == NULL) goto error; //Patch N3DS CPU Clock and L2 cache setting *(off - 4) = *(off - 3); *(off - 3) = *(off - 1); memcpy(off - 1, off, 16); *(off + 3) = 0xE3800000 | cpuSetting; } } } else if(progId == 0x0004013000001702LL) //CFG { static const u8 pattern[] = { 0x06, 0x46, 0x10, 0x48 }, patch[] = { 0x00, 0x26 }; //Disable SecureInfo signature check if(!patchMemory(code, size, pattern, sizeof(pattern), 0, patch, sizeof(patch), 1 )) goto error; if(secureInfoExists()) { static const u16 pattern[] = u"Sec", patch[] = u"C"; //Use SecureInfo_C if(patchMemory(code, size, pattern, sizeof(pattern) - 2, 22, patch, sizeof(patch) - 2, 2 ) != 2) goto error; } } else if(progId == 0x0004013000003702LL && progVer > 0) //RO { static const u8 pattern[] = { 0x20, 0xA0, 0xE1, 0x8B }, pattern2[] = { 0xE1, 0x30, 0x40, 0x2D }, pattern3[] = { 0x2D, 0xE9, 0x01, 0x70 }, patch[] = { 0x00, 0x00, 0xA0, 0xE3, 0x1E, 0xFF, 0x2F, 0xE1 //mov r0, #0; bx lr }; //Disable CRR0 signature (RSA2048 with SHA256) check and CRO0/CRR0 SHA256 hash checks (section hashes, and hash table) if(!patchMemory(code, size, pattern, sizeof(pattern), -9, patch, sizeof(patch), 1 ) || !patchMemory(code, size, pattern2, sizeof(pattern2), 1, patch, sizeof(patch), 1 ) || !patchMemory(code, size, pattern3, sizeof(pattern3), -2, patch, sizeof(patch), 1 )) goto error; } else if(progId == 0x0004003000008A02LL && MULTICONFIG(DEVOPTIONS) == 1) //ErrDisp { static const u8 pattern[] = { 0x00, 0xD0, 0xE5, 0xDB }, pattern2[] = { 0x14, 0x00, 0xD0, 0xE5, 0x01 }, patch[] = { 0x00, 0x00, 0xA0, 0xE3 }; //Patch UNITINFO checks to make ErrDisp more verbose if(!patchMemory(code, size, pattern, sizeof(pattern), -1, patch, sizeof(patch), 1 ) || patchMemory(code, size, pattern2, sizeof(pattern2), 0, patch, sizeof(patch), 3 ) != 3) goto error; } else if (progId == 0x0004013000003802LL) // ACT Module { antibanPatch(code, size); } if(CONFIG(PATCHGAMES) && (u32)((progId >> 0x20) & 0xFFFFFFEDULL) == 0x00040000) { u8 regionId = 0xFF, languageId; if(!loadTitleCodeSection(progId, code, size) || !loadTitleLocaleConfig(progId, ®ionId, &languageId)) goto error; if(regionId != 0xFF) { u32 CFGUHandleOffset; u8 *CFGU_GetConfigInfoBlk2_endPos = getCfgOffsets(code, size, &CFGUHandleOffset); if(CFGU_GetConfigInfoBlk2_endPos == NULL || !patchCfgGetLanguage(code, size, languageId, CFGU_GetConfigInfoBlk2_endPos)) goto error; patchCfgGetRegion(code, size, regionId, CFGUHandleOffset); } if(!patchRomfsRedirection(progId, code, size)) goto error; } return; error: svcBreak(USERBREAK_ASSERT); while(true); }