From 38ed75cc003776a43a0e8995a5380e711c98cbf6 Mon Sep 17 00:00:00 2001 From: tomvita <68505331+tomvita@users.noreply.github.com> Date: Wed, 8 Jan 2025 12:51:21 +0800 Subject: [PATCH] Add type 1 extension --- docs/features/cheats.md | 15 ++++++++++----- .../dmnt/source/cheat/impl/dmnt_cheat_vm.cpp | 6 +++++- .../dmnt/source/cheat/impl/dmnt_cheat_vm.hpp | 2 ++ 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/docs/features/cheats.md b/docs/features/cheats.md index 4abe85f8c..5ba49f5bc 100644 --- a/docs/features/cheats.md +++ b/docs/features/cheats.md @@ -62,11 +62,13 @@ Code type 0x1 performs a comparison of the contents of memory to a static value. If the condition is not met, all instructions until the appropriate End or Else conditional block terminator are skipped. #### Encoding -`1TMC00AA AAAAAAAA VVVVVVVV (VVVVVVVV)` +`1TMCXrAA AAAAAAAA VVVVVVVV (VVVVVVVV)` -+ T: Width of memory write (1, 2, 4, or 8 bytes). -+ M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr). ++ T: Width of memory read (1, 2, 4, or 8 bytes). ++ M: Memory region to read from (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr, 4 = none). + C: Condition to use, see below. ++ X: Operand Type, see below. ++ r: Offset Register (operand types 1). + A: Immediate offset to use from memory region base. + V: Value to compare to. @@ -78,6 +80,9 @@ If the condition is not met, all instructions until the appropriate End or Else + 5: == + 6: != +#### Operand Type ++ 0: Memory Base + Relative Offset ++ 1: Memory Base + Offset Register + Relative Offset --- ### Code Type 0x2: End Conditional Block @@ -126,7 +131,7 @@ Code type 0x5 allows loading a value from memory into a register, either using a `5TMR00AA AAAAAAAA` + T: Width of memory read (1, 2, 4, or 8 bytes). -+ M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr). ++ M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr, 4 = none). + R: Register to load value into. + A: Immediate offset to use from memory region base. @@ -149,7 +154,7 @@ Code type 0x5 allows loading a value from memory into a register, either using a `5TMR3SAA AAAAAAAA` + T: Width of memory read (1, 2, 4, or 8 bytes). -+ M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr). ++ M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr, 4 = none). + R: Register to load value into. + S: Register to use as offset register. + A: Immediate offset to use from memory region base. diff --git a/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.cpp b/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.cpp index 9576b465f..be3cfd246 100644 --- a/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.cpp +++ b/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.cpp @@ -108,6 +108,8 @@ namespace ams::dmnt::cheat::impl { this->LogToDebugFile("Bit Width: %x\n", opcode->begin_cond.bit_width); this->LogToDebugFile("Mem Type: %x\n", opcode->begin_cond.mem_type); this->LogToDebugFile("Cond Type: %x\n", opcode->begin_cond.cond_type); + this->LogToDebugFile("Inc Ofs reg: %d\n", opcode->begin_cond.include_ofs_reg); + this->LogToDebugFile("Ofs Reg Idx: %x\n", opcode->begin_cond.ofs_reg_index); this->LogToDebugFile("Rel Addr: %lx\n", opcode->begin_cond.rel_address); this->LogToDebugFile("Value: %lx\n", opcode->begin_cond.value.bit64); break; @@ -400,6 +402,8 @@ namespace ams::dmnt::cheat::impl { opcode.begin_cond.bit_width = (first_dword >> 24) & 0xF; opcode.begin_cond.mem_type = (MemoryAccessType)((first_dword >> 20) & 0xF); opcode.begin_cond.cond_type = (ConditionalComparisonType)((first_dword >> 16) & 0xF); + opcode.begin_cond.include_ofs_reg = ((first_dword >> 12) & 0xF) != 0; + opcode.begin_cond.ofs_reg_index = ((first_dword >> 8) & 0xF); opcode.begin_cond.rel_address = ((u64)(first_dword & 0xFF) << 32ul) | ((u64)second_dword); opcode.begin_cond.value = GetNextVmInt(opcode.begin_cond.bit_width); } @@ -856,7 +860,7 @@ namespace ams::dmnt::cheat::impl { case CheatVmOpcodeType_BeginConditionalBlock: { /* Read value from memory. */ - u64 src_address = GetCheatProcessAddress(metadata, cur_opcode.begin_cond.mem_type, cur_opcode.begin_cond.rel_address); + u64 src_address = GetCheatProcessAddress(metadata, cur_opcode.begin_cond.mem_type, (cur_opcode.begin_cond.include_ofs_reg) ? m_registers[cur_opcode.begin_cond.ofs_reg_index] + cur_opcode.begin_cond.rel_address : cur_opcode.begin_cond.rel_address); u64 src_value = 0; switch (cur_opcode.store_static.bit_width) { case 1: diff --git a/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.hpp b/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.hpp index a42d9c4cc..530dc490b 100644 --- a/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.hpp +++ b/stratosphere/dmnt/source/cheat/impl/dmnt_cheat_vm.hpp @@ -145,6 +145,8 @@ namespace ams::dmnt::cheat::impl { u32 bit_width; MemoryAccessType mem_type; ConditionalComparisonType cond_type; + bool include_ofs_reg; + u32 ofs_reg_index; u64 rel_address; VmInt value; };