From 1d40a08ef9773f8ea8980fe0002f71300553d2c7 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Fri, 24 Apr 2020 17:24:15 -0700 Subject: [PATCH] dmnt: move stuff around slightly, add client bindings --- docs/changelog.md | 10 ++++++ .../libstratosphere/source/dmnt/dmntcht.c | 31 +++++++++++++++- .../libstratosphere/source/dmnt/dmntcht.h | 5 +++ .../dmnt/source/cheat/dmnt_cheat_service.cpp | 16 ++++----- .../dmnt/source/cheat/dmnt_cheat_service.hpp | 12 +++---- .../dmnt/source/cheat/impl/dmnt_cheat_api.cpp | 36 +++++++++---------- .../dmnt/source/cheat/impl/dmnt_cheat_api.hpp | 8 ++--- .../dmnt/source/cheat/impl/dmnt_cheat_vm.cpp | 24 ++++++------- .../dmnt/source/cheat/impl/dmnt_cheat_vm.hpp | 4 +-- 9 files changed, 95 insertions(+), 51 deletions(-) diff --git a/docs/changelog.md b/docs/changelog.md index dc2ba0038..8a243e354 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -33,6 +33,16 @@ + A reimplementation was added for the `jpegdec` system module (thanks @HookedBehemoth)! + This allows two sessions instead of 1, so homebrew can now use it for software jpeg decoding in addition to the OS itself. + As usual the implementation has a very slightly smaller memory footprint than Nintendo's. ++ `dmnt`'s Cheat VM was extended to add three new opcodes. + + The first new opcode, "ReadWriteStaticRegister", allows for cheats to read from a bank of 128 read-only static registers, and write to a bank of 128 write-only static registers. + + This can be used in concert with new IPC commands that allow a cheat manager to read or write the value of these static registers to have "dynamic" cheats. + + As an example, a cheat manager could write a value to a static register that a cheat to control how many of an item to give in a game. + + As another example, a cheat manager could read a static register that a cheat writes to to learn how many items a player has. ++ The second and third opcodes are a pair, "PauseProcess" and "ResumeProcess". + + Executing pause process in a cheat will pause the game (it will be frozen) until a resume process opcode is used. + + These are also available over IPC, for cheat managers or system modules that want to pause or resume the attached cheat process. + + This allows a cheat to know that the game won't modify or access data the cheat is accessing. + + For example, this can be used to prevent Pokemon from seeing a pokemon a cheat is in the middle of injecting and turning it into a bad egg. + A bug was fixed that would cause the console to crash when connected to Wi-Fi on versions between 3.0.0 and 4.1.0 inclusive. + A bug was fixed that could cause boot to fail sporadically due to cache/tlb mismanagement when doing physical ASLR of the kernel. + A number of other minor issues were addressed (and more of Atmosphere was updated to reflect other changes in 10.0.x). diff --git a/libraries/libstratosphere/source/dmnt/dmntcht.c b/libraries/libstratosphere/source/dmnt/dmntcht.c index 1de765150..dd5faaa12 100644 --- a/libraries/libstratosphere/source/dmnt/dmntcht.c +++ b/libraries/libstratosphere/source/dmnt/dmntcht.c @@ -58,8 +58,20 @@ Result dmntchtGetCheatProcessMetadata(DmntCheatProcessMetadata *out_metadata) { return serviceDispatchOut(&g_dmntchtSrv, 65002, *out_metadata); } +static Result _dmntchtCmdVoid(Service* srv, u32 cmd_id) { + return serviceDispatch(srv, cmd_id); +} + Result dmntchtForceOpenCheatProcess(void) { - return serviceDispatch(&g_dmntchtSrv, 65003); + return _dmntchtCmdVoid(&g_dmntchtSrv, 65003); +} + +Result dmntchtPauseCheatProcess(void) { + return _dmntchtCmdVoid(&g_dmntchtSrv, 65004); +} + +Result dmntchtResumeCheatProcess(void) { + return _dmntchtCmdVoid(&g_dmntchtSrv, 65005); } static Result _dmntchtGetCount(u64 *out_count, u32 cmd_id) { @@ -142,6 +154,23 @@ Result dmntchtRemoveCheat(u32 cheat_id) { return _dmntchtCmdInU32NoOut(cheat_id, 65205); } +Result dmntchtReadStaticRegister(u64 *out, u8 which) { + return serviceDispatchInOut(&g_dmntchtSrv, 65206, which, *out); +} + +Result dmntchtWriteStaticRegister(u8 which, u64 value) { + const struct { + u64 which; + u64 value; + } in = { which, value }; + + return serviceDispatchIn(&g_dmntchtSrv, 65207, in); +} + +Result dmntchtResetStaticRegisters() { + return _dmntchtCmdVoid(&g_dmntchtSrv, 65208); +} + Result dmntchtGetFrozenAddressCount(u64 *out_count) { return _dmntchtGetCount(out_count, 65300); } diff --git a/libraries/libstratosphere/source/dmnt/dmntcht.h b/libraries/libstratosphere/source/dmnt/dmntcht.h index a04d20394..ef19824e0 100644 --- a/libraries/libstratosphere/source/dmnt/dmntcht.h +++ b/libraries/libstratosphere/source/dmnt/dmntcht.h @@ -74,6 +74,8 @@ Result dmntchtGetCheatProcessMappings(MemoryInfo *buffer, u64 max_count, u64 off Result dmntchtReadCheatProcessMemory(u64 address, void *buffer, size_t size); Result dmntchtWriteCheatProcessMemory(u64 address, const void *buffer, size_t size); Result dmntchtQueryCheatProcessMemory(MemoryInfo *mem_info, u64 address); +Result dmntchtPauseCheatProcess(void); +Result dmntchtResumeCheatProcess(void); Result dmntchtGetCheatCount(u64 *out_count); Result dmntchtGetCheats(DmntCheatEntry *buffer, u64 max_count, u64 offset, u64 *out_count); @@ -81,6 +83,9 @@ Result dmntchtGetCheatById(DmntCheatEntry *out_cheat, u32 cheat_id); Result dmntchtToggleCheat(u32 cheat_id); Result dmntchtAddCheat(DmntCheatDefinition *cheat, bool enabled, u32 *out_cheat_id); Result dmntchtRemoveCheat(u32 cheat_id); +Result dmntchtReadStaticRegister(u64 *out, u8 which); +Result dmntchtWriteStaticRegister(u8 which, u64 value); +Result dmntchtResetStaticRegisters(); Result dmntchtGetFrozenAddressCount(u64 *out_count); Result dmntchtGetFrozenAddresses(DmntFrozenAddressEntry *buffer, u64 max_count, u64 offset, u64 *out_count); diff --git a/stratosphere/dmnt/source/cheat/dmnt_cheat_service.cpp b/stratosphere/dmnt/source/cheat/dmnt_cheat_service.cpp index 51452f228..316fc3291 100644 --- a/stratosphere/dmnt/source/cheat/dmnt_cheat_service.cpp +++ b/stratosphere/dmnt/source/cheat/dmnt_cheat_service.cpp @@ -39,6 +39,14 @@ namespace ams::dmnt::cheat { return ResultSuccess(); } + Result CheatService::PauseCheatProcess() { + return dmnt::cheat::impl::PauseCheatProcess(); + } + + Result CheatService::ResumeCheatProcess() { + return dmnt::cheat::impl::ResumeCheatProcess(); + } + /* ========================================================================================= */ /* =================================== Memory Commands =================================== */ /* ========================================================================================= */ @@ -66,14 +74,6 @@ namespace ams::dmnt::cheat { return dmnt::cheat::impl::QueryCheatProcessMemory(mapping.GetPointer(), address); } - Result CheatService::BreakCheatProcess() { - return dmnt::cheat::impl::BreakCheatProcess(); - } - - Result CheatService::ContinueCheatProcess() { - return dmnt::cheat::impl::ContinueCheatProcess(); - } - /* ========================================================================================= */ /* =================================== Cheat Commands ==================================== */ /* ========================================================================================= */ diff --git a/stratosphere/dmnt/source/cheat/dmnt_cheat_service.hpp b/stratosphere/dmnt/source/cheat/dmnt_cheat_service.hpp index 416aeca2c..35c7d2c7c 100644 --- a/stratosphere/dmnt/source/cheat/dmnt_cheat_service.hpp +++ b/stratosphere/dmnt/source/cheat/dmnt_cheat_service.hpp @@ -26,6 +26,8 @@ namespace ams::dmnt::cheat { GetCheatProcessEvent = 65001, GetCheatProcessMetadata = 65002, ForceOpenCheatProcess = 65003, + PauseCheatProcess = 65004, + ResumeCheatProcess = 65005, /* Interact with Memory */ GetCheatProcessMappingCount = 65100, @@ -33,8 +35,6 @@ namespace ams::dmnt::cheat { ReadCheatProcessMemory = 65102, WriteCheatProcessMemory = 65103, QueryCheatProcessMemory = 65104, - BreakCheatProcess = 65105, - ContinueCheatProcess = 65106, /* Interact with Cheats */ GetCheatCount = 65200, @@ -59,14 +59,14 @@ namespace ams::dmnt::cheat { void GetCheatProcessEvent(sf::OutCopyHandle out_event); Result GetCheatProcessMetadata(sf::Out out_metadata); Result ForceOpenCheatProcess(); + Result PauseCheatProcess(); + Result ResumeCheatProcess(); Result GetCheatProcessMappingCount(sf::Out out_count); Result GetCheatProcessMappings(const sf::OutArray &mappings, sf::Out 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 mapping, u64 address); - Result BreakCheatProcess(); - Result ContinueCheatProcess(); Result GetCheatCount(sf::Out out_count); Result GetCheats(const sf::OutArray &cheats, sf::Out out_count, u64 offset); @@ -90,14 +90,14 @@ namespace ams::dmnt::cheat { MAKE_SERVICE_COMMAND_META(GetCheatProcessEvent), MAKE_SERVICE_COMMAND_META(GetCheatProcessMetadata), MAKE_SERVICE_COMMAND_META(ForceOpenCheatProcess), + MAKE_SERVICE_COMMAND_META(PauseCheatProcess), + MAKE_SERVICE_COMMAND_META(ResumeCheatProcess), MAKE_SERVICE_COMMAND_META(GetCheatProcessMappingCount), MAKE_SERVICE_COMMAND_META(GetCheatProcessMappings), MAKE_SERVICE_COMMAND_META(ReadCheatProcessMemory), MAKE_SERVICE_COMMAND_META(WriteCheatProcessMemory), MAKE_SERVICE_COMMAND_META(QueryCheatProcessMemory), - MAKE_SERVICE_COMMAND_META(BreakCheatProcess), - MAKE_SERVICE_COMMAND_META(ContinueCheatProcess), MAKE_SERVICE_COMMAND_META(GetCheatCount), MAKE_SERVICE_COMMAND_META(GetCheats), diff --git a/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_api.cpp b/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_api.cpp index a2cd6e817..302dcb22f 100644 --- a/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_api.cpp +++ b/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_api.cpp @@ -265,13 +265,13 @@ namespace ams::dmnt::cheat::impl { return ResultSuccess(); } - Result BreakCheatProcessUnsafe() { + Result PauseCheatProcessUnsafe() { this->broken_unsafe = true; this->unsafe_break_event.Clear(); return svcBreakDebugProcess(this->GetCheatProcessHandle()); } - Result ContinueCheatProcessUnsafe() { + Result ResumeCheatProcessUnsafe() { this->broken_unsafe = false; this->unsafe_break_event.Signal(); dmnt::cheat::impl::ContinueCheatProcess(this->GetCheatProcessHandle()); @@ -356,20 +356,20 @@ namespace ams::dmnt::cheat::impl { return svcQueryDebugProcessMemory(mapping, &tmp, this->GetCheatProcessHandle(), address); } - Result BreakCheatProcess() { + Result PauseCheatProcess() { std::scoped_lock lk(this->cheat_lock); R_TRY(this->EnsureCheatProcess()); - return this->BreakCheatProcessUnsafe(); + return this->PauseCheatProcessUnsafe(); } - Result ContinueCheatProcess() { + Result ResumeCheatProcess() { std::scoped_lock lk(this->cheat_lock); R_TRY(this->EnsureCheatProcess()); - return this->ContinueCheatProcessUnsafe(); + return this->ResumeCheatProcessUnsafe(); } Result GetCheatCount(u64 *out_count) { @@ -1096,6 +1096,14 @@ namespace ams::dmnt::cheat::impl { return GetReference(g_cheat_process_manager).ForceOpenCheatProcess(); } + Result PauseCheatProcess() { + return GetReference(g_cheat_process_manager).PauseCheatProcess(); + } + + Result ResumeCheatProcess() { + return GetReference(g_cheat_process_manager).ResumeCheatProcess(); + } + Result ReadCheatProcessMemoryUnsafe(u64 process_addr, void *out_data, size_t size) { return GetReference(g_cheat_process_manager).ReadCheatProcessMemoryUnsafe(process_addr, out_data, size); } @@ -1104,12 +1112,12 @@ namespace ams::dmnt::cheat::impl { return GetReference(g_cheat_process_manager).WriteCheatProcessMemoryUnsafe(process_addr, data, size); } - Result BreakCheatProcessUnsafe() { - return GetReference(g_cheat_process_manager).BreakCheatProcessUnsafe(); + Result PauseCheatProcessUnsafe() { + return GetReference(g_cheat_process_manager).PauseCheatProcessUnsafe(); } - Result ContinueCheatProcessUnsafe() { - return GetReference(g_cheat_process_manager).ContinueCheatProcessUnsafe(); + Result ResumeCheatProcessUnsafe() { + return GetReference(g_cheat_process_manager).ResumeCheatProcessUnsafe(); } Result GetCheatProcessMappingCount(u64 *out_count) { @@ -1132,14 +1140,6 @@ namespace ams::dmnt::cheat::impl { return GetReference(g_cheat_process_manager).QueryCheatProcessMemory(mapping, address); } - Result BreakCheatProcess() { - return GetReference(g_cheat_process_manager).BreakCheatProcess(); - } - - Result ContinueCheatProcess() { - return GetReference(g_cheat_process_manager).ContinueCheatProcess(); - } - Result GetCheatCount(u64 *out_count) { return GetReference(g_cheat_process_manager).GetCheatCount(out_count); } diff --git a/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_api.hpp b/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_api.hpp index 520103a5a..0940f2700 100644 --- a/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_api.hpp +++ b/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_api.hpp @@ -24,20 +24,20 @@ namespace ams::dmnt::cheat::impl { Handle GetCheatProcessEventHandle(); Result GetCheatProcessMetadata(CheatProcessMetadata *out); Result ForceOpenCheatProcess(); + Result PauseCheatProcess(); + Result ResumeCheatProcess(); Result ReadCheatProcessMemoryUnsafe(u64 process_addr, void *out_data, size_t size); Result WriteCheatProcessMemoryUnsafe(u64 process_addr, void *data, size_t size); - Result BreakCheatProcessUnsafe(); - Result ContinueCheatProcessUnsafe(); + Result PauseCheatProcessUnsafe(); + Result ResumeCheatProcessUnsafe(); Result GetCheatProcessMappingCount(u64 *out_count); Result GetCheatProcessMappings(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(MemoryInfo *mapping, u64 address); - Result BreakCheatProcess(); - Result ContinueCheatProcess(); Result GetCheatCount(u64 *out_count); Result GetCheats(CheatEntry *cheats, size_t max_count, u64 *out_count, u64 offset); diff --git a/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.cpp b/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.cpp index 4db17a5d8..ea03e95c5 100644 --- a/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.cpp +++ b/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.cpp @@ -247,11 +247,11 @@ namespace ams::dmnt::cheat::impl { this->LogToDebugFile("Reg Idx: %x\n", opcode->rw_static_reg.idx); this->LogToDebugFile("Stc Idx: %x\n", opcode->rw_static_reg.static_idx); break; - case CheatVmOpcodeType_BreakProcess: - this->LogToDebugFile("Opcode: Break Cheat Process\n"); + case CheatVmOpcodeType_PauseProcess: + this->LogToDebugFile("Opcode: Pause Cheat Process\n"); break; - case CheatVmOpcodeType_ContinueProcess: - this->LogToDebugFile("Opcode: Continue Cheat Process\n"); + case CheatVmOpcodeType_ResumeProcess: + this->LogToDebugFile("Opcode: Resume Cheat Process\n"); break; case CheatVmOpcodeType_DebugLog: this->LogToDebugFile("Opcode: Debug Log\n"); @@ -596,18 +596,18 @@ namespace ams::dmnt::cheat::impl { opcode.rw_static_reg.idx = (first_dword & 0xF); } break; - case CheatVmOpcodeType_BreakProcess: + case CheatVmOpcodeType_PauseProcess: { /* FF0????? */ /* FF0 = opcode 0xFF0 */ - /* Breaks the current process. */ + /* Pauses the current process. */ } break; - case CheatVmOpcodeType_ContinueProcess: + case CheatVmOpcodeType_ResumeProcess: { /* FF1????? */ /* FF1 = opcode 0xFF1 */ - /* Continues the current process. */ + /* Resumes the current process. */ } break; case CheatVmOpcodeType_DebugLog: @@ -1223,11 +1223,11 @@ namespace ams::dmnt::cheat::impl { this->static_registers[cur_opcode.rw_static_reg.static_idx] = this->registers[cur_opcode.rw_static_reg.idx]; } break; - case CheatVmOpcodeType_BreakProcess: - dmnt::cheat::impl::BreakCheatProcessUnsafe(); + case CheatVmOpcodeType_PauseProcess: + dmnt::cheat::impl::PauseCheatProcessUnsafe(); break; - case CheatVmOpcodeType_ContinueProcess: - dmnt::cheat::impl::ContinueCheatProcessUnsafe(); + case CheatVmOpcodeType_ResumeProcess: + dmnt::cheat::impl::ResumeCheatProcessUnsafe(); break; case CheatVmOpcodeType_DebugLog: { diff --git a/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.hpp b/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.hpp index 369af1212..66dcb6721 100644 --- a/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.hpp +++ b/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.hpp @@ -49,8 +49,8 @@ namespace ams::dmnt::cheat::impl { CheatVmOpcodeType_DoubleExtendedWidth = 0xF0, /* Double-extended width opcodes. */ - CheatVmOpcodeType_BreakProcess = 0xFF0, - CheatVmOpcodeType_ContinueProcess = 0xFF1, + CheatVmOpcodeType_PauseProcess = 0xFF0, + CheatVmOpcodeType_ResumeProcess = 0xFF1, CheatVmOpcodeType_DebugLog = 0xFFF, };