Always patch FS and P9, remove SM service checks
This commit is contained in:
parent
8258a98647
commit
22a8661fe1
@ -31,7 +31,6 @@ enum singleOptions
|
|||||||
PATCHGAMES,
|
PATCHGAMES,
|
||||||
PATCHVERSTRING,
|
PATCHVERSTRING,
|
||||||
SHOWGBABOOT,
|
SHOWGBABOOT,
|
||||||
PATCHACCESS,
|
|
||||||
PATCHUNITINFO,
|
PATCHUNITINFO,
|
||||||
DISABLEARM11EXCHANDLERS
|
DISABLEARM11EXCHANDLERS
|
||||||
};
|
};
|
||||||
|
@ -91,7 +91,6 @@ void configMenu(bool oldPinStatus, u32 oldPinMode)
|
|||||||
"( ) Enable game patching",
|
"( ) Enable game patching",
|
||||||
"( ) Show NAND or user string in System Settings",
|
"( ) Show NAND or user string in System Settings",
|
||||||
"( ) Show GBA boot screen in patched AGB_FIRM",
|
"( ) Show GBA boot screen in patched AGB_FIRM",
|
||||||
"( ) Patch ARM9 access",
|
|
||||||
"( ) Set developer UNITINFO",
|
"( ) Set developer UNITINFO",
|
||||||
"( ) Disable ARM11 exception handlers",
|
"( ) Disable ARM11 exception handlers",
|
||||||
};
|
};
|
||||||
@ -174,10 +173,6 @@ void configMenu(bool oldPinStatus, u32 oldPinMode)
|
|||||||
"Enable showing the GBA boot screen\n"
|
"Enable showing the GBA boot screen\n"
|
||||||
"when booting GBA games.",
|
"when booting GBA games.",
|
||||||
|
|
||||||
"Disable ARM9 exheader access checks.\n\n"
|
|
||||||
"Only select this if you know what you\n"
|
|
||||||
"are doing!",
|
|
||||||
|
|
||||||
"Make the console be always detected\n"
|
"Make the console be always detected\n"
|
||||||
"as a development unit, and conversely.\n"
|
"as a development unit, and conversely.\n"
|
||||||
"(which breaks online features, amiibo\n"
|
"(which breaks online features, amiibo\n"
|
||||||
@ -219,7 +214,6 @@ void configMenu(bool oldPinStatus, u32 oldPinMode)
|
|||||||
{ .visible = true },
|
{ .visible = true },
|
||||||
{ .visible = true },
|
{ .visible = true },
|
||||||
{ .visible = true },
|
{ .visible = true },
|
||||||
{ .visible = true },
|
|
||||||
{ .visible = true }
|
{ .visible = true }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
|
|
||||||
#define CONFIG_FILE "config.bin"
|
#define CONFIG_FILE "config.bin"
|
||||||
#define CONFIG_VERSIONMAJOR 2
|
#define CONFIG_VERSIONMAJOR 2
|
||||||
#define CONFIG_VERSIONMINOR 1
|
#define CONFIG_VERSIONMINOR 2
|
||||||
|
|
||||||
#define BOOTCFG_NAND BOOTCONFIG(0, 7)
|
#define BOOTCFG_NAND BOOTCONFIG(0, 7)
|
||||||
#define BOOTCFG_FIRM BOOTCONFIG(3, 7)
|
#define BOOTCFG_FIRM BOOTCONFIG(3, 7)
|
||||||
@ -58,7 +58,6 @@ enum singleOptions
|
|||||||
PATCHGAMES,
|
PATCHGAMES,
|
||||||
PATCHVERSTRING,
|
PATCHVERSTRING,
|
||||||
SHOWGBABOOT,
|
SHOWGBABOOT,
|
||||||
PATCHACCESS,
|
|
||||||
PATCHUNITINFO,
|
PATCHUNITINFO,
|
||||||
DISABLEARM11EXCHANDLERS
|
DISABLEARM11EXCHANDLERS
|
||||||
};
|
};
|
||||||
|
@ -405,7 +405,7 @@ u32 patchNativeFirm(u32 firmVersion, FirmwareSource nandType, bool loadFromStora
|
|||||||
ret += patchSvcBreak9(arm9Section, kernel9Size, (u32)firm->section[2].address);
|
ret += patchSvcBreak9(arm9Section, kernel9Size, (u32)firm->section[2].address);
|
||||||
ret += patchKernel9Panic(arm9Section, kernel9Size);
|
ret += patchKernel9Panic(arm9Section, kernel9Size);
|
||||||
|
|
||||||
if(CONFIG(PATCHACCESS)) ret += patchP9AccessChecks(process9Offset, process9Size);
|
ret += patchP9AccessChecks(process9Offset, process9Size);
|
||||||
|
|
||||||
mergeSection0(NATIVE_FIRM, firmVersion, loadFromStorage);
|
mergeSection0(NATIVE_FIRM, firmVersion, loadFromStorage);
|
||||||
firm->section[0].size = 0;
|
firm->section[0].size = 0;
|
||||||
|
@ -33,7 +33,6 @@ enum singleOptions
|
|||||||
PATCHGAMES,
|
PATCHGAMES,
|
||||||
PATCHVERSTRING,
|
PATCHVERSTRING,
|
||||||
SHOWGBABOOT,
|
SHOWGBABOOT,
|
||||||
PATCHACCESS,
|
|
||||||
PATCHUNITINFO,
|
PATCHUNITINFO,
|
||||||
DISABLEARM11EXCHANDLERS
|
DISABLEARM11EXCHANDLERS
|
||||||
};
|
};
|
||||||
|
@ -29,7 +29,4 @@
|
|||||||
#include <3ds/types.h>
|
#include <3ds/types.h>
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
|
|
||||||
extern Menu processPatchesMenu;
|
void ProcessPatchesMenu_PatchUnpatchFSDirectly(void);
|
||||||
|
|
||||||
void ProcessPatchesMenu_PatchUnpatchSM(void);
|
|
||||||
void ProcessPatchesMenu_PatchUnpatchFS(void);
|
|
||||||
|
@ -85,6 +85,8 @@ void initSystem()
|
|||||||
|
|
||||||
miscellaneousMenu.items[0].title = HBLDR_3DSX_TID == HBLDR_DEFAULT_3DSX_TID ? "Switch the hb. title to the current app." :
|
miscellaneousMenu.items[0].title = HBLDR_3DSX_TID == HBLDR_DEFAULT_3DSX_TID ? "Switch the hb. title to the current app." :
|
||||||
"Switch the hb. title to hblauncher_loader";
|
"Switch the hb. title to hblauncher_loader";
|
||||||
|
|
||||||
|
ProcessPatchesMenu_PatchUnpatchFSDirectly();
|
||||||
__sync_init();
|
__sync_init();
|
||||||
__appInit();
|
__appInit();
|
||||||
}
|
}
|
||||||
|
@ -40,10 +40,9 @@
|
|||||||
|
|
||||||
Menu rosalinaMenu = {
|
Menu rosalinaMenu = {
|
||||||
"Rosalina menu",
|
"Rosalina menu",
|
||||||
.nbItems = 10,
|
.nbItems = 9,
|
||||||
{
|
{
|
||||||
{ "Process list", METHOD, .method = &RosalinaMenu_ProcessList },
|
{ "Process list", METHOD, .method = &RosalinaMenu_ProcessList },
|
||||||
{ "Process patches menu...", MENU, .menu = &processPatchesMenu },
|
|
||||||
{ "Take screenshot (slow!)", METHOD, .method = &RosalinaMenu_TakeScreenshot },
|
{ "Take screenshot (slow!)", METHOD, .method = &RosalinaMenu_TakeScreenshot },
|
||||||
{ "New 3DS menu...", MENU, .menu = &N3DSMenu },
|
{ "New 3DS menu...", MENU, .menu = &N3DSMenu },
|
||||||
{ "Debugger options...", MENU, .menu = &debuggerMenu },
|
{ "Debugger options...", MENU, .menu = &debuggerMenu },
|
||||||
|
@ -33,44 +33,6 @@
|
|||||||
#include "fmt.h"
|
#include "fmt.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
Menu processPatchesMenu = {
|
|
||||||
"Process patches menu",
|
|
||||||
.nbItems = 2,
|
|
||||||
{
|
|
||||||
{ "Patch SM for the service checks", METHOD, .method = &ProcessPatchesMenu_PatchUnpatchSM },
|
|
||||||
{ "Patch FS for the archive checks", METHOD, .method = &ProcessPatchesMenu_PatchUnpatchFS },
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
static Result ProcessPatchesMenu_DoPatchUnpatchSM(u32 textTotalRoundedSize)
|
|
||||||
{
|
|
||||||
static bool patched = false;
|
|
||||||
static u32 *off;
|
|
||||||
static u32 origData;
|
|
||||||
|
|
||||||
if(patched)
|
|
||||||
{
|
|
||||||
*off = origData;
|
|
||||||
patched = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for(off = (u32 *)0x00100000; off < (u32 *)(0x00100000 + textTotalRoundedSize) - 3 &&
|
|
||||||
(off[0] != 0xE1A01006 || (off[1] & 0xFFFF) != 5);
|
|
||||||
off++);
|
|
||||||
|
|
||||||
if(off >= (u32 *)(0x00100000 + textTotalRoundedSize) - 3)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
off += 2;
|
|
||||||
*off = 0xE3A00001; // mov r0, #1
|
|
||||||
patched = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
processPatchesMenu.items[0].title = patched ? "Unpatch SM for the service checks" : "Patch SM for the service checks";
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Result ProcessPatchesMenu_DoPatchUnpatchFS(u32 textTotalRoundedSize)
|
static Result ProcessPatchesMenu_DoPatchUnpatchFS(u32 textTotalRoundedSize)
|
||||||
{
|
{
|
||||||
static bool patched = false;
|
static bool patched = false;
|
||||||
@ -101,7 +63,7 @@ static Result ProcessPatchesMenu_DoPatchUnpatchFS(u32 textTotalRoundedSize)
|
|||||||
patched = true;
|
patched = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
processPatchesMenu.items[1].title = patched ? "Unpatch FS for the archive checks" : "Patch FS for the archive checks";
|
//processPatchesMenu.items[1].title = patched ? "Unpatch FS for the archive checks" : "Patch FS for the archive checks";
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,35 +114,7 @@ static u32 ProcessPatchesMenu_PatchUnpatchProcessByName(const char *name, Result
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ProcessPatchesMenu_PatchUnpatchProcess(const char *processName, Result (*func)(u32 size))
|
void ProcessPatchesMenu_PatchUnpatchFSDirectly(void)
|
||||||
{
|
{
|
||||||
Draw_Lock();
|
ProcessPatchesMenu_PatchUnpatchProcessByName("fs", &ProcessPatchesMenu_DoPatchUnpatchFS);
|
||||||
Draw_ClearFramebuffer();
|
|
||||||
Draw_FlushFramebuffer();
|
|
||||||
Draw_Unlock();
|
|
||||||
|
|
||||||
Result res = ProcessPatchesMenu_PatchUnpatchProcessByName(processName, func);
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
Draw_Lock();
|
|
||||||
Draw_DrawString(10, 10, COLOR_TITLE, "Process patches menu");
|
|
||||||
if(R_SUCCEEDED(res))
|
|
||||||
Draw_DrawString(10, 30, COLOR_WHITE, "Operation succeeded.");
|
|
||||||
else
|
|
||||||
Draw_DrawFormattedString(10, 30, COLOR_WHITE, "Operation failed (0x%08x).", res);
|
|
||||||
Draw_FlushFramebuffer();
|
|
||||||
Draw_Unlock();
|
|
||||||
}
|
|
||||||
while(!(waitInput() & BUTTON_B) && !terminationRequest);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ProcessPatchesMenu_PatchUnpatchSM(void)
|
|
||||||
{
|
|
||||||
ProcessPatchesMenu_PatchUnpatchProcess("sm", &ProcessPatchesMenu_DoPatchUnpatchSM);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ProcessPatchesMenu_PatchUnpatchFS(void)
|
|
||||||
{
|
|
||||||
ProcessPatchesMenu_PatchUnpatchProcess("fs", &ProcessPatchesMenu_DoPatchUnpatchFS);
|
|
||||||
}
|
}
|
||||||
|
@ -13,13 +13,6 @@ This is part of 3ds_sm, which is licensed under the MIT license (see LICENSE for
|
|||||||
#include "srv_pm.h"
|
#include "srv_pm.h"
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
|
|
||||||
extern u32 __ctru_heap;
|
|
||||||
extern u32 __ctru_linear_heap;
|
|
||||||
extern char (*serviceAccessListBuffers)[34][8];
|
|
||||||
|
|
||||||
u32 __ctru_heap_size = 0x4000;
|
|
||||||
u32 __ctru_linear_heap_size = 0;
|
|
||||||
|
|
||||||
u32 nbSection0Modules;
|
u32 nbSection0Modules;
|
||||||
Handle resumeGetServiceHandleOrPortRegisteredSemaphore;
|
Handle resumeGetServiceHandleOrPortRegisteredSemaphore;
|
||||||
|
|
||||||
@ -43,7 +36,6 @@ void __appInit(void)
|
|||||||
svcGetSystemInfo(&out, 26, 0);
|
svcGetSystemInfo(&out, 26, 0);
|
||||||
nbSection0Modules = out;
|
nbSection0Modules = out;
|
||||||
assertSuccess(svcCreateSemaphore(&resumeGetServiceHandleOrPortRegisteredSemaphore, 0, 64));
|
assertSuccess(svcCreateSemaphore(&resumeGetServiceHandleOrPortRegisteredSemaphore, 0, 64));
|
||||||
serviceAccessListBuffers = (char (*)[34][8])__ctru_heap;
|
|
||||||
|
|
||||||
buildList(&freeSessionDataList, sessionDataPool, sizeof(sessionDataPool) / sizeof(SessionData), sizeof(SessionData));
|
buildList(&freeSessionDataList, sessionDataPool, sizeof(sessionDataPool) / sizeof(SessionData), sizeof(SessionData));
|
||||||
buildList(&freeProcessDataList, processDataPool, sizeof(processDataPool) / sizeof(ProcessData), sizeof(ProcessData));
|
buildList(&freeProcessDataList, processDataPool, sizeof(processDataPool) / sizeof(ProcessData), sizeof(ProcessData));
|
||||||
@ -53,16 +45,7 @@ void __appInit(void)
|
|||||||
// this is called after main exits
|
// this is called after main exits
|
||||||
void __appExit(void){}
|
void __appExit(void){}
|
||||||
|
|
||||||
void __system_allocateHeaps(void)
|
void __system_allocateHeaps(void){}
|
||||||
{
|
|
||||||
u32 tmp = 0;
|
|
||||||
|
|
||||||
// Allocate the application heap
|
|
||||||
__ctru_heap = 0x08000000;
|
|
||||||
svcControlMemory(&tmp, __ctru_heap, 0x0, __ctru_heap_size, MEMOP_ALLOC, MEMPERM_READ | MEMPERM_WRITE);
|
|
||||||
|
|
||||||
__ctru_linear_heap = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void __system_initSyscalls(void){}
|
void __system_initSyscalls(void){}
|
||||||
|
|
||||||
|
@ -10,10 +10,6 @@ This is part of 3ds_sm, which is licensed under the MIT license (see LICENSE for
|
|||||||
#include "services.h"
|
#include "services.h"
|
||||||
|
|
||||||
ProcessDataList processDataInUseList = { NULL, NULL }, freeProcessDataList = { NULL, NULL };
|
ProcessDataList processDataInUseList = { NULL, NULL }, freeProcessDataList = { NULL, NULL };
|
||||||
char (*serviceAccessListBuffers)[34][8];
|
|
||||||
|
|
||||||
// The kernel limits the number of processes to 47 anyways...
|
|
||||||
static u64 freeServiceAccessListBuffersIds = (1ULL << 59) - 1;
|
|
||||||
|
|
||||||
ProcessData *findProcessData(u32 pid)
|
ProcessData *findProcessData(u32 pid)
|
||||||
{
|
{
|
||||||
@ -28,20 +24,10 @@ ProcessData *findProcessData(u32 pid)
|
|||||||
|
|
||||||
ProcessData *doRegisterProcess(u32 pid, char (*serviceAccessList)[8], u32 serviceAccessListSize)
|
ProcessData *doRegisterProcess(u32 pid, char (*serviceAccessList)[8], u32 serviceAccessListSize)
|
||||||
{
|
{
|
||||||
|
(void)serviceAccessList; // Service access list checks removed for Luma3DS, see original 3ds_sm for implementation details.
|
||||||
|
(void)serviceAccessListSize;
|
||||||
|
|
||||||
ProcessData *processData = (ProcessData *)allocateNode(&processDataInUseList, &freeProcessDataList, sizeof(ProcessData), false);
|
ProcessData *processData = (ProcessData *)allocateNode(&processDataInUseList, &freeProcessDataList, sizeof(ProcessData), false);
|
||||||
if(serviceAccessListSize != 0)
|
|
||||||
{
|
|
||||||
s32 bufferId = 63 - __builtin_clzll(freeServiceAccessListBuffersIds);
|
|
||||||
if(bufferId == -1)
|
|
||||||
panic();
|
|
||||||
else
|
|
||||||
{
|
|
||||||
freeServiceAccessListBuffersIds &= ~(1ULL << bufferId);
|
|
||||||
processData->serviceAccessList = serviceAccessListBuffers[bufferId];
|
|
||||||
processData->serviceAccessListSize = serviceAccessListSize;
|
|
||||||
memcpy(processData->serviceAccessList, serviceAccessList, serviceAccessListSize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
assertSuccess(svcCreateSemaphore(&processData->notificationSemaphore, 0, 0x10));
|
assertSuccess(svcCreateSemaphore(&processData->notificationSemaphore, 0, 0x10));
|
||||||
processData->pid = pid;
|
processData->pid = pid;
|
||||||
@ -81,8 +67,6 @@ Result UnregisterProcess(u32 pid)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
freeServiceAccessListBuffersIds |= 1ULL << (u32)((processData->serviceAccessList - serviceAccessListBuffers[0]) / 34);
|
|
||||||
|
|
||||||
moveNode(processData, &freeProcessDataList, false);
|
moveNode(processData, &freeProcessDataList, false);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -38,20 +38,11 @@ static s32 findServicePortByName(bool isNamedPort, const char *name, s32 nameSiz
|
|||||||
|
|
||||||
static bool checkServiceAccess(SessionData *sessionData, const char *name, s32 nameSize)
|
static bool checkServiceAccess(SessionData *sessionData, const char *name, s32 nameSize)
|
||||||
{
|
{
|
||||||
if(sessionData->pid < nbSection0Modules)
|
(void)sessionData;
|
||||||
return true;
|
(void)name;
|
||||||
|
(void)nameSize;
|
||||||
|
|
||||||
ProcessData *processData = findProcessData(sessionData->pid);
|
return true; // Service access list checks removed for Luma3DS, see original 3ds_sm for implementation details.
|
||||||
if(processData == NULL)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
for(u32 i = 0; i < processData->serviceAccessListSize; i++)
|
|
||||||
{
|
|
||||||
if(areServiceNamesEqual(processData->serviceAccessList[i], name, nameSize))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static Result doRegisterServiceOrPort(u32 pid, Handle *serverPort, Handle clientPort, const char *name, s32 nameSize, s32 maxSessions, bool isNamedPort)
|
static Result doRegisterServiceOrPort(u32 pid, Handle *serverPort, Handle clientPort, const char *name, s32 nameSize, s32 maxSessions, bool isNamedPort)
|
||||||
|
Reference in New Issue
Block a user