diff --git a/stratosphere/dmnt/source/dmnt_cheat_manager.cpp b/stratosphere/dmnt/source/dmnt_cheat_manager.cpp index ddb743561..40be7a440 100644 --- a/stratosphere/dmnt/source/dmnt_cheat_manager.cpp +++ b/stratosphere/dmnt/source/dmnt_cheat_manager.cpp @@ -82,8 +82,7 @@ Result DmntCheatManager::ReadCheatProcessMemoryForVm(u64 proc_addr, void *out_da return svcReadDebugProcessMemory(out_data, g_cheat_process_debug_hnd, proc_addr, size); } - /* TODO: Return value... */ - return 0x20F; + return ResultDmntCheatNotAttached; } Result DmntCheatManager::WriteCheatProcessMemoryForVm(u64 proc_addr, const void *data, size_t size) { @@ -91,8 +90,67 @@ Result DmntCheatManager::WriteCheatProcessMemoryForVm(u64 proc_addr, const void return svcWriteDebugProcessMemory(g_cheat_process_debug_hnd, data, proc_addr, size); } - /* TODO: Return value... */ - return 0x20F; + return ResultDmntCheatNotAttached; +} + + +Result DmntCheatManager::GetCheatProcessMappingCount(u64 *out_count) { + std::scoped_lock lk(g_cheat_lock); + + if (!HasActiveCheatProcess()) { + return ResultDmntCheatNotAttached; + } + + MemoryInfo mem_info; + + u64 address = 0; + *out_count = 0; + do { + mem_info.perm = 0; + u32 tmp; + if (R_FAILED(svcQueryDebugProcessMemory(&mem_info, &tmp, g_cheat_process_debug_hnd, address))) { + break; + } + + if (mem_info.perm != 0) { + *out_count += 1; + } + + address = mem_info.addr + mem_info.size; + } while (address != 0); + + return 0; +} + +Result DmntCheatManager::GetCheatProcessMappings(MemoryInfo *mappings, size_t max_count, u64 *out_count, u64 offset) { + std::scoped_lock lk(g_cheat_lock); + + if (!HasActiveCheatProcess()) { + return ResultDmntCheatNotAttached; + } + + MemoryInfo mem_info; + u64 address = 0; + u64 count = 0; + *out_count = 0; + do { + mem_info.perm = 0; + u32 tmp; + if (R_FAILED(svcQueryDebugProcessMemory(&mem_info, &tmp, g_cheat_process_debug_hnd, address))) { + break; + } + + if (mem_info.perm != 0) { + count++; + if (count > offset) { + mappings[(*out_count)++] = mem_info; + } + } + + address = mem_info.addr + mem_info.size; + } while (address != 0 && *out_count < max_count); + + return 0; } Result DmntCheatManager::ReadCheatProcessMemory(u64 proc_addr, void *out_data, size_t size) { @@ -107,6 +165,17 @@ Result DmntCheatManager::WriteCheatProcessMemory(u64 proc_addr, const void *data return WriteCheatProcessMemoryForVm(proc_addr, data, size); } +Result DmntCheatManager::QueryCheatProcessMemory(MemoryInfo *mapping, u64 address) { + std::scoped_lock lk(g_cheat_lock); + + if (HasActiveCheatProcess()) { + u32 tmp; + return svcQueryDebugProcessMemory(mapping, &tmp, g_cheat_process_debug_hnd, address); + } + + return ResultDmntCheatNotAttached; +} + Handle DmntCheatManager::PrepareDebugNextApplication() { Result rc; Handle event_h; @@ -263,8 +332,7 @@ Result DmntCheatManager::GetCheatProcessMetadata(CheatProcessMetadata *out) { return 0; } - /* TODO: Decide on a set of return values... */ - return 0x20F; + return ResultDmntCheatNotAttached; } void DmntCheatManager::InitializeCheatManager() { diff --git a/stratosphere/dmnt/source/dmnt_cheat_manager.hpp b/stratosphere/dmnt/source/dmnt_cheat_manager.hpp index 5d7518ae6..c46a5f86b 100644 --- a/stratosphere/dmnt/source/dmnt_cheat_manager.hpp +++ b/stratosphere/dmnt/source/dmnt_cheat_manager.hpp @@ -37,8 +37,12 @@ class DmntCheatManager { static Result ReadCheatProcessMemoryForVm(u64 proc_addr, void *out_data, size_t size); static Result WriteCheatProcessMemoryForVm(u64 proc_addr, const void *data, size_t size); + + static Result GetCheatProcessMappingCount(u64 *out_count); + static Result GetCheatProcessMappings(MemoryInfo *mappings, size_t max_count, u64 *out_count, u64 offset); static Result ReadCheatProcessMemory(u64 proc_addr, void *out_data, size_t size); static Result WriteCheatProcessMemory(u64 proc_addr, const void *data, size_t size); + static Result QueryCheatProcessMemory(MemoryInfo *mapping, u64 address); static void InitializeCheatManager(); }; diff --git a/stratosphere/dmnt/source/dmnt_cheat_service.cpp b/stratosphere/dmnt/source/dmnt_cheat_service.cpp index b67422344..af41d8041 100644 --- a/stratosphere/dmnt/source/dmnt_cheat_service.cpp +++ b/stratosphere/dmnt/source/dmnt_cheat_service.cpp @@ -32,23 +32,45 @@ Result DmntCheatService::GetCheatProcessMetadata(Out out_m Result DmntCheatService::GetCheatProcessMappingCount(Out out_count) { - /* TODO */ - return 0xF601; + return DmntCheatManager::GetCheatProcessMappingCount(out_count.GetPointer()); } Result DmntCheatService::GetCheatProcessMappings(OutBuffer mappings, Out out_count, u64 offset) { - /* TODO */ - return 0xF601; + if (mappings.buffer == nullptr) { + return ResultDmntCheatNullBuffer; + } + + return DmntCheatManager::GetCheatProcessMappings(mappings.buffer, mappings.num_elements, out_count.GetPointer(), offset); } Result DmntCheatService::ReadCheatProcessMemory(OutBuffer buffer, u64 address, u64 out_size) { - /* TODO */ - return 0xF601; + if (buffer.buffer == nullptr) { + return ResultDmntCheatNullBuffer; + } + + u64 sz = out_size; + if (buffer.num_elements < sz) { + sz = buffer.num_elements; + } + + return DmntCheatManager::ReadCheatProcessMemory(address, buffer.buffer, sz); } Result DmntCheatService::WriteCheatProcessMemory(InBuffer buffer, u64 address, u64 in_size) { - /* TODO */ - return 0xF601; + if (buffer.buffer == nullptr) { + return ResultDmntCheatNullBuffer; + } + + u64 sz = in_size; + if (buffer.num_elements < sz) { + sz = buffer.num_elements; + } + + return DmntCheatManager::WriteCheatProcessMemory(address, buffer.buffer, sz); +} + +Result DmntCheatService::QueryCheatProcessMemory(Out mapping, u64 address) { + return DmntCheatManager::QueryCheatProcessMemory(mapping.GetPointer(), address); } diff --git a/stratosphere/dmnt/source/dmnt_cheat_service.hpp b/stratosphere/dmnt/source/dmnt_cheat_service.hpp index 02aca63d5..6a95dc0e9 100644 --- a/stratosphere/dmnt/source/dmnt_cheat_service.hpp +++ b/stratosphere/dmnt/source/dmnt_cheat_service.hpp @@ -31,6 +31,7 @@ enum DmntCheatCmd { DmntCheat_Cmd_GetCheatProcessMappings = 65101, DmntCheat_Cmd_ReadCheatProcessMemory = 65102, DmntCheat_Cmd_WriteCheatProcessMemory = 65103, + DmntCheat_Cmd_QueryCheatProcessMemory = 65104, /* Interact with Cheats */ DmntCheat_Cmd_GetCheatCount = 65200, @@ -56,6 +57,7 @@ class DmntCheatService final : public IServiceObject { Result GetCheatProcessMappings(OutBuffer mappings, Out out_count, u64 offset); Result ReadCheatProcessMemory(OutBuffer buffer, u64 address, u64 out_size); Result WriteCheatProcessMemory(InBuffer buffer, u64 address, u64 in_size); + Result QueryCheatProcessMemory(Out mapping, u64 address); Result GetCheatCount(Out out_count); Result GetCheats(OutBuffer cheats, Out out_count, u64 offset); @@ -78,6 +80,7 @@ class DmntCheatService final : public IServiceObject { MakeServiceCommandMeta(), MakeServiceCommandMeta(), MakeServiceCommandMeta(), + MakeServiceCommandMeta(), MakeServiceCommandMeta(), MakeServiceCommandMeta(), diff --git a/stratosphere/dmnt/source/dmnt_cheat_types.hpp b/stratosphere/dmnt/source/dmnt_cheat_types.hpp index 4e7a4602e..73979badf 100644 --- a/stratosphere/dmnt/source/dmnt_cheat_types.hpp +++ b/stratosphere/dmnt/source/dmnt_cheat_types.hpp @@ -18,6 +18,8 @@ #include #include +#include "dmnt_results.hpp" + struct MemoryRegionExtents { u64 base; u64 size; diff --git a/stratosphere/dmnt/source/dmnt_results.hpp b/stratosphere/dmnt/source/dmnt_results.hpp new file mode 100644 index 000000000..5be79a674 --- /dev/null +++ b/stratosphere/dmnt/source/dmnt_results.hpp @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2018 Atmosphère-NX + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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 . + */ + +#pragma once +#include +#include + +static constexpr u32 Module_Dmnt = 13; + +static constexpr Result ResultDmntUnknown = MAKERESULT(Module_Dmnt, 1); +static constexpr Result ResultDmntDebuggingDisabled = MAKERESULT(Module_Dmnt, 2); + +static constexpr Result ResultDmntCheatNotAttached = MAKERESULT(Module_Dmnt, 6500); +static constexpr Result ResultDmntCheatNullBuffer = MAKERESULT(Module_Dmnt, 6501); \ No newline at end of file