mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-23 04:41:12 +00:00
dmnt-cheat: Implement memory service cmds
This commit is contained in:
parent
e8a5aa81f4
commit
ef68881e5c
6 changed files with 140 additions and 14 deletions
|
@ -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);
|
return svcReadDebugProcessMemory(out_data, g_cheat_process_debug_hnd, proc_addr, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: Return value... */
|
return ResultDmntCheatNotAttached;
|
||||||
return 0x20F;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result DmntCheatManager::WriteCheatProcessMemoryForVm(u64 proc_addr, const void *data, size_t size) {
|
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);
|
return svcWriteDebugProcessMemory(g_cheat_process_debug_hnd, data, proc_addr, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: Return value... */
|
return ResultDmntCheatNotAttached;
|
||||||
return 0x20F;
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Result DmntCheatManager::GetCheatProcessMappingCount(u64 *out_count) {
|
||||||
|
std::scoped_lock<HosMutex> 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<HosMutex> 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) {
|
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);
|
return WriteCheatProcessMemoryForVm(proc_addr, data, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Result DmntCheatManager::QueryCheatProcessMemory(MemoryInfo *mapping, u64 address) {
|
||||||
|
std::scoped_lock<HosMutex> lk(g_cheat_lock);
|
||||||
|
|
||||||
|
if (HasActiveCheatProcess()) {
|
||||||
|
u32 tmp;
|
||||||
|
return svcQueryDebugProcessMemory(mapping, &tmp, g_cheat_process_debug_hnd, address);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ResultDmntCheatNotAttached;
|
||||||
|
}
|
||||||
|
|
||||||
Handle DmntCheatManager::PrepareDebugNextApplication() {
|
Handle DmntCheatManager::PrepareDebugNextApplication() {
|
||||||
Result rc;
|
Result rc;
|
||||||
Handle event_h;
|
Handle event_h;
|
||||||
|
@ -263,8 +332,7 @@ Result DmntCheatManager::GetCheatProcessMetadata(CheatProcessMetadata *out) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: Decide on a set of return values... */
|
return ResultDmntCheatNotAttached;
|
||||||
return 0x20F;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DmntCheatManager::InitializeCheatManager() {
|
void DmntCheatManager::InitializeCheatManager() {
|
||||||
|
|
|
@ -37,8 +37,12 @@ class DmntCheatManager {
|
||||||
|
|
||||||
static Result ReadCheatProcessMemoryForVm(u64 proc_addr, void *out_data, size_t size);
|
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 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 ReadCheatProcessMemory(u64 proc_addr, void *out_data, size_t size);
|
||||||
static Result WriteCheatProcessMemory(u64 proc_addr, const void *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();
|
static void InitializeCheatManager();
|
||||||
};
|
};
|
||||||
|
|
|
@ -32,23 +32,45 @@ Result DmntCheatService::GetCheatProcessMetadata(Out<CheatProcessMetadata> out_m
|
||||||
|
|
||||||
|
|
||||||
Result DmntCheatService::GetCheatProcessMappingCount(Out<u64> out_count) {
|
Result DmntCheatService::GetCheatProcessMappingCount(Out<u64> out_count) {
|
||||||
/* TODO */
|
return DmntCheatManager::GetCheatProcessMappingCount(out_count.GetPointer());
|
||||||
return 0xF601;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Result DmntCheatService::GetCheatProcessMappings(OutBuffer<MemoryInfo> mappings, Out<u64> out_count, u64 offset) {
|
Result DmntCheatService::GetCheatProcessMappings(OutBuffer<MemoryInfo> mappings, Out<u64> out_count, u64 offset) {
|
||||||
/* TODO */
|
if (mappings.buffer == nullptr) {
|
||||||
return 0xF601;
|
return ResultDmntCheatNullBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
return DmntCheatManager::GetCheatProcessMappings(mappings.buffer, mappings.num_elements, out_count.GetPointer(), offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result DmntCheatService::ReadCheatProcessMemory(OutBuffer<u8> buffer, u64 address, u64 out_size) {
|
Result DmntCheatService::ReadCheatProcessMemory(OutBuffer<u8> buffer, u64 address, u64 out_size) {
|
||||||
/* TODO */
|
if (buffer.buffer == nullptr) {
|
||||||
return 0xF601;
|
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<u8> buffer, u64 address, u64 in_size) {
|
Result DmntCheatService::WriteCheatProcessMemory(InBuffer<u8> buffer, u64 address, u64 in_size) {
|
||||||
/* TODO */
|
if (buffer.buffer == nullptr) {
|
||||||
return 0xF601;
|
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<MemoryInfo> mapping, u64 address) {
|
||||||
|
return DmntCheatManager::QueryCheatProcessMemory(mapping.GetPointer(), address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@ enum DmntCheatCmd {
|
||||||
DmntCheat_Cmd_GetCheatProcessMappings = 65101,
|
DmntCheat_Cmd_GetCheatProcessMappings = 65101,
|
||||||
DmntCheat_Cmd_ReadCheatProcessMemory = 65102,
|
DmntCheat_Cmd_ReadCheatProcessMemory = 65102,
|
||||||
DmntCheat_Cmd_WriteCheatProcessMemory = 65103,
|
DmntCheat_Cmd_WriteCheatProcessMemory = 65103,
|
||||||
|
DmntCheat_Cmd_QueryCheatProcessMemory = 65104,
|
||||||
|
|
||||||
/* Interact with Cheats */
|
/* Interact with Cheats */
|
||||||
DmntCheat_Cmd_GetCheatCount = 65200,
|
DmntCheat_Cmd_GetCheatCount = 65200,
|
||||||
|
@ -56,6 +57,7 @@ class DmntCheatService final : public IServiceObject {
|
||||||
Result GetCheatProcessMappings(OutBuffer<MemoryInfo> mappings, Out<u64> out_count, u64 offset);
|
Result GetCheatProcessMappings(OutBuffer<MemoryInfo> mappings, Out<u64> out_count, u64 offset);
|
||||||
Result ReadCheatProcessMemory(OutBuffer<u8> buffer, u64 address, u64 out_size);
|
Result ReadCheatProcessMemory(OutBuffer<u8> buffer, u64 address, u64 out_size);
|
||||||
Result WriteCheatProcessMemory(InBuffer<u8> buffer, u64 address, u64 in_size);
|
Result WriteCheatProcessMemory(InBuffer<u8> buffer, u64 address, u64 in_size);
|
||||||
|
Result QueryCheatProcessMemory(Out<MemoryInfo> mapping, u64 address);
|
||||||
|
|
||||||
Result GetCheatCount(Out<u64> out_count);
|
Result GetCheatCount(Out<u64> out_count);
|
||||||
Result GetCheats(OutBuffer<CheatEntry> cheats, Out<u64> out_count, u64 offset);
|
Result GetCheats(OutBuffer<CheatEntry> cheats, Out<u64> out_count, u64 offset);
|
||||||
|
@ -78,6 +80,7 @@ class DmntCheatService final : public IServiceObject {
|
||||||
MakeServiceCommandMeta<DmntCheat_Cmd_GetCheatProcessMappings, &DmntCheatService::GetCheatProcessMappings>(),
|
MakeServiceCommandMeta<DmntCheat_Cmd_GetCheatProcessMappings, &DmntCheatService::GetCheatProcessMappings>(),
|
||||||
MakeServiceCommandMeta<DmntCheat_Cmd_ReadCheatProcessMemory, &DmntCheatService::ReadCheatProcessMemory>(),
|
MakeServiceCommandMeta<DmntCheat_Cmd_ReadCheatProcessMemory, &DmntCheatService::ReadCheatProcessMemory>(),
|
||||||
MakeServiceCommandMeta<DmntCheat_Cmd_WriteCheatProcessMemory, &DmntCheatService::WriteCheatProcessMemory>(),
|
MakeServiceCommandMeta<DmntCheat_Cmd_WriteCheatProcessMemory, &DmntCheatService::WriteCheatProcessMemory>(),
|
||||||
|
MakeServiceCommandMeta<DmntCheat_Cmd_QueryCheatProcessMemory, &DmntCheatService::QueryCheatProcessMemory>(),
|
||||||
|
|
||||||
MakeServiceCommandMeta<DmntCheat_Cmd_GetCheatCount, &DmntCheatService::GetCheatCount>(),
|
MakeServiceCommandMeta<DmntCheat_Cmd_GetCheatCount, &DmntCheatService::GetCheatCount>(),
|
||||||
MakeServiceCommandMeta<DmntCheat_Cmd_GetCheats, &DmntCheatService::GetCheats>(),
|
MakeServiceCommandMeta<DmntCheat_Cmd_GetCheats, &DmntCheatService::GetCheats>(),
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
#include <switch.h>
|
#include <switch.h>
|
||||||
#include <stratosphere.hpp>
|
#include <stratosphere.hpp>
|
||||||
|
|
||||||
|
#include "dmnt_results.hpp"
|
||||||
|
|
||||||
struct MemoryRegionExtents {
|
struct MemoryRegionExtents {
|
||||||
u64 base;
|
u64 base;
|
||||||
u64 size;
|
u64 size;
|
||||||
|
|
27
stratosphere/dmnt/source/dmnt_results.hpp
Normal file
27
stratosphere/dmnt/source/dmnt_results.hpp
Normal file
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include <switch.h>
|
||||||
|
#include <stratosphere.hpp>
|
||||||
|
|
||||||
|
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);
|
Loading…
Reference in a new issue