From 3e9c58e29535fba776be35d6cb6d18e7dd5cf478 Mon Sep 17 00:00:00 2001 From: LittleCube Date: Thu, 12 Sep 2024 18:00:24 -0400 Subject: [PATCH 1/7] 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 c6c1e3d493045de63dc7b00b55f220ce34575ade Mon Sep 17 00:00:00 2001 From: LittleCube Date: Fri, 13 Sep 2024 02:32:22 +0000 Subject: [PATCH 2/7] 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 bfe60beb4167203650b2b21d3f1fa9ef30bce7b6 Mon Sep 17 00:00:00 2001 From: LittleCube Date: Fri, 13 Sep 2024 06:38:00 +0000 Subject: [PATCH 3/7] 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 7a244d0471acd85d1d09fd44d59f104731b09b79 Mon Sep 17 00:00:00 2001 From: LittleCube Date: Fri, 13 Sep 2024 21:17:04 +0000 Subject: [PATCH 4/7] 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 118bb4a3a8769428641cbb649690d5e518eff6eb Mon Sep 17 00:00:00 2001 From: LittleCube Date: Fri, 13 Sep 2024 22:23:14 +0000 Subject: [PATCH 5/7] implement using a new svc instead of breaking an old one --- k11_extension/include/svc/MapPluginMemory.h | 34 ++++++++ .../include/svc/MapProcessMemoryEx.h | 4 +- k11_extension/source/svc.c | 2 + k11_extension/source/svc/MapPluginMemory.c | 86 +++++++++++++++++++ k11_extension/source/svc/MapProcessMemoryEx.c | 13 +-- k11_extension/source/svc/wrappers.s | 12 ++- sysmodules/rosalina/include/csvc.h | 13 ++- sysmodules/rosalina/source/csvc.s | 13 ++- .../rosalina/source/input_redirection.c | 4 +- .../rosalina/source/menus/process_list.c | 4 +- .../rosalina/source/plugin/file_loader.c | 2 +- .../rosalina/source/plugin/memoryblock.c | 15 +++- sysmodules/rosalina/source/process_patches.c | 2 +- 13 files changed, 174 insertions(+), 30 deletions(-) create mode 100644 k11_extension/include/svc/MapPluginMemory.h create mode 100644 k11_extension/source/svc/MapPluginMemory.c diff --git a/k11_extension/include/svc/MapPluginMemory.h b/k11_extension/include/svc/MapPluginMemory.h new file mode 100644 index 000000000..7dff31cdd --- /dev/null +++ b/k11_extension/include/svc/MapPluginMemory.h @@ -0,0 +1,34 @@ +/* +* This file is part of Luma3DS +* Copyright (C) 2016-2020 Aurora Wright, TuxSH +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +* +* Additional Terms 7.b and 7.c of GPLv3 apply to this file: +* * Requiring preservation of specified reasonable legal notices or +* author attributions in that material or in the Appropriate Legal +* Notices displayed by works containing it. +* * Prohibiting misrepresentation of the origin of that material, +* or requiring that modified versions of such material be marked in +* reasonable ways as different from the original version. +*/ + +#pragma once + +#include "utils.h" +#include "kernel.h" +#include "svc.h" + +Result MapPluginMemory(Handle dstProcessHandle, u32 vaDst, Handle srcProcessHandle, u32 vaSrc, u32 size); +Result MapPluginMemoryWrapper(Handle dstProcessHandle, u32 vaDst, Handle srcProcessHandle, u32 vaSrc, u32 size); diff --git a/k11_extension/include/svc/MapProcessMemoryEx.h b/k11_extension/include/svc/MapProcessMemoryEx.h index 7e3637660..0b357afd1 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, bool shared); -Result MapProcessMemoryExWrapper(Handle dstProcessHandle, u32 vaDst, Handle srcProcessHandle, u32 vaSrc, u32 size, bool shared); +Result MapProcessMemoryEx(Handle dstProcessHandle, u32 vaDst, Handle srcProcessHandle, u32 vaSrc, u32 size); +Result MapProcessMemoryExWrapper(Handle dstProcessHandle, u32 vaDst, Handle srcProcessHandle, u32 vaSrc, u32 size); diff --git a/k11_extension/source/svc.c b/k11_extension/source/svc.c index dceb1eeab..27fca3163 100644 --- a/k11_extension/source/svc.c +++ b/k11_extension/source/svc.c @@ -42,6 +42,7 @@ #include "svc/KernelSetState.h" #include "svc/CustomBackdoor.h" #include "svc/MapProcessMemoryEx.h" +#include "svc/MapPluginMemory.h" #include "svc/UnmapProcessMemoryEx.h" #include "svc/ControlService.h" #include "svc/ControlProcess.h" @@ -98,6 +99,7 @@ void buildAlteredSvcTable(void) alteredSvcTable[0xA1] = UnmapProcessMemoryEx; alteredSvcTable[0xA2] = ControlMemoryEx; alteredSvcTable[0xA3] = ControlMemoryUnsafeWrapper; + alteredSvcTable[0xA4] = MapPluginMemoryWrapper; alteredSvcTable[0xB0] = ControlService; alteredSvcTable[0xB1] = CopyHandleWrapper; diff --git a/k11_extension/source/svc/MapPluginMemory.c b/k11_extension/source/svc/MapPluginMemory.c new file mode 100644 index 000000000..65c74a915 --- /dev/null +++ b/k11_extension/source/svc/MapPluginMemory.c @@ -0,0 +1,86 @@ +/* +* This file is part of Luma3DS +* Copyright (C) 2016-2020 Aurora Wright, TuxSH +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +* +* Additional Terms 7.b and 7.c of GPLv3 apply to this file: +* * Requiring preservation of specified reasonable legal notices or +* author attributions in that material or in the Appropriate Legal +* Notices displayed by works containing it. +* * Prohibiting misrepresentation of the origin of that material, +* or requiring that modified versions of such material be marked in +* reasonable ways as different from the original version. +*/ + +#include "svc/MapPluginMemory.h" + +Result MapPluginMemory(Handle dstProcessHandle, u32 vaDst, Handle srcProcessHandle, u32 vaSrc, u32 size) +{ + Result res = 0; + u32 sizeInPage = size >> 12; + KLinkedList list; + KProcess *srcProcess; + KProcess *dstProcess; + KProcessHandleTable *handleTable = handleTableOfProcess(currentCoreContext->objectContext.currentProcess); + + if (dstProcessHandle == CUR_PROCESS_HANDLE) + { + dstProcess = currentCoreContext->objectContext.currentProcess; + KAutoObject__AddReference((KAutoObject *)dstProcess); + } + else + dstProcess = KProcessHandleTable__ToKProcess(handleTable, dstProcessHandle); + + if (dstProcess == NULL) + return 0xD8E007F7; + + if (srcProcessHandle == CUR_PROCESS_HANDLE) + { + srcProcess = currentCoreContext->objectContext.currentProcess; + KAutoObject__AddReference((KAutoObject *)srcProcess); + } + else + srcProcess = KProcessHandleTable__ToKProcess(handleTable, srcProcessHandle); + + if (srcProcess == NULL) + { + res = 0xD8E007F7; + goto exit1; + } + + KLinkedList__Initialize(&list); + + res = KProcessHwInfo__GetListOfKBlockInfoForVA(hwInfoOfProcess(srcProcess), &list, vaSrc, sizeInPage); + + if (res >= 0) + { + // 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, 0xBB05, MEMPERM_RW | 0x18, 0); + } + + KLinkedList_KBlockInfo__Clear(&list); + + ((KAutoObject *)srcProcess)->vtable->DecrementReferenceCount((KAutoObject *)srcProcess); + +exit1: + ((KAutoObject *)dstProcess)->vtable->DecrementReferenceCount((KAutoObject *)dstProcess); + + invalidateEntireInstructionCache(); + flushEntireDataCache(); + + return res; +} diff --git a/k11_extension/source/svc/MapProcessMemoryEx.c b/k11_extension/source/svc/MapProcessMemoryEx.c index 1bb86e8cd..5d0da1674 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) { 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, 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..a2d8a1536 100644 --- a/k11_extension/source/svc/wrappers.s +++ b/k11_extension/source/svc/wrappers.s @@ -119,8 +119,16 @@ ControlMemoryUnsafeWrapper: .type MapProcessMemoryExWrapper, %function MapProcessMemoryExWrapper: push {lr} - str r5, [sp, #-4]! str r4, [sp, #-4]! bl MapProcessMemoryEx - add sp, #8 + add sp, #4 + pop {pc} + +.global MapPluginMemoryWrapper +.type MapPluginMemoryWrapper, %function +MapPluginMemoryWrapper: + push {lr} + str r4, [sp, #-4]! + bl MapPluginMemory + add sp, #4 pop {pc} \ No newline at end of file diff --git a/sysmodules/rosalina/include/csvc.h b/sysmodules/rosalina/include/csvc.h index b881408f5..88f0dbd10 100644 --- a/sysmodules/rosalina/include/csvc.h +++ b/sysmodules/rosalina/include/csvc.h @@ -80,9 +80,18 @@ 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, bool shared); +Result svcMapProcessMemoryEx(Handle dstProcessHandle, u32 destAddress, Handle srcProcessHandle, u32 srcAddress, u32 size); + +/** + * @brief Maps a block of plugin memory (sets MemState to PRIVATE instead of SHARED). + * @param dstProcessHandle Handle of the process to map the memory in (destination) + * @param destAddress Start address of the memory block in the destination process + * @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) +*/ +Result svcMapPluginMemory(Handle dstProcessHandle, u32 destAddress, Handle srcProcessHandle, u32 srcAddress, u32 size); /** * @brief Unmaps a block of process memory. diff --git a/sysmodules/rosalina/source/csvc.s b/sysmodules/rosalina/source/csvc.s index 20ef7754f..81becf060 100644 --- a/sysmodules/rosalina/source/csvc.s +++ b/sysmodules/rosalina/source/csvc.s @@ -59,13 +59,10 @@ SVC_BEGIN svcInvalidateEntireInstructionCache SVC_END SVC_BEGIN svcMapProcessMemoryEx - str r5, [sp, #-4]! str r4, [sp, #-4]! - ldr r4, [sp, #8] - ldr r5, [sp, #12] + ldr r4, [sp, #4] svc 0xA0 ldr r4, [sp], #4 - ldr r5, [sp], #4 bx lr SVC_END @@ -98,6 +95,14 @@ SVC_BEGIN svcFreeMemory bx lr SVC_END +SVC_BEGIN svcMapPluginMemory + str r4, [sp, #-4]! + ldr r4, [sp, #4] + svc 0xA4 + ldr r4, [sp], #4 + bx lr +SVC_END + SVC_BEGIN svcControlService svc 0xB0 bx lr diff --git a/sysmodules/rosalina/source/input_redirection.c b/sysmodules/rosalina/source/input_redirection.c index 2a6aa4eb4..50037d1bd 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); 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); 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..cbe080178 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); + Result heapRes = svcMapProcessMemoryEx(CUR_PROCESS_HANDLE, heapDestAddress, processHandle, heapStartAddress, heapTotalSize); 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..1a21946fa 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, true)))) + if (R_FAILED((res = svcMapProcessMemoryEx(CUR_PROCESS_HANDLE, procStart, process, procStart, 0x1000)))) { 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..24e86ff93 100644 --- a/sysmodules/rosalina/source/plugin/memoryblock.c +++ b/sysmodules/rosalina/source/plugin/memoryblock.c @@ -209,7 +209,7 @@ Result MemoryBlock__MountInProcess(void) 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)))) { error->message = "Couldn't map exe memory block"; error->code = res; @@ -217,7 +217,16 @@ 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 (header->heapSize > 0x500000) + { + res = svcMapProcessMemoryEx(target, header->heapVA, CUR_PROCESS_HANDLE, (u32) memblock->memblock + header->exeSize, header->heapSize); + } + else + { + res = svcMapPluginMemory(target, header->heapVA, CUR_PROCESS_HANDLE, (u32) memblock->memblock + header->exeSize, header->heapSize); + } + + if (R_FAILED(res)) { error->message = "Couldn't map heap memory block"; error->code = res; @@ -234,7 +243,7 @@ Result MemoryBlock__UnmountFromProcess(void) Result res = 0; - res = svcMapProcessMemoryEx(target, header->heapVA, CUR_PROCESS_HANDLE, (u32) memblock->memblock + header->exeSize, header->heapSize, true); + res = svcMapProcessMemoryEx(target, header->heapVA, CUR_PROCESS_HANDLE, (u32) memblock->memblock + header->exeSize, header->heapSize); res |= svcUnmapProcessMemoryEx(target, 0x07000000, header->exeSize); res |= svcUnmapProcessMemoryEx(target, header->heapVA, header->heapSize); diff --git a/sysmodules/rosalina/source/process_patches.c b/sysmodules/rosalina/source/process_patches.c index 44ef22f42..e72ecf670 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))) { svcCloseHandle(processHandle); return res; From 01b258b8ca0133711325825892f45ce6a5b6c703 Mon Sep 17 00:00:00 2001 From: LittleCube Date: Fri, 13 Sep 2024 22:51:08 +0000 Subject: [PATCH 6/7] revert whitespace --- sysmodules/rosalina/source/plugin/memoryblock.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sysmodules/rosalina/source/plugin/memoryblock.c b/sysmodules/rosalina/source/plugin/memoryblock.c index 24e86ff93..c648e364e 100644 --- a/sysmodules/rosalina/source/plugin/memoryblock.c +++ b/sysmodules/rosalina/source/plugin/memoryblock.c @@ -209,7 +209,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)))) { error->message = "Couldn't map exe memory block"; error->code = res; @@ -219,11 +219,11 @@ Result MemoryBlock__MountInProcess(void) // Heap (to be used by the plugin) if (header->heapSize > 0x500000) { - res = svcMapProcessMemoryEx(target, header->heapVA, CUR_PROCESS_HANDLE, (u32) memblock->memblock + header->exeSize, header->heapSize); + res = svcMapProcessMemoryEx(target, header->heapVA, CUR_PROCESS_HANDLE, (u32)memblock->memblock + header->exeSize, header->heapSize); } else { - res = svcMapPluginMemory(target, header->heapVA, CUR_PROCESS_HANDLE, (u32) memblock->memblock + header->exeSize, header->heapSize); + res = svcMapPluginMemory(target, header->heapVA, CUR_PROCESS_HANDLE, (u32)memblock->memblock + header->exeSize, header->heapSize); } if (R_FAILED(res)) From 48cf6596b16a62aa6fe09d4008d18fe1624a1dee Mon Sep 17 00:00:00 2001 From: LittleCube Date: Fri, 13 Sep 2024 23:21:06 +0000 Subject: [PATCH 7/7] give new svc a more general name --- .../svc/{MapPluginMemory.h => MapProcessMemoryPrivate.h} | 4 ++-- k11_extension/source/svc.c | 4 ++-- .../svc/{MapPluginMemory.c => MapProcessMemoryPrivate.c} | 4 ++-- k11_extension/source/svc/wrappers.s | 8 ++++---- sysmodules/rosalina/include/csvc.h | 4 ++-- sysmodules/rosalina/source/csvc.s | 2 +- sysmodules/rosalina/source/plugin/memoryblock.c | 2 +- 7 files changed, 14 insertions(+), 14 deletions(-) rename k11_extension/include/svc/{MapPluginMemory.h => MapProcessMemoryPrivate.h} (82%) rename k11_extension/source/svc/{MapPluginMemory.c => MapProcessMemoryPrivate.c} (92%) diff --git a/k11_extension/include/svc/MapPluginMemory.h b/k11_extension/include/svc/MapProcessMemoryPrivate.h similarity index 82% rename from k11_extension/include/svc/MapPluginMemory.h rename to k11_extension/include/svc/MapProcessMemoryPrivate.h index 7dff31cdd..b82290c7f 100644 --- a/k11_extension/include/svc/MapPluginMemory.h +++ b/k11_extension/include/svc/MapProcessMemoryPrivate.h @@ -30,5 +30,5 @@ #include "kernel.h" #include "svc.h" -Result MapPluginMemory(Handle dstProcessHandle, u32 vaDst, Handle srcProcessHandle, u32 vaSrc, u32 size); -Result MapPluginMemoryWrapper(Handle dstProcessHandle, u32 vaDst, Handle srcProcessHandle, u32 vaSrc, u32 size); +Result MapProcessMemoryPrivate(Handle dstProcessHandle, u32 vaDst, Handle srcProcessHandle, u32 vaSrc, u32 size); +Result MapProcessMemoryPrivateWrapper(Handle dstProcessHandle, u32 vaDst, Handle srcProcessHandle, u32 vaSrc, u32 size); diff --git a/k11_extension/source/svc.c b/k11_extension/source/svc.c index 27fca3163..f29fda6b9 100644 --- a/k11_extension/source/svc.c +++ b/k11_extension/source/svc.c @@ -42,8 +42,8 @@ #include "svc/KernelSetState.h" #include "svc/CustomBackdoor.h" #include "svc/MapProcessMemoryEx.h" -#include "svc/MapPluginMemory.h" #include "svc/UnmapProcessMemoryEx.h" +#include "svc/MapProcessMemoryPrivate.h" #include "svc/ControlService.h" #include "svc/ControlProcess.h" #include "svc/ExitProcess.h" @@ -99,7 +99,7 @@ void buildAlteredSvcTable(void) alteredSvcTable[0xA1] = UnmapProcessMemoryEx; alteredSvcTable[0xA2] = ControlMemoryEx; alteredSvcTable[0xA3] = ControlMemoryUnsafeWrapper; - alteredSvcTable[0xA4] = MapPluginMemoryWrapper; + alteredSvcTable[0xA4] = MapProcessMemoryPrivateWrapper; alteredSvcTable[0xB0] = ControlService; alteredSvcTable[0xB1] = CopyHandleWrapper; diff --git a/k11_extension/source/svc/MapPluginMemory.c b/k11_extension/source/svc/MapProcessMemoryPrivate.c similarity index 92% rename from k11_extension/source/svc/MapPluginMemory.c rename to k11_extension/source/svc/MapProcessMemoryPrivate.c index 65c74a915..c1cf95d67 100644 --- a/k11_extension/source/svc/MapPluginMemory.c +++ b/k11_extension/source/svc/MapProcessMemoryPrivate.c @@ -24,9 +24,9 @@ * reasonable ways as different from the original version. */ -#include "svc/MapPluginMemory.h" +#include "svc/MapProcessMemoryPrivate.h" -Result MapPluginMemory(Handle dstProcessHandle, u32 vaDst, Handle srcProcessHandle, u32 vaSrc, u32 size) +Result MapProcessMemoryPrivate(Handle dstProcessHandle, u32 vaDst, Handle srcProcessHandle, u32 vaSrc, u32 size) { Result res = 0; u32 sizeInPage = size >> 12; diff --git a/k11_extension/source/svc/wrappers.s b/k11_extension/source/svc/wrappers.s index a2d8a1536..cb0cbda21 100644 --- a/k11_extension/source/svc/wrappers.s +++ b/k11_extension/source/svc/wrappers.s @@ -124,11 +124,11 @@ MapProcessMemoryExWrapper: add sp, #4 pop {pc} -.global MapPluginMemoryWrapper -.type MapPluginMemoryWrapper, %function -MapPluginMemoryWrapper: +.global MapProcessMemoryPrivateWrapper +.type MapProcessMemoryPrivateWrapper, %function +MapProcessMemoryPrivateWrapper: push {lr} str r4, [sp, #-4]! - bl MapPluginMemory + bl MapProcessMemoryPrivate add sp, #4 pop {pc} \ No newline at end of file diff --git a/sysmodules/rosalina/include/csvc.h b/sysmodules/rosalina/include/csvc.h index 88f0dbd10..d6dad38bd 100644 --- a/sysmodules/rosalina/include/csvc.h +++ b/sysmodules/rosalina/include/csvc.h @@ -84,14 +84,14 @@ void svcInvalidateEntireInstructionCache(void); Result svcMapProcessMemoryEx(Handle dstProcessHandle, u32 destAddress, Handle srcProcessHandle, u32 srcAddress, u32 size); /** - * @brief Maps a block of plugin memory (sets MemState to PRIVATE instead of SHARED). + * @brief Maps a block of process memory, but sets MemState to PRIVATE instead of SHARED. * @param dstProcessHandle Handle of the process to map the memory in (destination) * @param destAddress Start address of the memory block in the destination process * @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) */ -Result svcMapPluginMemory(Handle dstProcessHandle, u32 destAddress, Handle srcProcessHandle, u32 srcAddress, u32 size); +Result svcMapProcessMemoryPrivate(Handle dstProcessHandle, u32 destAddress, Handle srcProcessHandle, u32 srcAddress, u32 size); /** * @brief Unmaps a block of process memory. diff --git a/sysmodules/rosalina/source/csvc.s b/sysmodules/rosalina/source/csvc.s index 81becf060..97ba8bf2e 100644 --- a/sysmodules/rosalina/source/csvc.s +++ b/sysmodules/rosalina/source/csvc.s @@ -95,7 +95,7 @@ SVC_BEGIN svcFreeMemory bx lr SVC_END -SVC_BEGIN svcMapPluginMemory +SVC_BEGIN svcMapProcessMemoryPrivate str r4, [sp, #-4]! ldr r4, [sp, #4] svc 0xA4 diff --git a/sysmodules/rosalina/source/plugin/memoryblock.c b/sysmodules/rosalina/source/plugin/memoryblock.c index c648e364e..9889d93f8 100644 --- a/sysmodules/rosalina/source/plugin/memoryblock.c +++ b/sysmodules/rosalina/source/plugin/memoryblock.c @@ -223,7 +223,7 @@ Result MemoryBlock__MountInProcess(void) } else { - res = svcMapPluginMemory(target, header->heapVA, CUR_PROCESS_HANDLE, (u32)memblock->memblock + header->exeSize, header->heapSize); + res = svcMapProcessMemoryPrivate(target, header->heapVA, CUR_PROCESS_HANDLE, (u32)memblock->memblock + header->exeSize, header->heapSize); } if (R_FAILED(res))