From 4e5361f656b4ca3b9416b8adcac2e1f7788bcf55 Mon Sep 17 00:00:00 2001 From: LittleCube Date: Thu, 12 Sep 2024 18:00:24 -0400 Subject: [PATCH 1/6] set plugins' heap memory on load to PRIVATE instead of SHARED --- k11_extension/include/svc/MapProcessMemoryEx.h | 4 ++-- k11_extension/source/svc/MapProcessMemoryEx.c | 13 +++++++++++-- k11_extension/source/svc/wrappers.s | 3 ++- sysmodules/rosalina/include/csvc.h | 3 ++- sysmodules/rosalina/source/csvc.s | 5 ++++- sysmodules/rosalina/source/input_redirection.c | 4 ++-- sysmodules/rosalina/source/menus/process_list.c | 4 ++-- sysmodules/rosalina/source/plugin/file_loader.c | 2 +- sysmodules/rosalina/source/plugin/memoryblock.c | 6 ++++-- sysmodules/rosalina/source/process_patches.c | 2 +- 10 files changed, 31 insertions(+), 15 deletions(-) diff --git a/k11_extension/include/svc/MapProcessMemoryEx.h b/k11_extension/include/svc/MapProcessMemoryEx.h index 0b357afd1..7e3637660 100644 --- a/k11_extension/include/svc/MapProcessMemoryEx.h +++ b/k11_extension/include/svc/MapProcessMemoryEx.h @@ -30,5 +30,5 @@ #include "kernel.h" #include "svc.h" -Result MapProcessMemoryEx(Handle dstProcessHandle, u32 vaDst, Handle srcProcessHandle, u32 vaSrc, u32 size); -Result MapProcessMemoryExWrapper(Handle dstProcessHandle, u32 vaDst, Handle srcProcessHandle, u32 vaSrc, u32 size); +Result MapProcessMemoryEx(Handle dstProcessHandle, u32 vaDst, Handle srcProcessHandle, u32 vaSrc, u32 size, bool shared); +Result MapProcessMemoryExWrapper(Handle dstProcessHandle, u32 vaDst, Handle srcProcessHandle, u32 vaSrc, u32 size, bool shared); diff --git a/k11_extension/source/svc/MapProcessMemoryEx.c b/k11_extension/source/svc/MapProcessMemoryEx.c index 5d0da1674..1bb86e8cd 100644 --- a/k11_extension/source/svc/MapProcessMemoryEx.c +++ b/k11_extension/source/svc/MapProcessMemoryEx.c @@ -26,7 +26,7 @@ #include "svc/MapProcessMemoryEx.h" -Result MapProcessMemoryEx(Handle dstProcessHandle, u32 vaDst, Handle srcProcessHandle, u32 vaSrc, u32 size) +Result MapProcessMemoryEx(Handle dstProcessHandle, u32 vaDst, Handle srcProcessHandle, u32 vaSrc, u32 size, bool shared) { Result res = 0; u32 sizeInPage = size >> 12; @@ -69,7 +69,16 @@ Result MapProcessMemoryEx(Handle dstProcessHandle, u32 vaDst, Handle srcProcess // Check if the destination address is free and large enough res = KProcessHwInfo__CheckVaState(hwInfoOfProcess(dstProcess), vaDst, size, 0, 0); if (res == 0) - res = KProcessHwInfo__MapListOfKBlockInfo(hwInfoOfProcess(dstProcess), vaDst, &list, 0x5806, MEMPERM_RW | 0x18, 0); + { + if (shared) + { + res = KProcessHwInfo__MapListOfKBlockInfo(hwInfoOfProcess(dstProcess), vaDst, &list, 0x5806, MEMPERM_RW | 0x18, 0); + } + else + { + res = KProcessHwInfo__MapListOfKBlockInfo(hwInfoOfProcess(dstProcess), vaDst, &list, 0xBB05, MEMPERM_RW | 0x18, 0); + } + } } KLinkedList_KBlockInfo__Clear(&list); diff --git a/k11_extension/source/svc/wrappers.s b/k11_extension/source/svc/wrappers.s index 6d07ccde8..608cfd990 100644 --- a/k11_extension/source/svc/wrappers.s +++ b/k11_extension/source/svc/wrappers.s @@ -119,7 +119,8 @@ ControlMemoryUnsafeWrapper: .type MapProcessMemoryExWrapper, %function MapProcessMemoryExWrapper: push {lr} + str r5, [sp, #-4]! str r4, [sp, #-4]! bl MapProcessMemoryEx - add sp, #4 + add sp, #8 pop {pc} \ No newline at end of file diff --git a/sysmodules/rosalina/include/csvc.h b/sysmodules/rosalina/include/csvc.h index f6d8ce989..b881408f5 100644 --- a/sysmodules/rosalina/include/csvc.h +++ b/sysmodules/rosalina/include/csvc.h @@ -80,8 +80,9 @@ void svcInvalidateEntireInstructionCache(void); * @param srcProcessHandle Handle of the process to map the memory from (source) * @param srcAddress Start address of the memory block in the source process * @param size Size of the block of the memory to map (truncated to a multiple of 0x1000 bytes) + * @param shared Flag for whether to set the memory's state to SHARED instead of PRIVATE */ -Result svcMapProcessMemoryEx(Handle dstProcessHandle, u32 destAddress, Handle srcProcessHandle, u32 srcAddress, u32 size); +Result svcMapProcessMemoryEx(Handle dstProcessHandle, u32 destAddress, Handle srcProcessHandle, u32 srcAddress, u32 size, bool shared); /** * @brief Unmaps a block of process memory. diff --git a/sysmodules/rosalina/source/csvc.s b/sysmodules/rosalina/source/csvc.s index da6987533..20ef7754f 100644 --- a/sysmodules/rosalina/source/csvc.s +++ b/sysmodules/rosalina/source/csvc.s @@ -59,10 +59,13 @@ SVC_BEGIN svcInvalidateEntireInstructionCache SVC_END SVC_BEGIN svcMapProcessMemoryEx + str r5, [sp, #-4]! str r4, [sp, #-4]! - ldr r4, [sp, #4] + ldr r4, [sp, #8] + ldr r5, [sp, #12] svc 0xA0 ldr r4, [sp], #4 + ldr r5, [sp], #4 bx lr SVC_END diff --git a/sysmodules/rosalina/source/input_redirection.c b/sysmodules/rosalina/source/input_redirection.c index 50037d1bd..2a6aa4eb4 100644 --- a/sysmodules/rosalina/source/input_redirection.c +++ b/sysmodules/rosalina/source/input_redirection.c @@ -223,7 +223,7 @@ static Result InputRedirection_DoUndoIrPatches(Handle processHandle, bool doPatc totalSize = (u32)(textTotalRoundedSize + rodataTotalRoundedSize + dataTotalRoundedSize); svcGetProcessInfo(&startAddress, processHandle, 0x10005); - res = svcMapProcessMemoryEx(CUR_PROCESS_HANDLE, 0x00100000, processHandle, (u32) startAddress, totalSize); + res = svcMapProcessMemoryEx(CUR_PROCESS_HANDLE, 0x00100000, processHandle, (u32) startAddress, totalSize, true); if(R_SUCCEEDED(res) && !patchPrepared) { @@ -356,7 +356,7 @@ static Result InputRedirection_DoUndoHidPatches(Handle processHandle, bool doPat totalSize = (u32)(textTotalRoundedSize + rodataTotalRoundedSize + dataTotalRoundedSize); svcGetProcessInfo(&startAddress, processHandle, 0x10005); - res = svcMapProcessMemoryEx(CUR_PROCESS_HANDLE, 0x00100000, processHandle, (u32) startAddress, totalSize); + res = svcMapProcessMemoryEx(CUR_PROCESS_HANDLE, 0x00100000, processHandle, (u32) startAddress, totalSize, true); if (R_SUCCEEDED(res) && !patchPrepared) { diff --git a/sysmodules/rosalina/source/menus/process_list.c b/sysmodules/rosalina/source/menus/process_list.c index cbe080178..f2007420b 100644 --- a/sysmodules/rosalina/source/menus/process_list.c +++ b/sysmodules/rosalina/source/menus/process_list.c @@ -245,8 +245,8 @@ static void ProcessListMenu_MemoryViewer(const ProcessInfo *info) svcQueryProcessMemory(&mem, &out, processHandle, heapStartAddress); heapTotalSize = mem.size; - Result codeRes = svcMapProcessMemoryEx(CUR_PROCESS_HANDLE, codeDestAddress, processHandle, codeStartAddress, codeTotalSize); - Result heapRes = svcMapProcessMemoryEx(CUR_PROCESS_HANDLE, heapDestAddress, processHandle, heapStartAddress, heapTotalSize); + Result codeRes = svcMapProcessMemoryEx(CUR_PROCESS_HANDLE, codeDestAddress, processHandle, codeStartAddress, codeTotalSize, true); + Result heapRes = svcMapProcessMemoryEx(CUR_PROCESS_HANDLE, heapDestAddress, processHandle, heapStartAddress, heapTotalSize, true); bool codeAvailable = R_SUCCEEDED(codeRes); bool heapAvailable = R_SUCCEEDED(heapRes); diff --git a/sysmodules/rosalina/source/plugin/file_loader.c b/sysmodules/rosalina/source/plugin/file_loader.c index 1a21946fa..f58e770ef 100644 --- a/sysmodules/rosalina/source/plugin/file_loader.c +++ b/sysmodules/rosalina/source/plugin/file_loader.c @@ -292,7 +292,7 @@ bool TryToLoadPlugin(Handle process) extern u32 g_savedGameInstr[2]; - if (R_FAILED((res = svcMapProcessMemoryEx(CUR_PROCESS_HANDLE, procStart, process, procStart, 0x1000)))) + if (R_FAILED((res = svcMapProcessMemoryEx(CUR_PROCESS_HANDLE, procStart, process, procStart, 0x1000, true)))) { ctx->error.message = "Couldn't map process"; ctx->error.code = res; diff --git a/sysmodules/rosalina/source/plugin/memoryblock.c b/sysmodules/rosalina/source/plugin/memoryblock.c index 8738f1efd..c222e3c68 100644 --- a/sysmodules/rosalina/source/plugin/memoryblock.c +++ b/sysmodules/rosalina/source/plugin/memoryblock.c @@ -61,8 +61,10 @@ Result MemoryBlock__IsReady(void) // Then allocate our plugin memory block if (R_SUCCEEDED(res)) + { res = svcControlMemoryUnsafe((u32 *)&memblock->memblock, 0x07000000, g_memBlockSize, MEMOP_REGION_APP | MEMOP_ALLOC | MEMOP_LINEAR_FLAG, MEMPERM_RW); + } // Finally release game reserve block if (R_SUCCEEDED(res)) @@ -209,7 +211,7 @@ Result MemoryBlock__MountInProcess(void) Result res = 0; // Executable - if (R_FAILED((res = svcMapProcessMemoryEx(target, 0x07000000, CUR_PROCESS_HANDLE, (u32)memblock->memblock, header->exeSize)))) + if (R_FAILED((res = svcMapProcessMemoryEx(target, 0x07000000, CUR_PROCESS_HANDLE, (u32) memblock->memblock, header->exeSize, true)))) { error->message = "Couldn't map exe memory block"; error->code = res; @@ -217,7 +219,7 @@ Result MemoryBlock__MountInProcess(void) } // Heap (to be used by the plugin) - if (R_FAILED((res = svcMapProcessMemoryEx(target, header->heapVA, CUR_PROCESS_HANDLE, (u32)memblock->memblock + header->exeSize, header->heapSize)))) + if (R_FAILED((res = svcMapProcessMemoryEx(target, header->heapVA, CUR_PROCESS_HANDLE, (u32) memblock->memblock + header->exeSize, header->heapSize, false)))) { error->message = "Couldn't map heap memory block"; error->code = res; diff --git a/sysmodules/rosalina/source/process_patches.c b/sysmodules/rosalina/source/process_patches.c index e72ecf670..44ef22f42 100644 --- a/sysmodules/rosalina/source/process_patches.c +++ b/sysmodules/rosalina/source/process_patches.c @@ -77,7 +77,7 @@ Result OperateOnProcessByName(const char *name, OperateOnProcessCb func) // NOTE: we suppose .text, .rodata, .data+.bss are contiguous & in that order u32 totalSize = (u32)(textSize + roSize + rwSize); - if (R_FAILED(res = svcMapProcessMemoryEx(CUR_PROCESS_HANDLE, 0x00100000, processHandle, (u32) startAddress, totalSize))) + if (R_FAILED(res = svcMapProcessMemoryEx(CUR_PROCESS_HANDLE, 0x00100000, processHandle, (u32) startAddress, totalSize, true))) { svcCloseHandle(processHandle); return res; From f23ea97f2299a0847a9fcf6806fc592a06c1dd81 Mon Sep 17 00:00:00 2001 From: LittleCube Date: Fri, 13 Sep 2024 02:32:22 +0000 Subject: [PATCH 2/6] workaround 10 MiB heap plugins --- sysmodules/rosalina/source/plugin/memoryblock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sysmodules/rosalina/source/plugin/memoryblock.c b/sysmodules/rosalina/source/plugin/memoryblock.c index c222e3c68..e4e706c50 100644 --- a/sysmodules/rosalina/source/plugin/memoryblock.c +++ b/sysmodules/rosalina/source/plugin/memoryblock.c @@ -219,7 +219,7 @@ Result MemoryBlock__MountInProcess(void) } // Heap (to be used by the plugin) - if (R_FAILED((res = svcMapProcessMemoryEx(target, header->heapVA, CUR_PROCESS_HANDLE, (u32) memblock->memblock + header->exeSize, header->heapSize, false)))) + if (R_FAILED((res = svcMapProcessMemoryEx(target, header->heapVA, CUR_PROCESS_HANDLE, (u32) memblock->memblock + header->exeSize, header->heapSize, (header->heapSize > 0x500000) ? true : false)))) { error->message = "Couldn't map heap memory block"; error->code = res; From 365f6feb9b0ce0f4b502f0354e0a2bb1fd97aba2 Mon Sep 17 00:00:00 2001 From: LittleCube Date: Fri, 13 Sep 2024 06:38:00 +0000 Subject: [PATCH 3/6] ensure heap is freed properly --- sysmodules/rosalina/source/plugin/memoryblock.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sysmodules/rosalina/source/plugin/memoryblock.c b/sysmodules/rosalina/source/plugin/memoryblock.c index e4e706c50..d6bced7b4 100644 --- a/sysmodules/rosalina/source/plugin/memoryblock.c +++ b/sysmodules/rosalina/source/plugin/memoryblock.c @@ -232,10 +232,13 @@ Result MemoryBlock__UnmountFromProcess(void) { Handle target = PluginLoaderCtx.target; PluginHeader *header = &PluginLoaderCtx.header; + MemoryBlock *memblock = &PluginLoaderCtx.memblock; Result res = 0; - res = svcUnmapProcessMemoryEx(target, 0x07000000, header->exeSize); + res = svcMapProcessMemoryEx(target, header->heapVA, CUR_PROCESS_HANDLE, (u32) memblock->memblock + header->exeSize, header->heapSize, true); + + res |= svcUnmapProcessMemoryEx(target, 0x07000000, header->exeSize); res |= svcUnmapProcessMemoryEx(target, header->heapVA, header->heapSize); return res; From 7f9022e14f7e5bfcf3f5feac394edd84ad51ef0d Mon Sep 17 00:00:00 2001 From: LittleCube Date: Fri, 13 Sep 2024 21:17:04 +0000 Subject: [PATCH 4/6] revert to quick syntax --- sysmodules/rosalina/source/plugin/memoryblock.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sysmodules/rosalina/source/plugin/memoryblock.c b/sysmodules/rosalina/source/plugin/memoryblock.c index d6bced7b4..83b2a5f0d 100644 --- a/sysmodules/rosalina/source/plugin/memoryblock.c +++ b/sysmodules/rosalina/source/plugin/memoryblock.c @@ -61,10 +61,8 @@ Result MemoryBlock__IsReady(void) // Then allocate our plugin memory block if (R_SUCCEEDED(res)) - { res = svcControlMemoryUnsafe((u32 *)&memblock->memblock, 0x07000000, g_memBlockSize, MEMOP_REGION_APP | MEMOP_ALLOC | MEMOP_LINEAR_FLAG, MEMPERM_RW); - } // Finally release game reserve block if (R_SUCCEEDED(res)) From 2ae98760666b44eb20c79e6ce812386f888005e3 Mon Sep 17 00:00:00 2001 From: PabloMK7 Date: Fri, 27 Sep 2024 17:58:28 +0200 Subject: [PATCH 5/6] Make the svc changes back compatible and only map private if requested --- k11_extension/include/svc/MapProcessMemoryEx.h | 10 ++++++++-- k11_extension/source/svc/MapProcessMemoryEx.c | 13 ++----------- k11_extension/source/svc/wrappers.s | 3 +++ sysmodules/rosalina/include/csvc.h | 11 +++++++++-- sysmodules/rosalina/include/plugin/3gx.h | 3 ++- sysmodules/rosalina/include/plugin/plgloader.h | 1 + sysmodules/rosalina/source/csvc.s | 12 ++++++------ sysmodules/rosalina/source/input_redirection.c | 4 ++-- sysmodules/rosalina/source/menus/process_list.c | 4 ++-- sysmodules/rosalina/source/plugin/file_loader.c | 3 ++- sysmodules/rosalina/source/plugin/memoryblock.c | 8 +++----- sysmodules/rosalina/source/plugin/plgloader.c | 1 + sysmodules/rosalina/source/process_patches.c | 2 +- 13 files changed, 42 insertions(+), 33 deletions(-) diff --git a/k11_extension/include/svc/MapProcessMemoryEx.h b/k11_extension/include/svc/MapProcessMemoryEx.h index 7e3637660..c97c348a0 100644 --- a/k11_extension/include/svc/MapProcessMemoryEx.h +++ b/k11_extension/include/svc/MapProcessMemoryEx.h @@ -30,5 +30,11 @@ #include "kernel.h" #include "svc.h" -Result MapProcessMemoryEx(Handle dstProcessHandle, u32 vaDst, Handle srcProcessHandle, u32 vaSrc, u32 size, bool shared); -Result MapProcessMemoryExWrapper(Handle dstProcessHandle, u32 vaDst, Handle srcProcessHandle, u32 vaSrc, u32 size, bool shared); +/// Flags for svcMapProcessMemoryEx +typedef enum MapExFlags +{ + MAPEXFLAGS_PRIVATE = BIT(0), ///< Maps the memory as PRIVATE (0xBB05) instead of SHARED (0x5806) +} MapExFlags; + +Result MapProcessMemoryEx(Handle dstProcessHandle, u32 vaDst, Handle srcProcessHandle, u32 vaSrc, u32 size, MapExFlags flags); +Result MapProcessMemoryExWrapper(Handle dstProcessHandle, u32 vaDst, Handle srcProcessHandle, u32 vaSrc, u32 size, MapExFlags flags); diff --git a/k11_extension/source/svc/MapProcessMemoryEx.c b/k11_extension/source/svc/MapProcessMemoryEx.c index 1bb86e8cd..05baf1a96 100644 --- a/k11_extension/source/svc/MapProcessMemoryEx.c +++ b/k11_extension/source/svc/MapProcessMemoryEx.c @@ -26,7 +26,7 @@ #include "svc/MapProcessMemoryEx.h" -Result MapProcessMemoryEx(Handle dstProcessHandle, u32 vaDst, Handle srcProcessHandle, u32 vaSrc, u32 size, bool shared) +Result MapProcessMemoryEx(Handle dstProcessHandle, u32 vaDst, Handle srcProcessHandle, u32 vaSrc, u32 size, MapExFlags flags) { Result res = 0; u32 sizeInPage = size >> 12; @@ -69,16 +69,7 @@ Result MapProcessMemoryEx(Handle dstProcessHandle, u32 vaDst, Handle srcProcess // Check if the destination address is free and large enough res = KProcessHwInfo__CheckVaState(hwInfoOfProcess(dstProcess), vaDst, size, 0, 0); if (res == 0) - { - if (shared) - { - res = KProcessHwInfo__MapListOfKBlockInfo(hwInfoOfProcess(dstProcess), vaDst, &list, 0x5806, MEMPERM_RW | 0x18, 0); - } - else - { - res = KProcessHwInfo__MapListOfKBlockInfo(hwInfoOfProcess(dstProcess), vaDst, &list, 0xBB05, MEMPERM_RW | 0x18, 0); - } - } + res = KProcessHwInfo__MapListOfKBlockInfo(hwInfoOfProcess(dstProcess), vaDst, &list, (flags & MAPEXFLAGS_PRIVATE) ? 0xBB05 : 0x5806, MEMPERM_RW | 0x18, 0); } KLinkedList_KBlockInfo__Clear(&list); diff --git a/k11_extension/source/svc/wrappers.s b/k11_extension/source/svc/wrappers.s index 608cfd990..cefa9684b 100644 --- a/k11_extension/source/svc/wrappers.s +++ b/k11_extension/source/svc/wrappers.s @@ -119,6 +119,9 @@ ControlMemoryUnsafeWrapper: .type MapProcessMemoryExWrapper, %function MapProcessMemoryExWrapper: push {lr} + cmp r0, #0xFFFFFFF2 @ Check magic value, for backwards compatibility + moveq r0, r6 @ If value present, flags present in r5 and dst process in r6, so move dst process back to r0 + movne r5, #0 @ If value not present, clear the flags as its the old version str r5, [sp, #-4]! str r4, [sp, #-4]! bl MapProcessMemoryEx diff --git a/sysmodules/rosalina/include/csvc.h b/sysmodules/rosalina/include/csvc.h index b881408f5..8965a9db4 100644 --- a/sysmodules/rosalina/include/csvc.h +++ b/sysmodules/rosalina/include/csvc.h @@ -73,6 +73,13 @@ void svcInvalidateEntireInstructionCache(void); ///@name Memory management ///@{ + +/// Flags for svcMapProcessMemoryEx +typedef enum MapExFlags +{ + MAPEXFLAGS_PRIVATE = BIT(0), ///< Maps the memory as PRIVATE (0xBB05) instead of SHARED (0x5806) +} MapExFlags; + /** * @brief Maps a block of process memory. * @param dstProcessHandle Handle of the process to map the memory in (destination) @@ -80,9 +87,9 @@ void svcInvalidateEntireInstructionCache(void); * @param srcProcessHandle Handle of the process to map the memory from (source) * @param srcAddress Start address of the memory block in the source process * @param size Size of the block of the memory to map (truncated to a multiple of 0x1000 bytes) - * @param shared Flag for whether to set the memory's state to SHARED instead of PRIVATE + * @param flags Extended flags for mapping the memory (see MapExFlags) */ -Result svcMapProcessMemoryEx(Handle dstProcessHandle, u32 destAddress, Handle srcProcessHandle, u32 srcAddress, u32 size, bool shared); +Result svcMapProcessMemoryEx(Handle dstProcessHandle, u32 destAddress, Handle srcProcessHandle, u32 srcAddress, u32 size, MapExFlags flags); /** * @brief Unmaps a block of process memory. diff --git a/sysmodules/rosalina/include/plugin/3gx.h b/sysmodules/rosalina/include/plugin/3gx.h index 738fa8a65..d14030953 100644 --- a/sysmodules/rosalina/include/plugin/3gx.h +++ b/sysmodules/rosalina/include/plugin/3gx.h @@ -23,7 +23,8 @@ typedef struct CTR_PACKED u32 compatibility : 2; u32 eventsSelfManaged : 1; u32 swapNotNeeded : 1; - u32 unused : 24; + u32 usePrivateMemory : 1; + u32 unused : 23; }; }; u32 exeLoadChecksum; diff --git a/sysmodules/rosalina/include/plugin/plgloader.h b/sysmodules/rosalina/include/plugin/plgloader.h index 2f0b95fdf..7178bf133 100644 --- a/sysmodules/rosalina/include/plugin/plgloader.h +++ b/sysmodules/rosalina/include/plugin/plgloader.h @@ -93,6 +93,7 @@ typedef struct u32 swapLoadChecksum; bool eventsSelfManaged; + bool isMemPrivate; } PluginLoaderContext; extern PluginLoaderContext PluginLoaderCtx; diff --git a/sysmodules/rosalina/source/csvc.s b/sysmodules/rosalina/source/csvc.s index 20ef7754f..3a91db9d0 100644 --- a/sysmodules/rosalina/source/csvc.s +++ b/sysmodules/rosalina/source/csvc.s @@ -59,13 +59,13 @@ SVC_BEGIN svcInvalidateEntireInstructionCache SVC_END SVC_BEGIN svcMapProcessMemoryEx - str r5, [sp, #-4]! - str r4, [sp, #-4]! - ldr r4, [sp, #8] - ldr r5, [sp, #12] + push {r4, r5, r6} + ldr r4, [sp, #12] + ldr r5, [sp, #16] + mov r6, r0 @ Move the dst handle to r6 to make room for magic value + mov r0, #0xFFFFFFF2 @ Set r0 to magic value, which allows for backwards compatibility svc 0xA0 - ldr r4, [sp], #4 - ldr r5, [sp], #4 + pop {r4, r5, r6} bx lr SVC_END diff --git a/sysmodules/rosalina/source/input_redirection.c b/sysmodules/rosalina/source/input_redirection.c index 2a6aa4eb4..60c18213e 100644 --- a/sysmodules/rosalina/source/input_redirection.c +++ b/sysmodules/rosalina/source/input_redirection.c @@ -223,7 +223,7 @@ static Result InputRedirection_DoUndoIrPatches(Handle processHandle, bool doPatc totalSize = (u32)(textTotalRoundedSize + rodataTotalRoundedSize + dataTotalRoundedSize); svcGetProcessInfo(&startAddress, processHandle, 0x10005); - res = svcMapProcessMemoryEx(CUR_PROCESS_HANDLE, 0x00100000, processHandle, (u32) startAddress, totalSize, true); + res = svcMapProcessMemoryEx(CUR_PROCESS_HANDLE, 0x00100000, processHandle, (u32) startAddress, totalSize, 0); if(R_SUCCEEDED(res) && !patchPrepared) { @@ -356,7 +356,7 @@ static Result InputRedirection_DoUndoHidPatches(Handle processHandle, bool doPat totalSize = (u32)(textTotalRoundedSize + rodataTotalRoundedSize + dataTotalRoundedSize); svcGetProcessInfo(&startAddress, processHandle, 0x10005); - res = svcMapProcessMemoryEx(CUR_PROCESS_HANDLE, 0x00100000, processHandle, (u32) startAddress, totalSize, true); + res = svcMapProcessMemoryEx(CUR_PROCESS_HANDLE, 0x00100000, processHandle, (u32) startAddress, totalSize, 0); if (R_SUCCEEDED(res) && !patchPrepared) { diff --git a/sysmodules/rosalina/source/menus/process_list.c b/sysmodules/rosalina/source/menus/process_list.c index f2007420b..de3133161 100644 --- a/sysmodules/rosalina/source/menus/process_list.c +++ b/sysmodules/rosalina/source/menus/process_list.c @@ -245,8 +245,8 @@ static void ProcessListMenu_MemoryViewer(const ProcessInfo *info) svcQueryProcessMemory(&mem, &out, processHandle, heapStartAddress); heapTotalSize = mem.size; - Result codeRes = svcMapProcessMemoryEx(CUR_PROCESS_HANDLE, codeDestAddress, processHandle, codeStartAddress, codeTotalSize, true); - Result heapRes = svcMapProcessMemoryEx(CUR_PROCESS_HANDLE, heapDestAddress, processHandle, heapStartAddress, heapTotalSize, true); + Result codeRes = svcMapProcessMemoryEx(CUR_PROCESS_HANDLE, codeDestAddress, processHandle, codeStartAddress, codeTotalSize, 0); + Result heapRes = svcMapProcessMemoryEx(CUR_PROCESS_HANDLE, heapDestAddress, processHandle, heapStartAddress, heapTotalSize, 0); bool codeAvailable = R_SUCCEEDED(codeRes); bool heapAvailable = R_SUCCEEDED(heapRes); diff --git a/sysmodules/rosalina/source/plugin/file_loader.c b/sysmodules/rosalina/source/plugin/file_loader.c index f58e770ef..6bea9bda6 100644 --- a/sysmodules/rosalina/source/plugin/file_loader.c +++ b/sysmodules/rosalina/source/plugin/file_loader.c @@ -214,6 +214,7 @@ bool TryToLoadPlugin(Handle process) // Flags if (!res) { ctx->eventsSelfManaged = fileHeader.infos.eventsSelfManaged; + ctx->isMemPrivate = fileHeader.infos.usePrivateMemory; if (ctx->pluginMemoryStrategy == PLG_STRATEGY_SWAP && fileHeader.infos.swapNotNeeded) ctx->pluginMemoryStrategy = PLG_STRATEGY_NONE; } @@ -292,7 +293,7 @@ bool TryToLoadPlugin(Handle process) extern u32 g_savedGameInstr[2]; - if (R_FAILED((res = svcMapProcessMemoryEx(CUR_PROCESS_HANDLE, procStart, process, procStart, 0x1000, true)))) + if (R_FAILED((res = svcMapProcessMemoryEx(CUR_PROCESS_HANDLE, procStart, process, procStart, 0x1000, 0)))) { ctx->error.message = "Couldn't map process"; ctx->error.code = res; diff --git a/sysmodules/rosalina/source/plugin/memoryblock.c b/sysmodules/rosalina/source/plugin/memoryblock.c index 83b2a5f0d..07bc576b8 100644 --- a/sysmodules/rosalina/source/plugin/memoryblock.c +++ b/sysmodules/rosalina/source/plugin/memoryblock.c @@ -205,11 +205,12 @@ Result MemoryBlock__MountInProcess(void) Error *error = &PluginLoaderCtx.error; PluginHeader *header = &PluginLoaderCtx.header; MemoryBlock *memblock = &PluginLoaderCtx.memblock; + bool isPrivate = PluginLoaderCtx.isMemPrivate; Result res = 0; // Executable - if (R_FAILED((res = svcMapProcessMemoryEx(target, 0x07000000, CUR_PROCESS_HANDLE, (u32) memblock->memblock, header->exeSize, true)))) + if (R_FAILED((res = svcMapProcessMemoryEx(target, 0x07000000, CUR_PROCESS_HANDLE, (u32) memblock->memblock, header->exeSize, isPrivate ? MAPEXFLAGS_PRIVATE : 0)))) { error->message = "Couldn't map exe memory block"; error->code = res; @@ -217,7 +218,7 @@ Result MemoryBlock__MountInProcess(void) } // Heap (to be used by the plugin) - if (R_FAILED((res = svcMapProcessMemoryEx(target, header->heapVA, CUR_PROCESS_HANDLE, (u32) memblock->memblock + header->exeSize, header->heapSize, (header->heapSize > 0x500000) ? true : false)))) + if (R_FAILED((res = svcMapProcessMemoryEx(target, header->heapVA, CUR_PROCESS_HANDLE, (u32) memblock->memblock + header->exeSize, header->heapSize, isPrivate ? MAPEXFLAGS_PRIVATE : 0)))) { error->message = "Couldn't map heap memory block"; error->code = res; @@ -230,12 +231,9 @@ Result MemoryBlock__UnmountFromProcess(void) { Handle target = PluginLoaderCtx.target; PluginHeader *header = &PluginLoaderCtx.header; - MemoryBlock *memblock = &PluginLoaderCtx.memblock; Result res = 0; - res = svcMapProcessMemoryEx(target, header->heapVA, CUR_PROCESS_HANDLE, (u32) memblock->memblock + header->exeSize, header->heapSize, true); - res |= svcUnmapProcessMemoryEx(target, 0x07000000, header->exeSize); res |= svcUnmapProcessMemoryEx(target, header->heapVA, header->heapSize); diff --git a/sysmodules/rosalina/source/plugin/plgloader.c b/sysmodules/rosalina/source/plugin/plgloader.c index 55e5ec8ff..f3aea9918 100644 --- a/sysmodules/rosalina/source/plugin/plgloader.c +++ b/sysmodules/rosalina/source/plugin/plgloader.c @@ -558,6 +558,7 @@ static void WaitForProcessTerminated(void *arg) ctx->isSwapFunctionset = false; ctx->pluginMemoryStrategy = PLG_STRATEGY_SWAP; ctx->eventsSelfManaged = false; + ctx->isMemPrivate = false; g_blockMenuOpen = 0; MemoryBlock__ResetSwapSettings(); //if (!ctx->userLoadParameters.noIRPatch) diff --git a/sysmodules/rosalina/source/process_patches.c b/sysmodules/rosalina/source/process_patches.c index 44ef22f42..41cf608d6 100644 --- a/sysmodules/rosalina/source/process_patches.c +++ b/sysmodules/rosalina/source/process_patches.c @@ -77,7 +77,7 @@ Result OperateOnProcessByName(const char *name, OperateOnProcessCb func) // NOTE: we suppose .text, .rodata, .data+.bss are contiguous & in that order u32 totalSize = (u32)(textSize + roSize + rwSize); - if (R_FAILED(res = svcMapProcessMemoryEx(CUR_PROCESS_HANDLE, 0x00100000, processHandle, (u32) startAddress, totalSize, true))) + if (R_FAILED(res = svcMapProcessMemoryEx(CUR_PROCESS_HANDLE, 0x00100000, processHandle, (u32) startAddress, totalSize, 0))) { svcCloseHandle(processHandle); return res; From a63dd626e80c878e61da37493327c8f562e37ca0 Mon Sep 17 00:00:00 2001 From: PabloMK7 Date: Fri, 27 Sep 2024 20:31:10 +0200 Subject: [PATCH 6/6] Save r5 in wrapper as old code doesnt save it --- k11_extension/source/svc/wrappers.s | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/k11_extension/source/svc/wrappers.s b/k11_extension/source/svc/wrappers.s index cefa9684b..43652bf7e 100644 --- a/k11_extension/source/svc/wrappers.s +++ b/k11_extension/source/svc/wrappers.s @@ -118,7 +118,7 @@ ControlMemoryUnsafeWrapper: .global MapProcessMemoryExWrapper .type MapProcessMemoryExWrapper, %function MapProcessMemoryExWrapper: - push {lr} + push {r5, lr} @ We need to save r5 because the old implementation doesn't save it cmp r0, #0xFFFFFFF2 @ Check magic value, for backwards compatibility moveq r0, r6 @ If value present, flags present in r5 and dst process in r6, so move dst process back to r0 movne r5, #0 @ If value not present, clear the flags as its the old version @@ -126,4 +126,4 @@ MapProcessMemoryExWrapper: str r4, [sp, #-4]! bl MapProcessMemoryEx add sp, #8 - pop {pc} \ No newline at end of file + pop {r5, pc} \ No newline at end of file