Revert "hoc-clk: add live vdd2, live boost clock and basic pwm dimming"
This reverts commit 15b7df8ef1.
This commit is contained in:
@@ -1,41 +0,0 @@
|
||||
ATMOSPHERE_BUILD_CONFIGS :=
|
||||
all: nx_release
|
||||
|
||||
THIS_MAKEFILE := $(abspath $(lastword $(MAKEFILE_LIST)))
|
||||
CURRENT_DIRECTORY := $(abspath $(dir $(THIS_MAKEFILE)))
|
||||
|
||||
define ATMOSPHERE_ADD_TARGET
|
||||
|
||||
ATMOSPHERE_BUILD_CONFIGS += $(strip $1)
|
||||
|
||||
$(strip $1):
|
||||
@echo "Building $(strip $1)"
|
||||
@$$(MAKE) -f $(CURRENT_DIRECTORY)/system_module.mk ATMOSPHERE_MAKEFILE_TARGET="$(strip $1)" ATMOSPHERE_BUILD_NAME="$(strip $2)" ATMOSPHERE_BOARD="$(strip $3)" ATMOSPHERE_CPU="$(strip $4)" $(strip $5)
|
||||
|
||||
clean-$(strip $1):
|
||||
@echo "Cleaning $(strip $1)"
|
||||
@$$(MAKE) -f $(CURRENT_DIRECTORY)/system_module.mk clean ATMOSPHERE_MAKEFILE_TARGET="$(strip $1)" ATMOSPHERE_BUILD_NAME="$(strip $2)" ATMOSPHERE_BOARD="$(strip $3)" ATMOSPHERE_CPU="$(strip $4)" $(strip $5)
|
||||
|
||||
endef
|
||||
|
||||
define ATMOSPHERE_ADD_TARGETS
|
||||
|
||||
$(eval $(call ATMOSPHERE_ADD_TARGET, $(strip $1)_release, release, $(strip $2), $(strip $3), \
|
||||
ATMOSPHERE_BUILD_SETTINGS="$(strip $4)" \
|
||||
))
|
||||
|
||||
$(eval $(call ATMOSPHERE_ADD_TARGET, $(strip $1)_debug, debug, $(strip $2), $(strip $3), \
|
||||
ATMOSPHERE_BUILD_SETTINGS="$(strip $4) -DAMS_BUILD_FOR_DEBUGGING" ATMOSPHERE_BUILD_FOR_DEBUGGING=1 \
|
||||
))
|
||||
|
||||
$(eval $(call ATMOSPHERE_ADD_TARGET, $(strip $1)_audit, audit, $(strip $2), $(strip $3), \
|
||||
ATMOSPHERE_BUILD_SETTINGS="$(strip $4) -DAMS_BUILD_FOR_AUDITING" ATMOSPHERE_BUILD_FOR_DEBUGGING=1 ATMOSPHERE_BUILD_FOR_AUDITING=1 \
|
||||
))
|
||||
|
||||
endef
|
||||
|
||||
$(eval $(call ATMOSPHERE_ADD_TARGETS, nx, nx-hac-001, arm-cortex-a57,))
|
||||
|
||||
clean: $(foreach config,$(ATMOSPHERE_BUILD_CONFIGS),clean-$(config))
|
||||
|
||||
.PHONY: all clean $(foreach config,$(ATMOSPHERE_BUILD_CONFIGS), $(config) clean-$(config))
|
||||
@@ -1,124 +0,0 @@
|
||||
{
|
||||
"name": "dmnt",
|
||||
"title_id": "0x010000000000000d",
|
||||
"title_id_range_min": "0x010000000000000d",
|
||||
"title_id_range_max": "0x010000000000000d",
|
||||
"main_thread_stack_size": "0x00004000",
|
||||
"main_thread_priority": 39,
|
||||
"default_cpu_id": 3,
|
||||
"process_category": 0,
|
||||
"is_retail": true,
|
||||
"pool_partition": 2,
|
||||
"is_64_bit": true,
|
||||
"address_space_type": 3,
|
||||
"disable_device_address_space_merge": true,
|
||||
"filesystem_access": {
|
||||
"permissions": "0xFFFFFFFFFFFFFFFF"
|
||||
},
|
||||
"service_access": [
|
||||
"pm:dmnt",
|
||||
"pm:info",
|
||||
"ldr:dmnt",
|
||||
"ro:dmnt",
|
||||
"ns:dev",
|
||||
"spl:",
|
||||
"lr",
|
||||
"htc",
|
||||
"bsd:s",
|
||||
"sfdnsres",
|
||||
"bsdcfg",
|
||||
"set",
|
||||
"set:sys",
|
||||
"fsp-srv",
|
||||
"fatal:u",
|
||||
"hid"
|
||||
],
|
||||
"service_host": [
|
||||
"dmnt:-",
|
||||
"dmnt:cht"
|
||||
],
|
||||
"kernel_capabilities": [{
|
||||
"type": "kernel_flags",
|
||||
"value": {
|
||||
"highest_thread_priority": 63,
|
||||
"lowest_thread_priority": 24,
|
||||
"lowest_cpu_id": 0,
|
||||
"highest_cpu_id": 3
|
||||
}
|
||||
}, {
|
||||
"type": "syscalls",
|
||||
"value": {
|
||||
"svcSetHeapSize": "0x01",
|
||||
"svcSetMemoryPermission": "0x02",
|
||||
"svcSetMemoryAttribute": "0x03",
|
||||
"svcMapMemory": "0x04",
|
||||
"svcUnmapMemory": "0x05",
|
||||
"svcQueryMemory": "0x06",
|
||||
"svcExitProcess": "0x07",
|
||||
"svcCreateThread": "0x08",
|
||||
"svcStartThread": "0x09",
|
||||
"svcExitThread": "0x0a",
|
||||
"svcSleepThread": "0x0b",
|
||||
"svcGetThreadPriority": "0x0c",
|
||||
"svcSetThreadPriority": "0x0d",
|
||||
"svcGetThreadCoreMask": "0x0e",
|
||||
"svcSetThreadCoreMask": "0x0f",
|
||||
"svcGetCurrentProcessorNumber": "0x10",
|
||||
"svcSignalEvent": "0x11",
|
||||
"svcClearEvent": "0x12",
|
||||
"svcMapSharedMemory": "0x13",
|
||||
"svcUnmapSharedMemory": "0x14",
|
||||
"svcCreateTransferMemory": "0x15",
|
||||
"svcCloseHandle": "0x16",
|
||||
"svcResetSignal": "0x17",
|
||||
"svcWaitSynchronization": "0x18",
|
||||
"svcCancelSynchronization": "0x19",
|
||||
"svcArbitrateLock": "0x1a",
|
||||
"svcArbitrateUnlock": "0x1b",
|
||||
"svcWaitProcessWideKeyAtomic": "0x1c",
|
||||
"svcSignalProcessWideKey": "0x1d",
|
||||
"svcGetSystemTick": "0x1e",
|
||||
"svcConnectToNamedPort": "0x1f",
|
||||
"svcSendSyncRequestLight": "0x20",
|
||||
"svcSendSyncRequest": "0x21",
|
||||
"svcSendSyncRequestWithUserBuffer": "0x22",
|
||||
"svcSendAsyncRequestWithUserBuffer": "0x23",
|
||||
"svcGetProcessId": "0x24",
|
||||
"svcGetThreadId": "0x25",
|
||||
"svcBreak": "0x26",
|
||||
"svcOutputDebugString": "0x27",
|
||||
"svcReturnFromException": "0x28",
|
||||
"svcGetInfo": "0x29",
|
||||
"svcWaitForAddress": "0x34",
|
||||
"svcSignalToAddress": "0x35",
|
||||
"svcSynchronizePreemptionState": "0x36",
|
||||
"svcCreateSession": "0x40",
|
||||
"svcAcceptSession": "0x41",
|
||||
"svcReplyAndReceiveLight": "0x42",
|
||||
"svcReplyAndReceive": "0x43",
|
||||
"svcReplyAndReceiveWithUserBuffer": "0x44",
|
||||
"svcCreateEvent": "0x45",
|
||||
"svcDebugActiveProcess": "0x60",
|
||||
"svcBreakDebugProcess": "0x61",
|
||||
"svcTerminateDebugProcess": "0x62",
|
||||
"svcGetDebugEvent": "0x63",
|
||||
"svcContinueDebugEvent": "0x64",
|
||||
"svcGetProcessList": "0x65",
|
||||
"svcGetThreadList": "0x66",
|
||||
"svcGetDebugThreadContext": "0x67",
|
||||
"svcSetDebugThreadContext": "0x68",
|
||||
"svcQueryDebugProcessMemory": "0x69",
|
||||
"svcReadDebugProcessMemory": "0x6a",
|
||||
"svcWriteDebugProcessMemory": "0x6b",
|
||||
"svcSetHardwareBreakPoint": "0x6c",
|
||||
"svcGetDebugThreadParam": "0x6d",
|
||||
"svcCallSecureMonitor": "0x7f"
|
||||
}
|
||||
}, {
|
||||
"type": "min_kernel_version",
|
||||
"value": "0x0030"
|
||||
}, {
|
||||
"type": "handle_table_size",
|
||||
"value": 0
|
||||
}]
|
||||
}
|
||||
@@ -1,156 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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/>.
|
||||
*/
|
||||
#include <stratosphere.hpp>
|
||||
#include "dmnt_cheat_service.hpp"
|
||||
#include "impl/dmnt_cheat_api.hpp"
|
||||
|
||||
namespace ams::dmnt::cheat {
|
||||
|
||||
/* ========================================================================================= */
|
||||
/* ==================================== Meta Commands ==================================== */
|
||||
/* ========================================================================================= */
|
||||
|
||||
void CheatService::HasCheatProcess(sf::Out<bool> out) {
|
||||
out.SetValue(dmnt::cheat::impl::GetHasActiveCheatProcess());
|
||||
}
|
||||
|
||||
void CheatService::GetCheatProcessEvent(sf::OutCopyHandle out_event) {
|
||||
out_event.SetValue(dmnt::cheat::impl::GetCheatProcessEventHandle(), false);
|
||||
}
|
||||
|
||||
Result CheatService::GetCheatProcessMetadata(sf::Out<CheatProcessMetadata> out_metadata) {
|
||||
R_RETURN(dmnt::cheat::impl::GetCheatProcessMetadata(out_metadata.GetPointer()));
|
||||
}
|
||||
|
||||
Result CheatService::ForceOpenCheatProcess() {
|
||||
R_UNLESS(R_SUCCEEDED(dmnt::cheat::impl::ForceOpenCheatProcess()), dmnt::cheat::ResultCheatNotAttached());
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
Result CheatService::PauseCheatProcess() {
|
||||
R_RETURN(dmnt::cheat::impl::PauseCheatProcess());
|
||||
}
|
||||
|
||||
Result CheatService::ResumeCheatProcess() {
|
||||
R_RETURN(dmnt::cheat::impl::ResumeCheatProcess());
|
||||
}
|
||||
|
||||
Result CheatService::ForceCloseCheatProcess() {
|
||||
R_RETURN(dmnt::cheat::impl::ForceCloseCheatProcess());
|
||||
}
|
||||
|
||||
/* ========================================================================================= */
|
||||
/* =================================== Memory Commands =================================== */
|
||||
/* ========================================================================================= */
|
||||
|
||||
Result CheatService::GetCheatProcessMappingCount(sf::Out<u64> out_count) {
|
||||
R_RETURN(dmnt::cheat::impl::GetCheatProcessMappingCount(out_count.GetPointer()));
|
||||
}
|
||||
|
||||
Result CheatService::GetCheatProcessMappings(const sf::OutArray<svc::MemoryInfo> &mappings, sf::Out<u64> out_count, u64 offset) {
|
||||
R_UNLESS(mappings.GetPointer() != nullptr, dmnt::cheat::ResultCheatNullBuffer());
|
||||
R_RETURN(dmnt::cheat::impl::GetCheatProcessMappings(mappings.GetPointer(), mappings.GetSize(), out_count.GetPointer(), offset));
|
||||
}
|
||||
|
||||
Result CheatService::ReadCheatProcessMemory(const sf::OutBuffer &buffer, u64 address, u64 out_size) {
|
||||
R_UNLESS(buffer.GetPointer() != nullptr, dmnt::cheat::ResultCheatNullBuffer());
|
||||
R_RETURN(dmnt::cheat::impl::ReadCheatProcessMemory(address, buffer.GetPointer(), std::min(out_size, buffer.GetSize())));
|
||||
}
|
||||
|
||||
Result CheatService::WriteCheatProcessMemory(const sf::InBuffer &buffer, u64 address, u64 in_size) {
|
||||
R_UNLESS(buffer.GetPointer() != nullptr, dmnt::cheat::ResultCheatNullBuffer());
|
||||
R_RETURN(dmnt::cheat::impl::WriteCheatProcessMemory(address, buffer.GetPointer(), std::min(in_size, buffer.GetSize())));
|
||||
}
|
||||
|
||||
Result CheatService::QueryCheatProcessMemory(sf::Out<svc::MemoryInfo> mapping, u64 address) {
|
||||
R_RETURN(dmnt::cheat::impl::QueryCheatProcessMemory(mapping.GetPointer(), address));
|
||||
}
|
||||
|
||||
/* ========================================================================================= */
|
||||
/* =================================== Cheat Commands ==================================== */
|
||||
/* ========================================================================================= */
|
||||
|
||||
Result CheatService::GetCheatCount(sf::Out<u64> out_count) {
|
||||
R_RETURN(dmnt::cheat::impl::GetCheatCount(out_count.GetPointer()));
|
||||
}
|
||||
|
||||
Result CheatService::GetCheats(const sf::OutArray<CheatEntry> &cheats, sf::Out<u64> out_count, u64 offset) {
|
||||
R_UNLESS(cheats.GetPointer() != nullptr, dmnt::cheat::ResultCheatNullBuffer());
|
||||
R_RETURN(dmnt::cheat::impl::GetCheats(cheats.GetPointer(), cheats.GetSize(), out_count.GetPointer(), offset));
|
||||
}
|
||||
|
||||
Result CheatService::GetCheatById(sf::Out<CheatEntry> cheat, u32 cheat_id) {
|
||||
R_RETURN(dmnt::cheat::impl::GetCheatById(cheat.GetPointer(), cheat_id));
|
||||
}
|
||||
|
||||
Result CheatService::ToggleCheat(u32 cheat_id) {
|
||||
R_RETURN(dmnt::cheat::impl::ToggleCheat(cheat_id));
|
||||
}
|
||||
|
||||
Result CheatService::AddCheat(const CheatDefinition &cheat, sf::Out<u32> out_cheat_id, bool enabled) {
|
||||
R_RETURN(dmnt::cheat::impl::AddCheat(out_cheat_id.GetPointer(), cheat, enabled));
|
||||
}
|
||||
|
||||
Result CheatService::RemoveCheat(u32 cheat_id) {
|
||||
R_RETURN(dmnt::cheat::impl::RemoveCheat(cheat_id));
|
||||
}
|
||||
|
||||
Result CheatService::ReadStaticRegister(sf::Out<u64> out, u8 which) {
|
||||
R_RETURN(dmnt::cheat::impl::ReadStaticRegister(out.GetPointer(), which));
|
||||
}
|
||||
|
||||
Result CheatService::WriteStaticRegister(u8 which, u64 value) {
|
||||
R_RETURN(dmnt::cheat::impl::WriteStaticRegister(which, value));
|
||||
}
|
||||
|
||||
Result CheatService::ResetStaticRegisters() {
|
||||
R_RETURN(dmnt::cheat::impl::ResetStaticRegisters());
|
||||
}
|
||||
|
||||
Result CheatService::SetMasterCheat(const CheatDefinition &cheat) {
|
||||
R_RETURN(dmnt::cheat::impl::SetMasterCheat(cheat));
|
||||
}
|
||||
|
||||
/* ========================================================================================= */
|
||||
/* =================================== Address Commands ================================== */
|
||||
/* ========================================================================================= */
|
||||
|
||||
Result CheatService::GetFrozenAddressCount(sf::Out<u64> out_count) {
|
||||
R_RETURN(dmnt::cheat::impl::GetFrozenAddressCount(out_count.GetPointer()));
|
||||
}
|
||||
|
||||
Result CheatService::GetFrozenAddresses(const sf::OutArray<FrozenAddressEntry> &addresses, sf::Out<u64> out_count, u64 offset) {
|
||||
R_UNLESS(addresses.GetPointer() != nullptr, dmnt::cheat::ResultCheatNullBuffer());
|
||||
R_RETURN(dmnt::cheat::impl::GetFrozenAddresses(addresses.GetPointer(), addresses.GetSize(), out_count.GetPointer(), offset));
|
||||
}
|
||||
|
||||
Result CheatService::GetFrozenAddress(sf::Out<FrozenAddressEntry> entry, u64 address) {
|
||||
R_RETURN(dmnt::cheat::impl::GetFrozenAddress(entry.GetPointer(), address));
|
||||
}
|
||||
|
||||
Result CheatService::EnableFrozenAddress(sf::Out<u64> out_value, u64 address, u64 width) {
|
||||
/* Width needs to be a power of two <= 8. */
|
||||
R_UNLESS(width > 0, dmnt::cheat::ResultFrozenAddressInvalidWidth());
|
||||
R_UNLESS(width <= sizeof(u64), dmnt::cheat::ResultFrozenAddressInvalidWidth());
|
||||
R_UNLESS((width & (width - 1)) == 0, dmnt::cheat::ResultFrozenAddressInvalidWidth());
|
||||
R_RETURN(dmnt::cheat::impl::EnableFrozenAddress(out_value.GetPointer(), address, width));
|
||||
}
|
||||
|
||||
Result CheatService::DisableFrozenAddress(u64 address) {
|
||||
R_RETURN(dmnt::cheat::impl::DisableFrozenAddress(address));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere.hpp>
|
||||
|
||||
/* TODO: In libstratosphere, eventually? */
|
||||
#define AMS_DMNT_I_CHEAT_INTERFACE_INTERFACE_INFO(C, H) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65000, void, HasCheatProcess, (sf::Out<bool> out), (out)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65001, void, GetCheatProcessEvent, (sf::OutCopyHandle out_event), (out_event)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65002, Result, GetCheatProcessMetadata, (sf::Out<dmnt::cheat::CheatProcessMetadata> out_metadata), (out_metadata)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65003, Result, ForceOpenCheatProcess, (), ()) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65004, Result, PauseCheatProcess, (), ()) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65005, Result, ResumeCheatProcess, (), ()) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65006, Result, ForceCloseCheatProcess, (), ()) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65100, Result, GetCheatProcessMappingCount, (sf::Out<u64> out_count), (out_count)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65101, Result, GetCheatProcessMappings, (const sf::OutArray<svc::MemoryInfo> &mappings, sf::Out<u64> out_count, u64 offset), (mappings, out_count, offset)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65102, Result, ReadCheatProcessMemory, (const sf::OutBuffer &buffer, u64 address, u64 out_size), (buffer, address, out_size)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65103, Result, WriteCheatProcessMemory, (const sf::InBuffer &buffer, u64 address, u64 in_size), (buffer, address, in_size)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65104, Result, QueryCheatProcessMemory, (sf::Out<svc::MemoryInfo> mapping, u64 address), (mapping, address)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65200, Result, GetCheatCount, (sf::Out<u64> out_count), (out_count)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65201, Result, GetCheats, (const sf::OutArray<dmnt::cheat::CheatEntry> &cheats, sf::Out<u64> out_count, u64 offset), (cheats, out_count, offset)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65202, Result, GetCheatById, (sf::Out<dmnt::cheat::CheatEntry> cheat, u32 cheat_id), (cheat, cheat_id)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65203, Result, ToggleCheat, (u32 cheat_id), (cheat_id)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65204, Result, AddCheat, (const dmnt::cheat::CheatDefinition &cheat, sf::Out<u32> out_cheat_id, bool enabled), (cheat, out_cheat_id, enabled)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65205, Result, RemoveCheat, (u32 cheat_id), (cheat_id)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65206, Result, ReadStaticRegister, (sf::Out<u64> out, u8 which), (out, which)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65207, Result, WriteStaticRegister, (u8 which, u64 value), (which, value)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65208, Result, ResetStaticRegisters, (), ()) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65209, Result, SetMasterCheat, (const dmnt::cheat::CheatDefinition &cheat), (cheat)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65300, Result, GetFrozenAddressCount, (sf::Out<u64> out_count), (out_count)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65301, Result, GetFrozenAddresses, (const sf::OutArray<dmnt::cheat::FrozenAddressEntry> &addresses, sf::Out<u64> out_count, u64 offset), (addresses, out_count, offset)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65302, Result, GetFrozenAddress, (sf::Out<dmnt::cheat::FrozenAddressEntry> entry, u64 address), (entry, address)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65303, Result, EnableFrozenAddress, (sf::Out<u64> out_value, u64 address, u64 width), (out_value, address, width)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65304, Result, DisableFrozenAddress, (u64 address), (address))
|
||||
|
||||
AMS_SF_DEFINE_INTERFACE(ams::dmnt::cheat::impl, ICheatInterface, AMS_DMNT_I_CHEAT_INTERFACE_INTERFACE_INFO, 0x00000000)
|
||||
|
||||
namespace ams::dmnt::cheat {
|
||||
|
||||
class CheatService {
|
||||
public:
|
||||
void HasCheatProcess(sf::Out<bool> out);
|
||||
void GetCheatProcessEvent(sf::OutCopyHandle out_event);
|
||||
Result GetCheatProcessMetadata(sf::Out<CheatProcessMetadata> out_metadata);
|
||||
Result ForceOpenCheatProcess();
|
||||
Result PauseCheatProcess();
|
||||
Result ResumeCheatProcess();
|
||||
Result ForceCloseCheatProcess();
|
||||
|
||||
Result GetCheatProcessMappingCount(sf::Out<u64> out_count);
|
||||
Result GetCheatProcessMappings(const sf::OutArray<svc::MemoryInfo> &mappings, sf::Out<u64> out_count, u64 offset);
|
||||
Result ReadCheatProcessMemory(const sf::OutBuffer &buffer, u64 address, u64 out_size);
|
||||
Result WriteCheatProcessMemory(const sf::InBuffer &buffer, u64 address, u64 in_size);
|
||||
Result QueryCheatProcessMemory(sf::Out<svc::MemoryInfo> mapping, u64 address);
|
||||
|
||||
Result GetCheatCount(sf::Out<u64> out_count);
|
||||
Result GetCheats(const sf::OutArray<CheatEntry> &cheats, sf::Out<u64> out_count, u64 offset);
|
||||
Result GetCheatById(sf::Out<CheatEntry> cheat, u32 cheat_id);
|
||||
Result ToggleCheat(u32 cheat_id);
|
||||
Result AddCheat(const CheatDefinition &cheat, sf::Out<u32> out_cheat_id, bool enabled);
|
||||
Result RemoveCheat(u32 cheat_id);
|
||||
Result ReadStaticRegister(sf::Out<u64> out, u8 which);
|
||||
Result WriteStaticRegister(u8 which, u64 value);
|
||||
Result ResetStaticRegisters();
|
||||
Result SetMasterCheat(const CheatDefinition &cheat);
|
||||
|
||||
Result GetFrozenAddressCount(sf::Out<u64> out_count);
|
||||
Result GetFrozenAddresses(const sf::OutArray<FrozenAddressEntry> &addresses, sf::Out<u64> out_count, u64 offset);
|
||||
Result GetFrozenAddress(sf::Out<FrozenAddressEntry> entry, u64 address);
|
||||
Result EnableFrozenAddress(sf::Out<u64> out_value, u64 address, u64 width);
|
||||
Result DisableFrozenAddress(u64 address);
|
||||
};
|
||||
static_assert(impl::IsICheatInterface<CheatService>);
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,60 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere.hpp>
|
||||
|
||||
namespace ams::dmnt::cheat::impl {
|
||||
|
||||
void InitializeCheatManager();
|
||||
|
||||
bool GetHasActiveCheatProcess();
|
||||
os::NativeHandle GetCheatProcessEventHandle();
|
||||
Result GetCheatProcessMetadata(CheatProcessMetadata *out);
|
||||
Result ForceOpenCheatProcess();
|
||||
Result PauseCheatProcess();
|
||||
Result ResumeCheatProcess();
|
||||
Result ForceCloseCheatProcess();
|
||||
|
||||
Result ReadCheatProcessMemoryUnsafe(u64 process_addr, void *out_data, size_t size);
|
||||
Result WriteCheatProcessMemoryUnsafe(u64 process_addr, void *data, size_t size);
|
||||
|
||||
Result PauseCheatProcessUnsafe();
|
||||
Result ResumeCheatProcessUnsafe();
|
||||
|
||||
Result GetCheatProcessMappingCount(u64 *out_count);
|
||||
Result GetCheatProcessMappings(svc::MemoryInfo *mappings, size_t max_count, u64 *out_count, u64 offset);
|
||||
Result ReadCheatProcessMemory(u64 proc_addr, void *out_data, size_t size);
|
||||
Result WriteCheatProcessMemory(u64 proc_addr, const void *data, size_t size);
|
||||
Result QueryCheatProcessMemory(svc::MemoryInfo *mapping, u64 address);
|
||||
|
||||
Result GetCheatCount(u64 *out_count);
|
||||
Result GetCheats(CheatEntry *cheats, size_t max_count, u64 *out_count, u64 offset);
|
||||
Result GetCheatById(CheatEntry *out_cheat, u32 cheat_id);
|
||||
Result ToggleCheat(u32 cheat_id);
|
||||
Result AddCheat(u32 *out_id, const CheatDefinition &def, bool enabled);
|
||||
Result RemoveCheat(u32 cheat_id);
|
||||
Result SetMasterCheat(const CheatDefinition &def);
|
||||
Result ReadStaticRegister(u64 *out, size_t which);
|
||||
Result WriteStaticRegister(size_t which, u64 value);
|
||||
Result ResetStaticRegisters();
|
||||
|
||||
Result GetFrozenAddressCount(u64 *out_count);
|
||||
Result GetFrozenAddresses(FrozenAddressEntry *frz_addrs, size_t max_count, u64 *out_count, u64 offset);
|
||||
Result GetFrozenAddress(FrozenAddressEntry *frz_addr, u64 address);
|
||||
Result EnableFrozenAddress(u64 *out_value, u64 address, u64 width);
|
||||
Result DisableFrozenAddress(u64 address);
|
||||
|
||||
}
|
||||
@@ -1,158 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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/>.
|
||||
*/
|
||||
#include <stratosphere.hpp>
|
||||
#include "dmnt_cheat_debug_events_manager.hpp"
|
||||
|
||||
/* WORKAROUND: This design prevents a kernel deadlock from occurring on 6.0.0+ */
|
||||
|
||||
namespace ams::dmnt::cheat::impl {
|
||||
|
||||
namespace {
|
||||
|
||||
class DebugEventsManager {
|
||||
public:
|
||||
static constexpr size_t NumCores = 4;
|
||||
static constexpr size_t ThreadStackSize = os::MemoryPageSize;
|
||||
private:
|
||||
std::array<uintptr_t, NumCores> m_handle_message_queue_buffers;
|
||||
std::array<uintptr_t, NumCores> m_result_message_queue_buffers;
|
||||
std::array<os::MessageQueue, NumCores> m_handle_message_queues;
|
||||
std::array<os::MessageQueue, NumCores> m_result_message_queues;
|
||||
std::array<os::ThreadType, NumCores> m_threads;
|
||||
|
||||
alignas(os::MemoryPageSize) u8 m_thread_stacks[NumCores][ThreadStackSize];
|
||||
private:
|
||||
static void PerCoreThreadFunction(void *_this) {
|
||||
/* This thread will wait on the appropriate message queue. */
|
||||
DebugEventsManager *this_ptr = reinterpret_cast<DebugEventsManager *>(_this);
|
||||
const size_t current_core = svc::GetCurrentProcessorNumber();
|
||||
while (true) {
|
||||
/* Receive handle. */
|
||||
os::NativeHandle debug_handle = this_ptr->WaitReceiveHandle(current_core);
|
||||
|
||||
/* Continue events on the correct core. */
|
||||
Result result = this_ptr->ContinueDebugEvent(debug_handle);
|
||||
|
||||
/* Return our result. */
|
||||
this_ptr->SendContinueResult(current_core, result);
|
||||
}
|
||||
}
|
||||
|
||||
Result GetTargetCore(size_t *out, const svc::DebugEventInfo &dbg_event, os::NativeHandle debug_handle) {
|
||||
/* If we don't need to continue on a specific core, use the system core. */
|
||||
size_t target_core = NumCores - 1;
|
||||
|
||||
/* Retrieve correct core for new thread event. */
|
||||
if (dbg_event.type == svc::DebugEvent_CreateThread) {
|
||||
u64 out64 = 0;
|
||||
u32 out32 = 0;
|
||||
|
||||
R_TRY_CATCH(svc::GetDebugThreadParam(&out64, &out32, debug_handle, dbg_event.info.create_thread.thread_id, svc::DebugThreadParam_CurrentCore)) {
|
||||
R_CATCH_RETHROW(svc::ResultProcessTerminated)
|
||||
} R_END_TRY_CATCH_WITH_ABORT_UNLESS;
|
||||
|
||||
target_core = out32;
|
||||
}
|
||||
|
||||
/* Set the target core. */
|
||||
*out = target_core;
|
||||
R_SUCCEED();
|
||||
}
|
||||
|
||||
void SendHandle(size_t target_core, os::NativeHandle debug_handle) {
|
||||
m_handle_message_queues[target_core].Send(static_cast<uintptr_t>(debug_handle));
|
||||
}
|
||||
|
||||
os::NativeHandle WaitReceiveHandle(size_t core_id) {
|
||||
uintptr_t x = 0;
|
||||
m_handle_message_queues[core_id].Receive(&x);
|
||||
return static_cast<os::NativeHandle>(x);
|
||||
}
|
||||
|
||||
Result ContinueDebugEvent(os::NativeHandle debug_handle) {
|
||||
if (hos::GetVersion() >= hos::Version_3_0_0) {
|
||||
R_RETURN(svc::ContinueDebugEvent(debug_handle, svc::ContinueFlag_ExceptionHandled | svc::ContinueFlag_ContinueAll, nullptr, 0));
|
||||
} else {
|
||||
R_RETURN(svc::LegacyContinueDebugEvent(debug_handle, svc::ContinueFlag_ExceptionHandled | svc::ContinueFlag_ContinueAll, 0));
|
||||
}
|
||||
}
|
||||
|
||||
void SendContinueResult(size_t target_core, Result result) {
|
||||
m_result_message_queues[target_core].Send(static_cast<uintptr_t>(result.GetValue()));
|
||||
}
|
||||
|
||||
Result GetContinueResult(size_t core_id) {
|
||||
uintptr_t x = 0;
|
||||
m_result_message_queues[core_id].Receive(&x);
|
||||
return static_cast<Result>(x);
|
||||
}
|
||||
public:
|
||||
DebugEventsManager()
|
||||
: m_handle_message_queues{
|
||||
os::MessageQueue(std::addressof(m_handle_message_queue_buffers[0]), 1),
|
||||
os::MessageQueue(std::addressof(m_handle_message_queue_buffers[1]), 1),
|
||||
os::MessageQueue(std::addressof(m_handle_message_queue_buffers[2]), 1),
|
||||
os::MessageQueue(std::addressof(m_handle_message_queue_buffers[3]), 1)},
|
||||
m_result_message_queues{
|
||||
os::MessageQueue(std::addressof(m_result_message_queue_buffers[0]), 1),
|
||||
os::MessageQueue(std::addressof(m_result_message_queue_buffers[1]), 1),
|
||||
os::MessageQueue(std::addressof(m_result_message_queue_buffers[2]), 1),
|
||||
os::MessageQueue(std::addressof(m_result_message_queue_buffers[3]), 1)},
|
||||
m_thread_stacks{}
|
||||
{
|
||||
for (size_t i = 0; i < NumCores; i++) {
|
||||
/* Create thread. */
|
||||
R_ABORT_UNLESS(os::CreateThread(std::addressof(m_threads[i]), PerCoreThreadFunction, this, m_thread_stacks[i], ThreadStackSize, AMS_GET_SYSTEM_THREAD_PRIORITY(dmnt, MultiCoreEventManager), i));
|
||||
os::SetThreadNamePointer(std::addressof(m_threads[i]), AMS_GET_SYSTEM_THREAD_NAME(dmnt, MultiCoreEventManager));
|
||||
|
||||
/* Set core mask. */
|
||||
os::SetThreadCoreMask(std::addressof(m_threads[i]), i, (1u << i));
|
||||
|
||||
/* Start thread. */
|
||||
os::StartThread(std::addressof(m_threads[i]));
|
||||
}
|
||||
}
|
||||
|
||||
Result ContinueCheatProcess(os::NativeHandle cheat_dbg_hnd) {
|
||||
/* Loop getting all debug events. */
|
||||
svc::DebugEventInfo d;
|
||||
size_t target_core = NumCores - 1;
|
||||
while (R_SUCCEEDED(svc::GetDebugEvent(std::addressof(d), cheat_dbg_hnd))) {
|
||||
if (d.type == svc::DebugEvent_CreateThread) {
|
||||
R_TRY(GetTargetCore(std::addressof(target_core), d, cheat_dbg_hnd));
|
||||
}
|
||||
}
|
||||
|
||||
/* Send handle to correct core, wait for continue to finish. */
|
||||
this->SendHandle(target_core, cheat_dbg_hnd);
|
||||
R_RETURN(this->GetContinueResult(target_core));
|
||||
}
|
||||
};
|
||||
|
||||
/* Manager global. */
|
||||
util::TypedStorage<DebugEventsManager> g_events_manager;
|
||||
|
||||
}
|
||||
|
||||
void InitializeDebugEventsManager() {
|
||||
util::ConstructAt(g_events_manager);
|
||||
}
|
||||
|
||||
Result ContinueCheatProcess(os::NativeHandle cheat_dbg_hnd) {
|
||||
R_RETURN(GetReference(g_events_manager).ContinueCheatProcess(cheat_dbg_hnd));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere.hpp>
|
||||
|
||||
namespace ams::dmnt::cheat::impl {
|
||||
|
||||
void InitializeDebugEventsManager();
|
||||
|
||||
Result ContinueCheatProcess(os::NativeHandle cheat_dbg_hnd);
|
||||
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,350 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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 <stratosphere.hpp>
|
||||
|
||||
namespace ams::dmnt::cheat::impl {
|
||||
|
||||
enum CheatVmOpcodeType : u32 {
|
||||
CheatVmOpcodeType_StoreStatic = 0,
|
||||
CheatVmOpcodeType_BeginConditionalBlock = 1,
|
||||
CheatVmOpcodeType_EndConditionalBlock = 2,
|
||||
CheatVmOpcodeType_ControlLoop = 3,
|
||||
CheatVmOpcodeType_LoadRegisterStatic = 4,
|
||||
CheatVmOpcodeType_LoadRegisterMemory = 5,
|
||||
CheatVmOpcodeType_StoreStaticToAddress = 6,
|
||||
CheatVmOpcodeType_PerformArithmeticStatic = 7,
|
||||
CheatVmOpcodeType_BeginKeypressConditionalBlock = 8,
|
||||
|
||||
/* These are not implemented by Gateway's VM. */
|
||||
CheatVmOpcodeType_PerformArithmeticRegister = 9,
|
||||
CheatVmOpcodeType_StoreRegisterToAddress = 10,
|
||||
CheatVmOpcodeType_Reserved11 = 11,
|
||||
|
||||
/* This is a meta entry, and not a real opcode. */
|
||||
/* This is to facilitate multi-nybble instruction decoding. */
|
||||
CheatVmOpcodeType_ExtendedWidth = 12,
|
||||
|
||||
/* Extended width opcodes. */
|
||||
CheatVmOpcodeType_BeginRegisterConditionalBlock = 0xC0,
|
||||
CheatVmOpcodeType_SaveRestoreRegister = 0xC1,
|
||||
CheatVmOpcodeType_SaveRestoreRegisterMask = 0xC2,
|
||||
CheatVmOpcodeType_ReadWriteStaticRegister = 0xC3,
|
||||
CheatVmOpcodeType_BeginExtendedKeypressConditionalBlock = 0xC4,
|
||||
|
||||
/* This is a meta entry, and not a real opcode. */
|
||||
/* This is to facilitate multi-nybble instruction decoding. */
|
||||
CheatVmOpcodeType_DoubleExtendedWidth = 0xF0,
|
||||
|
||||
/* Double-extended width opcodes. */
|
||||
CheatVmOpcodeType_PauseProcess = 0xFF0,
|
||||
CheatVmOpcodeType_ResumeProcess = 0xFF1,
|
||||
CheatVmOpcodeType_DebugLog = 0xFFF,
|
||||
};
|
||||
|
||||
enum MemoryAccessType : u32 {
|
||||
MemoryAccessType_MainNso = 0,
|
||||
MemoryAccessType_Heap = 1,
|
||||
MemoryAccessType_Alias = 2,
|
||||
MemoryAccessType_Aslr = 3,
|
||||
MemoryAccessType_NonRelative = 4,
|
||||
};
|
||||
|
||||
enum ConditionalComparisonType : u32 {
|
||||
ConditionalComparisonType_GT = 1,
|
||||
ConditionalComparisonType_GE = 2,
|
||||
ConditionalComparisonType_LT = 3,
|
||||
ConditionalComparisonType_LE = 4,
|
||||
ConditionalComparisonType_EQ = 5,
|
||||
ConditionalComparisonType_NE = 6,
|
||||
};
|
||||
|
||||
enum RegisterArithmeticType : u32 {
|
||||
RegisterArithmeticType_Addition = 0,
|
||||
RegisterArithmeticType_Subtraction = 1,
|
||||
RegisterArithmeticType_Multiplication = 2,
|
||||
RegisterArithmeticType_LeftShift = 3,
|
||||
RegisterArithmeticType_RightShift = 4,
|
||||
|
||||
/* These are not supported by Gateway's VM. */
|
||||
RegisterArithmeticType_LogicalAnd = 5,
|
||||
RegisterArithmeticType_LogicalOr = 6,
|
||||
RegisterArithmeticType_LogicalNot = 7,
|
||||
RegisterArithmeticType_LogicalXor = 8,
|
||||
|
||||
RegisterArithmeticType_None = 9,
|
||||
RegisterArithmeticType_FloatAddition = 10,
|
||||
RegisterArithmeticType_FloatSubtraction = 11,
|
||||
RegisterArithmeticType_FloatMultiplication = 12,
|
||||
RegisterArithmeticType_FloatDivision = 13,
|
||||
};
|
||||
|
||||
enum StoreRegisterOffsetType : u32 {
|
||||
StoreRegisterOffsetType_None = 0,
|
||||
StoreRegisterOffsetType_Reg = 1,
|
||||
StoreRegisterOffsetType_Imm = 2,
|
||||
StoreRegisterOffsetType_MemReg = 3,
|
||||
StoreRegisterOffsetType_MemImm = 4,
|
||||
StoreRegisterOffsetType_MemImmReg = 5,
|
||||
};
|
||||
|
||||
enum CompareRegisterValueType : u32 {
|
||||
CompareRegisterValueType_MemoryRelAddr = 0,
|
||||
CompareRegisterValueType_MemoryOfsReg = 1,
|
||||
CompareRegisterValueType_RegisterRelAddr = 2,
|
||||
CompareRegisterValueType_RegisterOfsReg = 3,
|
||||
CompareRegisterValueType_StaticValue = 4,
|
||||
CompareRegisterValueType_OtherRegister = 5,
|
||||
};
|
||||
|
||||
enum SaveRestoreRegisterOpType : u32 {
|
||||
SaveRestoreRegisterOpType_Restore = 0,
|
||||
SaveRestoreRegisterOpType_Save = 1,
|
||||
SaveRestoreRegisterOpType_ClearSaved = 2,
|
||||
SaveRestoreRegisterOpType_ClearRegs = 3,
|
||||
};
|
||||
|
||||
enum DebugLogValueType : u32 {
|
||||
DebugLogValueType_MemoryRelAddr = 0,
|
||||
DebugLogValueType_MemoryOfsReg = 1,
|
||||
DebugLogValueType_RegisterRelAddr = 2,
|
||||
DebugLogValueType_RegisterOfsReg = 3,
|
||||
DebugLogValueType_RegisterValue = 4,
|
||||
};
|
||||
|
||||
union VmInt {
|
||||
u8 bit8;
|
||||
u16 bit16;
|
||||
u32 bit32;
|
||||
u64 bit64;
|
||||
};
|
||||
|
||||
struct StoreStaticOpcode {
|
||||
u32 bit_width;
|
||||
MemoryAccessType mem_type;
|
||||
u32 offset_register;
|
||||
u64 rel_address;
|
||||
VmInt value;
|
||||
};
|
||||
|
||||
struct BeginConditionalOpcode {
|
||||
u32 bit_width;
|
||||
MemoryAccessType mem_type;
|
||||
ConditionalComparisonType cond_type;
|
||||
bool include_ofs_reg;
|
||||
u32 ofs_reg_index;
|
||||
u64 rel_address;
|
||||
VmInt value;
|
||||
};
|
||||
|
||||
struct EndConditionalOpcode {
|
||||
bool is_else;
|
||||
};
|
||||
|
||||
struct ControlLoopOpcode {
|
||||
bool start_loop;
|
||||
u32 reg_index;
|
||||
u32 num_iters;
|
||||
};
|
||||
|
||||
struct LoadRegisterStaticOpcode {
|
||||
u32 reg_index;
|
||||
u64 value;
|
||||
};
|
||||
|
||||
struct LoadRegisterMemoryOpcode {
|
||||
u32 bit_width;
|
||||
MemoryAccessType mem_type;
|
||||
u32 reg_index;
|
||||
u8 load_from_reg;
|
||||
u8 offset_register;
|
||||
u64 rel_address;
|
||||
};
|
||||
|
||||
struct StoreStaticToAddressOpcode {
|
||||
u32 bit_width;
|
||||
u32 reg_index;
|
||||
bool increment_reg;
|
||||
bool add_offset_reg;
|
||||
u32 offset_reg_index;
|
||||
u64 value;
|
||||
};
|
||||
|
||||
struct PerformArithmeticStaticOpcode {
|
||||
u32 bit_width;
|
||||
u32 reg_index;
|
||||
RegisterArithmeticType math_type;
|
||||
u32 value;
|
||||
};
|
||||
|
||||
struct BeginKeypressConditionalOpcode {
|
||||
u32 key_mask;
|
||||
};
|
||||
|
||||
struct BeginExtendedKeypressConditionalOpcode {
|
||||
u64 key_mask;
|
||||
bool auto_repeat;
|
||||
};
|
||||
|
||||
struct PerformArithmeticRegisterOpcode {
|
||||
u32 bit_width;
|
||||
RegisterArithmeticType math_type;
|
||||
u32 dst_reg_index;
|
||||
u32 src_reg_1_index;
|
||||
u32 src_reg_2_index;
|
||||
bool has_immediate;
|
||||
VmInt value;
|
||||
};
|
||||
|
||||
struct StoreRegisterToAddressOpcode {
|
||||
u32 bit_width;
|
||||
u32 str_reg_index;
|
||||
u32 addr_reg_index;
|
||||
bool increment_reg;
|
||||
StoreRegisterOffsetType ofs_type;
|
||||
MemoryAccessType mem_type;
|
||||
u32 ofs_reg_index;
|
||||
u64 rel_address;
|
||||
};
|
||||
|
||||
struct BeginRegisterConditionalOpcode {
|
||||
u32 bit_width;
|
||||
ConditionalComparisonType cond_type;
|
||||
u32 val_reg_index;
|
||||
CompareRegisterValueType comp_type;
|
||||
MemoryAccessType mem_type;
|
||||
u32 addr_reg_index;
|
||||
u32 other_reg_index;
|
||||
u32 ofs_reg_index;
|
||||
u64 rel_address;
|
||||
VmInt value;
|
||||
};
|
||||
|
||||
struct SaveRestoreRegisterOpcode {
|
||||
u32 dst_index;
|
||||
u32 src_index;
|
||||
SaveRestoreRegisterOpType op_type;
|
||||
};
|
||||
|
||||
struct SaveRestoreRegisterMaskOpcode {
|
||||
SaveRestoreRegisterOpType op_type;
|
||||
bool should_operate[0x10];
|
||||
};
|
||||
|
||||
struct ReadWriteStaticRegisterOpcode {
|
||||
u32 static_idx;
|
||||
u32 idx;
|
||||
};
|
||||
|
||||
struct DebugLogOpcode {
|
||||
u32 bit_width;
|
||||
u32 log_id;
|
||||
DebugLogValueType val_type;
|
||||
MemoryAccessType mem_type;
|
||||
u32 addr_reg_index;
|
||||
u32 val_reg_index;
|
||||
u32 ofs_reg_index;
|
||||
u64 rel_address;
|
||||
};
|
||||
|
||||
struct CheatVmOpcode {
|
||||
CheatVmOpcodeType opcode;
|
||||
bool begin_conditional_block;
|
||||
union {
|
||||
StoreStaticOpcode store_static;
|
||||
BeginConditionalOpcode begin_cond;
|
||||
EndConditionalOpcode end_cond;
|
||||
ControlLoopOpcode ctrl_loop;
|
||||
LoadRegisterStaticOpcode ldr_static;
|
||||
LoadRegisterMemoryOpcode ldr_memory;
|
||||
StoreStaticToAddressOpcode str_static;
|
||||
PerformArithmeticStaticOpcode perform_math_static;
|
||||
BeginKeypressConditionalOpcode begin_keypress_cond;
|
||||
BeginExtendedKeypressConditionalOpcode begin_ext_keypress_cond;
|
||||
PerformArithmeticRegisterOpcode perform_math_reg;
|
||||
StoreRegisterToAddressOpcode str_register;
|
||||
BeginRegisterConditionalOpcode begin_reg_cond;
|
||||
SaveRestoreRegisterOpcode save_restore_reg;
|
||||
SaveRestoreRegisterMaskOpcode save_restore_regmask;
|
||||
ReadWriteStaticRegisterOpcode rw_static_reg;
|
||||
DebugLogOpcode debug_log;
|
||||
};
|
||||
};
|
||||
|
||||
class CheatVirtualMachine {
|
||||
public:
|
||||
constexpr static size_t MaximumProgramOpcodeCount = 0x400;
|
||||
constexpr static size_t NumRegisters = 0x10;
|
||||
constexpr static size_t NumReadableStaticRegisters = 0x80;
|
||||
constexpr static size_t NumWritableStaticRegisters = 0x80;
|
||||
constexpr static size_t NumStaticRegisters = NumReadableStaticRegisters + NumWritableStaticRegisters;
|
||||
private:
|
||||
size_t m_num_opcodes = 0;
|
||||
size_t m_instruction_ptr = 0;
|
||||
size_t m_condition_depth = 0;
|
||||
bool m_decode_success = false;
|
||||
u32 m_program[MaximumProgramOpcodeCount] = {0};
|
||||
u64 m_registers[NumRegisters] = {0};
|
||||
u64 m_saved_values[NumRegisters] = {0};
|
||||
u64 m_static_registers[NumStaticRegisters] = {0};
|
||||
size_t m_loop_tops[NumRegisters] = {0};
|
||||
private:
|
||||
bool DecodeNextOpcode(CheatVmOpcode *out);
|
||||
void SkipConditionalBlock(bool is_if);
|
||||
void ResetState();
|
||||
|
||||
/* For implementing the DebugLog opcode. */
|
||||
void DebugLog(u32 log_id, u64 value);
|
||||
|
||||
/* For debugging. These will be IFDEF'd out normally. */
|
||||
void OpenDebugLogFile();
|
||||
void CloseDebugLogFile();
|
||||
void LogToDebugFile(const char *format, ...);
|
||||
void LogOpcode(const CheatVmOpcode *opcode);
|
||||
|
||||
static u64 GetVmInt(VmInt value, u32 bit_width);
|
||||
static u64 GetCheatProcessAddress(const CheatProcessMetadata* metadata, MemoryAccessType mem_type, u64 rel_address);
|
||||
public:
|
||||
constexpr CheatVirtualMachine() = default;
|
||||
|
||||
size_t GetProgramSize() {
|
||||
return m_num_opcodes;
|
||||
}
|
||||
|
||||
bool LoadProgram(const CheatEntry *cheats, size_t num_cheats);
|
||||
void Execute(const CheatProcessMetadata *metadata);
|
||||
|
||||
u64 GetStaticRegister(size_t which) const {
|
||||
return m_static_registers[which];
|
||||
}
|
||||
|
||||
void SetStaticRegister(size_t which, u64 value) {
|
||||
m_static_registers[which] = value;
|
||||
}
|
||||
|
||||
void ResetStaticRegisters() {
|
||||
std::memset(m_static_registers, 0, sizeof(m_static_registers));
|
||||
}
|
||||
#ifdef DMNT_CHEAT_VM_DEBUG_LOG
|
||||
private:
|
||||
fs::FileHandle m_debug_log_file = {};
|
||||
s64 m_debug_log_file_offset = 0;
|
||||
bool m_has_debug_log_file = false;
|
||||
char m_debug_log_format_buf[0x100] = {0};
|
||||
#endif
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,165 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 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/>.
|
||||
*/
|
||||
#include <stratosphere.hpp>
|
||||
#include "cheat/dmnt_cheat_service.hpp"
|
||||
#include "cheat/impl/dmnt_cheat_api.hpp"
|
||||
|
||||
namespace ams {
|
||||
|
||||
namespace dmnt {
|
||||
|
||||
namespace {
|
||||
|
||||
constinit u8 g_fs_heap_memory[4_KB];
|
||||
lmem::HeapHandle g_fs_heap_handle;
|
||||
|
||||
void *AllocateForFs(size_t size) {
|
||||
return lmem::AllocateFromExpHeap(g_fs_heap_handle, size);
|
||||
}
|
||||
|
||||
void DeallocateForFs(void *p, size_t size) {
|
||||
AMS_UNUSED(size);
|
||||
return lmem::FreeToExpHeap(g_fs_heap_handle, p);
|
||||
}
|
||||
|
||||
void InitializeFsHeap() {
|
||||
g_fs_heap_handle = lmem::CreateExpHeap(g_fs_heap_memory, sizeof(g_fs_heap_memory), lmem::CreateOption_None);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
using ServerOptions = sf::hipc::DefaultServerManagerOptions;
|
||||
|
||||
constexpr sm::ServiceName DebugMonitorServiceName = sm::ServiceName::Encode("dmnt:-");
|
||||
constexpr size_t DebugMonitorMaxSessions = 4;
|
||||
|
||||
constexpr sm::ServiceName CheatServiceName = sm::ServiceName::Encode("dmnt:cht");
|
||||
constexpr size_t CheatMaxSessions = 2;
|
||||
|
||||
/* dmnt:-, dmnt:cht. */
|
||||
constexpr size_t NumServers = 2;
|
||||
constexpr size_t NumSessions = DebugMonitorMaxSessions + CheatMaxSessions;
|
||||
|
||||
sf::hipc::ServerManager<NumServers, ServerOptions, NumSessions> g_server_manager;
|
||||
|
||||
constinit sf::UnmanagedServiceObject<dmnt::cheat::impl::ICheatInterface, dmnt::cheat::CheatService> g_cheat_service;
|
||||
|
||||
void LoopServerThread(void *) {
|
||||
g_server_manager.LoopProcess();
|
||||
}
|
||||
|
||||
/* NOTE: Nintendo loops four threads processing on the manager -- we'll loop an extra fifth for our cheat service. */
|
||||
constexpr size_t TotalThreads = DebugMonitorMaxSessions + 1;
|
||||
static_assert(TotalThreads >= 1, "TotalThreads");
|
||||
constexpr size_t NumExtraThreads = TotalThreads - 1;
|
||||
constexpr size_t ThreadStackSize = 0x4000;
|
||||
alignas(os::MemoryPageSize) u8 g_extra_thread_stacks[NumExtraThreads][ThreadStackSize];
|
||||
|
||||
os::ThreadType g_extra_threads[NumExtraThreads];
|
||||
|
||||
void InitializeIpcServer() {
|
||||
/* Create services. */
|
||||
R_ABORT_UNLESS(g_server_manager.RegisterObjectForServer(g_cheat_service.GetShared(), CheatServiceName, CheatMaxSessions));
|
||||
}
|
||||
|
||||
void LoopProcessIpcServer() {
|
||||
/* Initialize threads. */
|
||||
if constexpr (NumExtraThreads > 0) {
|
||||
static_assert(AMS_GET_SYSTEM_THREAD_PRIORITY(dmnt, Main) == AMS_GET_SYSTEM_THREAD_PRIORITY(dmnt, Ipc));
|
||||
for (size_t i = 0; i < NumExtraThreads; i++) {
|
||||
R_ABORT_UNLESS(os::CreateThread(std::addressof(g_extra_threads[i]), LoopServerThread, nullptr, g_extra_thread_stacks[i], ThreadStackSize, AMS_GET_SYSTEM_THREAD_PRIORITY(dmnt, Ipc)));
|
||||
os::SetThreadNamePointer(std::addressof(g_extra_threads[i]), AMS_GET_SYSTEM_THREAD_NAME(dmnt, Ipc));
|
||||
}
|
||||
}
|
||||
|
||||
/* Start extra threads. */
|
||||
if constexpr (NumExtraThreads > 0) {
|
||||
for (size_t i = 0; i < NumExtraThreads; i++) {
|
||||
os::StartThread(std::addressof(g_extra_threads[i]));
|
||||
}
|
||||
}
|
||||
|
||||
/* Loop this thread. */
|
||||
LoopServerThread(nullptr);
|
||||
|
||||
/* Wait for extra threads to finish. */
|
||||
if constexpr (NumExtraThreads > 0) {
|
||||
for (size_t i = 0; i < NumExtraThreads; i++) {
|
||||
os::WaitThread(std::addressof(g_extra_threads[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace init {
|
||||
|
||||
void InitializeSystemModule() {
|
||||
/* Initialize heap. */
|
||||
dmnt::InitializeFsHeap();
|
||||
|
||||
/* Initialize our connection to sm. */
|
||||
R_ABORT_UNLESS(sm::Initialize());
|
||||
|
||||
/* Initialize fs. */
|
||||
fs::InitializeForSystem();
|
||||
fs::SetAllocator(dmnt::AllocateForFs, dmnt::DeallocateForFs);
|
||||
fs::SetEnabledAutoAbort(false);
|
||||
|
||||
/* Initialize other services we need. */
|
||||
R_ABORT_UNLESS(pmdmntInitialize());
|
||||
R_ABORT_UNLESS(pminfoInitialize());
|
||||
R_ABORT_UNLESS(ldrDmntInitialize());
|
||||
R_ABORT_UNLESS(roDmntInitialize());
|
||||
R_ABORT_UNLESS(nsdevInitialize());
|
||||
lr::Initialize();
|
||||
R_ABORT_UNLESS(setInitialize());
|
||||
R_ABORT_UNLESS(setsysInitialize());
|
||||
R_ABORT_UNLESS(hidInitialize());
|
||||
|
||||
/* Mount the SD card. */
|
||||
R_ABORT_UNLESS(fs::MountSdCard("sdmc"));
|
||||
|
||||
/* Verify that we can sanely execute. */
|
||||
ams::CheckApiVersion();
|
||||
}
|
||||
|
||||
void FinalizeSystemModule() { /* ... */ }
|
||||
|
||||
void Startup() { /* ... */ }
|
||||
|
||||
}
|
||||
|
||||
void Main() {
|
||||
/* Set thread name. */
|
||||
os::SetThreadNamePointer(os::GetCurrentThread(), AMS_GET_SYSTEM_THREAD_NAME(dmnt, Main));
|
||||
AMS_ASSERT(os::GetThreadPriority(os::GetCurrentThread()) == AMS_GET_SYSTEM_THREAD_PRIORITY(dmnt, Main));
|
||||
|
||||
/* Initialize the cheat manager. */
|
||||
dmnt::cheat::impl::InitializeCheatManager();
|
||||
|
||||
/* Initialize ipc server. */
|
||||
dmnt::InitializeIpcServer();
|
||||
|
||||
/* Loop processing ipc server. */
|
||||
dmnt::LoopProcessIpcServer();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,132 +0,0 @@
|
||||
#---------------------------------------------------------------------------------
|
||||
# pull in common stratosphere sysmodule configuration
|
||||
#---------------------------------------------------------------------------------
|
||||
THIS_MAKEFILE := $(abspath $(lastword $(MAKEFILE_LIST)))
|
||||
CURRENT_DIRECTORY := $(abspath $(dir $(THIS_MAKEFILE)))
|
||||
include $(dir $(abspath $(lastword $(MAKEFILE_LIST))))/../../libraries/config/templates/stratosphere.mk
|
||||
|
||||
ATMOSPHERE_SYSTEM_MODULE_TARGETS := nsp
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# no real need to edit anything past this point unless you need to add additional
|
||||
# rules for different file extensions
|
||||
#---------------------------------------------------------------------------------
|
||||
ifneq ($(__RECURSIVE__),1)
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
export TOPDIR := $(CURDIR)
|
||||
|
||||
export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
|
||||
$(foreach dir,$(DATA),$(CURDIR)/$(dir))
|
||||
|
||||
CFILES := $(call FIND_SOURCE_FILES,$(SOURCES),c)
|
||||
CPPFILES := $(call FIND_SOURCE_FILES,$(SOURCES),cpp)
|
||||
SFILES := $(call FIND_SOURCE_FILES,$(SOURCES),s)
|
||||
|
||||
BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# use CXX for linking C++ projects, CC for standard C
|
||||
#---------------------------------------------------------------------------------
|
||||
ifeq ($(strip $(CPPFILES)),)
|
||||
#---------------------------------------------------------------------------------
|
||||
export LD := $(CC)
|
||||
#---------------------------------------------------------------------------------
|
||||
else
|
||||
#---------------------------------------------------------------------------------
|
||||
export LD := $(CXX)
|
||||
#---------------------------------------------------------------------------------
|
||||
endif
|
||||
#---------------------------------------------------------------------------------
|
||||
|
||||
export OFILES := $(addsuffix .o,$(BINFILES)) \
|
||||
$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
|
||||
|
||||
export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
|
||||
$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
|
||||
$(foreach dir,$(AMS_LIBDIRS),-I$(dir)/include) \
|
||||
-I$(CURDIR)/$(ATMOSPHERE_BUILD_DIR)
|
||||
|
||||
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) $(foreach dir,$(AMS_LIBDIRS),-L$(dir)/$(ATMOSPHERE_LIBRARY_DIR))
|
||||
|
||||
export BUILD_EXEFS_SRC := $(TOPDIR)/$(EXEFS_SRC)
|
||||
|
||||
ifeq ($(strip $(CONFIG_JSON)),)
|
||||
jsons := $(wildcard *.json)
|
||||
ifneq (,$(findstring $(TARGET).json,$(jsons)))
|
||||
export APP_JSON := $(TOPDIR)/$(TARGET).json
|
||||
else
|
||||
ifneq (,$(findstring config.json,$(jsons)))
|
||||
export APP_JSON := $(TOPDIR)/config.json
|
||||
endif
|
||||
endif
|
||||
else
|
||||
export APP_JSON := $(TOPDIR)/$(CONFIG_JSON)
|
||||
endif
|
||||
|
||||
.PHONY: clean all check_lib
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
all: $(ATMOSPHERE_OUT_DIR) $(ATMOSPHERE_BUILD_DIR) $(ATMOSPHERE_LIBRARIES_DIR)/libstratosphere/$(ATMOSPHERE_LIBRARY_DIR)/libstratosphere.a
|
||||
@$(MAKE) __RECURSIVE__=1 OUTPUT=$(CURDIR)/$(ATMOSPHERE_OUT_DIR)/$(TARGET) \
|
||||
DEPSDIR=$(CURDIR)/$(ATMOSPHERE_BUILD_DIR) \
|
||||
--no-print-directory -C $(ATMOSPHERE_BUILD_DIR) \
|
||||
-f $(THIS_MAKEFILE)
|
||||
|
||||
$(ATMOSPHERE_LIBRARIES_DIR)/libstratosphere/$(ATMOSPHERE_LIBRARY_DIR)/libstratosphere.a: check_lib
|
||||
@$(SILENTCMD)echo "Checked library."
|
||||
|
||||
|
||||
ifeq ($(ATMOSPHERE_CHECKED_LIBSTRATOSPHERE),1)
|
||||
check_lib:
|
||||
else
|
||||
check_lib:
|
||||
@$(MAKE) --no-print-directory -C $(ATMOSPHERE_LIBRARIES_DIR)/libstratosphere -f $(ATMOSPHERE_LIBRARIES_DIR)/libstratosphere/libstratosphere.mk
|
||||
endif
|
||||
|
||||
$(ATMOSPHERE_OUT_DIR) $(ATMOSPHERE_BUILD_DIR):
|
||||
@[ -d $@ ] || mkdir -p $@
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
clean:
|
||||
@echo clean ...
|
||||
@rm -fr $(ATMOSPHERE_OUT_DIR) $(ATMOSPHERE_BUILD_DIR)
|
||||
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
else
|
||||
.PHONY: all
|
||||
|
||||
DEPENDS := $(OFILES:.o=.d)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# main targets
|
||||
#---------------------------------------------------------------------------------
|
||||
all : $(foreach target,$(ATMOSPHERE_SYSTEM_MODULE_TARGETS),$(OUTPUT).$(target))
|
||||
|
||||
$(OUTPUT).kip : $(OUTPUT).elf
|
||||
$(OUTPUT).nsp : $(OUTPUT).nso $(OUTPUT).npdm
|
||||
$(OUTPUT).nso : $(OUTPUT).elf
|
||||
|
||||
$(OUTPUT).elf : $(OFILES)
|
||||
|
||||
$(OFILES) : $(ATMOSPHERE_LIBRARIES_DIR)/libstratosphere/$(ATMOSPHERE_LIBRARY_DIR)/libstratosphere.a
|
||||
|
||||
%.npdm : %.npdm.json
|
||||
@echo built ... $< $@
|
||||
@npdmtool $< $@
|
||||
@echo built ... $(notdir $@)
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# you need a rule like this for each extension you use as binary data
|
||||
#---------------------------------------------------------------------------------
|
||||
%.bin.o : %.bin
|
||||
#---------------------------------------------------------------------------------
|
||||
@echo $(notdir $<)
|
||||
@$(bin2o)
|
||||
|
||||
-include $(DEPENDS)
|
||||
|
||||
#---------------------------------------------------------------------------------------
|
||||
endif
|
||||
#---------------------------------------------------------------------------------------
|
||||
Reference in New Issue
Block a user