PabloMK7 c055fb6f5e
Merge 3GX plugin loader fork (#1916)
This commit adds all the changes made to the 3GX plugin loader fork of Luma3DS. The most important features are:

- Add 3GX plugin loader support. New service added to rosalina: plg:ldr
- Add svcControlProcess, svcControlMemoryUnsafe and improve svcMapProcessMemoryEx (breaking change)
- Allow applications to override certain configurations depending on their needs:
    - Disable core2 thread redirection
    - Disable game patching for the next app
    - Force New 3DS speedup
    - Force next application in a specific memory mode
    - Block the opening of the Rosalina menu
- Add GDB commands to list all process handles and catch all SVC (latter is for IDA Pro as gdb client supports it)
- Other changes necessary for plugins to work properly. Please check changed files in this PR for more details. 

---------

Co-authored-by: PabloMK7 <hackyglitch@gmail.com>
Co-authored-by: Nanquitas <nath.doidi@gmail.com>
Co-authored-by: TuxSH <1922548+TuxSH@users.noreply.github.com>
2023-07-14 20:08:07 +02:00

144 lines
3.8 KiB
C

#include <3ds.h>
#include <assert.h>
#include "memory.h"
#include "patcher.h"
#include "ifile.h"
#include "util.h"
#include "loader.h"
#include "service_manager.h"
#include "3dsx.h"
#include "hbldr.h"
u32 config, multiConfig, bootConfig;
bool isN3DS, isSdMode, nextGamePatchDisabled;
// MAKE SURE fsreg has been init before calling this
static Result fsldrPatchPermissions(void)
{
u32 pid;
Result res = 0;
FS_ProgramInfo info;
ExHeader_Arm11StorageInfo storageInfo = {
.fs_access_info = FSACCESS_NANDRW | FSACCESS_NANDRO_RO | FSACCESS_SDMC_RW,
};
info.programId = 0x0004013000001302LL; // loader PID
info.mediaType = MEDIATYPE_NAND;
TRY(svcGetProcessId(&pid, CUR_PROCESS_HANDLE));
return FSREG_Register(pid, 0xFFFF000000000000LL, &info, &storageInfo);
}
static inline void loadCFWInfo(void)
{
s64 out;
u64 hbldrTid = 0;
bool isLumaWithKext = svcGetSystemInfo(&out, 0x20000, 0) == 1;
if (isLumaWithKext)
{
svcGetSystemInfo(&out, 0x10000, 3);
config = (u32)out;
svcGetSystemInfo(&out, 0x10000, 4);
multiConfig = (u32)out;
svcGetSystemInfo(&out, 0x10000, 5);
bootConfig = (u32)out;
svcGetSystemInfo(&out, 0x10000, 0x100);
hbldrTid = (u64)out;
svcGetSystemInfo(&out, 0x10000, 0x201);
isN3DS = (bool)out;
svcGetSystemInfo(&out, 0x10000, 0x203);
isSdMode = (bool)out;
}
else
{
// Try to support non-Luma or builds where kext is disabled
s64 numKips = 0;
svcGetSystemInfo(&numKips, 26, 0);
if (numKips >= 6)
panic(0xDEADCAFE);
config = 0; // all options 0
multiConfig = 0;
bootConfig = 0;
isN3DS = OS_KernelConfig->app_memtype >= 6;
isSdMode = true;
}
hbldrTid = hbldrTid == 0 ? HBLDR_DEFAULT_3DSX_TID : hbldrTid;
Luma_SharedConfig->hbldr_3dsx_tid = hbldrTid;
Luma_SharedConfig->selected_hbldr_3dsx_tid = hbldrTid;
Luma_SharedConfig->use_hbldr = true;
}
void __ctru_exit(int rc) { (void)rc; } // needed to avoid linking error
// this is called after main exits
void __wrap_exit(int rc)
{
(void)rc;
// Not supposed to terminate... kernel will clean up the handles if it does happen anyway
svcExitProcess();
}
void __sync_init();
void __libc_init_array(void);
// called before main
void initSystem(void)
{
__sync_init();
loadCFWInfo();
Result res;
for(res = 0xD88007FA; res == (Result)0xD88007FA; svcSleepThread(500 * 1000LL))
{
res = srvInit();
if(R_FAILED(res) && res != (Result)0xD88007FA)
panic(res);
}
assertSuccess(fsRegInit());
assertSuccess(fsldrPatchPermissions());
//fsldrInit();
assertSuccess(srvGetServiceHandle(fsGetSessionHandle(), "fs:LDR"));
// Hackjob
assertSuccess(FSUSER_InitializeWithSdkVersion(*fsGetSessionHandle(), 0x70200C8));
assertSuccess(FSUSER_SetPriority(0));
assertSuccess(pxiPmInit());
//__libc_init_array();
}
static const ServiceManagerServiceEntry services[] = {
{ "Loader", 2, loaderHandleCommands, false },
{ "hb:ldr", 2, hbldrHandleCommands, true },
{ NULL },
};
static const ServiceManagerNotificationEntry notifications[] = {
{ 0x000, NULL },
};
static u8 ALIGN(4) staticBufferForHbldr[0x400];
static_assert(ARGVBUF_SIZE > 2 * PATH_MAX, "Wrong 3DSX argv buffer size");
int main(void)
{
nextGamePatchDisabled = false;
// Loader doesn't use any input static buffer, so we should be fine
u32 *sbuf = getThreadStaticBuffers();
sbuf[0] = IPC_Desc_StaticBuffer(sizeof(staticBufferForHbldr), 0);
sbuf[1] = (u32)staticBufferForHbldr;
sbuf[2] = IPC_Desc_StaticBuffer(sizeof(staticBufferForHbldr), 1);
sbuf[3] = (u32)staticBufferForHbldr;
assertSuccess(ServiceManager_Run(services, notifications, NULL));
return 0;
}