diff options
| -rw-r--r-- | src/core/memory/cheat_engine.cpp | 25 | ||||
| -rw-r--r-- | src/core/memory/cheat_engine.h | 6 | ||||
| -rw-r--r-- | src/core/memory/dmnt_cheat_vm.cpp | 17 | ||||
| -rw-r--r-- | src/core/memory/dmnt_cheat_vm.h | 4 |
4 files changed, 32 insertions, 20 deletions
diff --git a/src/core/memory/cheat_engine.cpp b/src/core/memory/cheat_engine.cpp index 7a8c14c2b..14d1a3840 100644 --- a/src/core/memory/cheat_engine.cpp +++ b/src/core/memory/cheat_engine.cpp | |||
| @@ -47,12 +47,23 @@ StandardVmCallbacks::StandardVmCallbacks(System& system_, const CheatProcessMeta | |||
| 47 | 47 | ||
| 48 | StandardVmCallbacks::~StandardVmCallbacks() = default; | 48 | StandardVmCallbacks::~StandardVmCallbacks() = default; |
| 49 | 49 | ||
| 50 | void StandardVmCallbacks::MemoryRead(VAddr address, void* data, u64 size) { | 50 | void StandardVmCallbacks::MemoryReadUnsafe(VAddr address, void* data, u64 size) { |
| 51 | system.ApplicationMemory().ReadBlock(SanitizeAddress(address), data, size); | 51 | // Return zero on invalid address |
| 52 | if (!IsAddressInRange(address) || !system.ApplicationMemory().IsValidVirtualAddress(address)) { | ||
| 53 | std::memset(data, 0, size); | ||
| 54 | return; | ||
| 55 | } | ||
| 56 | |||
| 57 | system.ApplicationMemory().ReadBlock(address, data, size); | ||
| 52 | } | 58 | } |
| 53 | 59 | ||
| 54 | void StandardVmCallbacks::MemoryWrite(VAddr address, const void* data, u64 size) { | 60 | void StandardVmCallbacks::MemoryWriteUnsafe(VAddr address, const void* data, u64 size) { |
| 55 | system.ApplicationMemory().WriteBlock(SanitizeAddress(address), data, size); | 61 | // Skip invalid memory write address |
| 62 | if (!IsAddressInRange(address) || !system.ApplicationMemory().IsValidVirtualAddress(address)) { | ||
| 63 | return; | ||
| 64 | } | ||
| 65 | |||
| 66 | system.ApplicationMemory().WriteBlock(address, data, size); | ||
| 56 | } | 67 | } |
| 57 | 68 | ||
| 58 | u64 StandardVmCallbacks::HidKeysDown() { | 69 | u64 StandardVmCallbacks::HidKeysDown() { |
| @@ -82,7 +93,7 @@ void StandardVmCallbacks::CommandLog(std::string_view data) { | |||
| 82 | data.back() == '\n' ? data.substr(0, data.size() - 1) : data); | 93 | data.back() == '\n' ? data.substr(0, data.size() - 1) : data); |
| 83 | } | 94 | } |
| 84 | 95 | ||
| 85 | VAddr StandardVmCallbacks::SanitizeAddress(VAddr in) const { | 96 | bool StandardVmCallbacks::IsAddressInRange(VAddr in) const { |
| 86 | if ((in < metadata.main_nso_extents.base || | 97 | if ((in < metadata.main_nso_extents.base || |
| 87 | in >= metadata.main_nso_extents.base + metadata.main_nso_extents.size) && | 98 | in >= metadata.main_nso_extents.base + metadata.main_nso_extents.size) && |
| 88 | (in < metadata.heap_extents.base || | 99 | (in < metadata.heap_extents.base || |
| @@ -97,10 +108,10 @@ VAddr StandardVmCallbacks::SanitizeAddress(VAddr in) const { | |||
| 97 | "the cheat may be incorrect. However, this may be normal early in execution if " | 108 | "the cheat may be incorrect. However, this may be normal early in execution if " |
| 98 | "the game has not properly set up yet.", | 109 | "the game has not properly set up yet.", |
| 99 | in); | 110 | in); |
| 100 | return 0; ///< Invalid addresses will hard crash | 111 | return false; ///< Invalid addresses will hard crash |
| 101 | } | 112 | } |
| 102 | 113 | ||
| 103 | return in; | 114 | return true; |
| 104 | } | 115 | } |
| 105 | 116 | ||
| 106 | CheatParser::~CheatParser() = default; | 117 | CheatParser::~CheatParser() = default; |
diff --git a/src/core/memory/cheat_engine.h b/src/core/memory/cheat_engine.h index 64a9c486b..619cabaa2 100644 --- a/src/core/memory/cheat_engine.h +++ b/src/core/memory/cheat_engine.h | |||
| @@ -27,14 +27,14 @@ public: | |||
| 27 | StandardVmCallbacks(System& system_, const CheatProcessMetadata& metadata_); | 27 | StandardVmCallbacks(System& system_, const CheatProcessMetadata& metadata_); |
| 28 | ~StandardVmCallbacks() override; | 28 | ~StandardVmCallbacks() override; |
| 29 | 29 | ||
| 30 | void MemoryRead(VAddr address, void* data, u64 size) override; | 30 | void MemoryReadUnsafe(VAddr address, void* data, u64 size) override; |
| 31 | void MemoryWrite(VAddr address, const void* data, u64 size) override; | 31 | void MemoryWriteUnsafe(VAddr address, const void* data, u64 size) override; |
| 32 | u64 HidKeysDown() override; | 32 | u64 HidKeysDown() override; |
| 33 | void DebugLog(u8 id, u64 value) override; | 33 | void DebugLog(u8 id, u64 value) override; |
| 34 | void CommandLog(std::string_view data) override; | 34 | void CommandLog(std::string_view data) override; |
| 35 | 35 | ||
| 36 | private: | 36 | private: |
| 37 | VAddr SanitizeAddress(VAddr address) const; | 37 | bool IsAddressInRange(VAddr address) const; |
| 38 | 38 | ||
| 39 | const CheatProcessMetadata& metadata; | 39 | const CheatProcessMetadata& metadata; |
| 40 | Core::System& system; | 40 | Core::System& system; |
diff --git a/src/core/memory/dmnt_cheat_vm.cpp b/src/core/memory/dmnt_cheat_vm.cpp index 9424e0f73..8bc81e72d 100644 --- a/src/core/memory/dmnt_cheat_vm.cpp +++ b/src/core/memory/dmnt_cheat_vm.cpp | |||
| @@ -773,7 +773,7 @@ void DmntCheatVm::Execute(const CheatProcessMetadata& metadata) { | |||
| 773 | case 2: | 773 | case 2: |
| 774 | case 4: | 774 | case 4: |
| 775 | case 8: | 775 | case 8: |
| 776 | callbacks->MemoryWrite(dst_address, &dst_value, store_static->bit_width); | 776 | callbacks->MemoryWriteUnsafe(dst_address, &dst_value, store_static->bit_width); |
| 777 | break; | 777 | break; |
| 778 | } | 778 | } |
| 779 | } else if (auto begin_cond = std::get_if<BeginConditionalOpcode>(&cur_opcode.opcode)) { | 779 | } else if (auto begin_cond = std::get_if<BeginConditionalOpcode>(&cur_opcode.opcode)) { |
| @@ -786,7 +786,7 @@ void DmntCheatVm::Execute(const CheatProcessMetadata& metadata) { | |||
| 786 | case 2: | 786 | case 2: |
| 787 | case 4: | 787 | case 4: |
| 788 | case 8: | 788 | case 8: |
| 789 | callbacks->MemoryRead(src_address, &src_value, begin_cond->bit_width); | 789 | callbacks->MemoryReadUnsafe(src_address, &src_value, begin_cond->bit_width); |
| 790 | break; | 790 | break; |
| 791 | } | 791 | } |
| 792 | // Check against condition. | 792 | // Check against condition. |
| @@ -857,8 +857,8 @@ void DmntCheatVm::Execute(const CheatProcessMetadata& metadata) { | |||
| 857 | case 2: | 857 | case 2: |
| 858 | case 4: | 858 | case 4: |
| 859 | case 8: | 859 | case 8: |
| 860 | callbacks->MemoryRead(src_address, ®isters[ldr_memory->reg_index], | 860 | callbacks->MemoryReadUnsafe(src_address, ®isters[ldr_memory->reg_index], |
| 861 | ldr_memory->bit_width); | 861 | ldr_memory->bit_width); |
| 862 | break; | 862 | break; |
| 863 | } | 863 | } |
| 864 | } else if (auto str_static = std::get_if<StoreStaticToAddressOpcode>(&cur_opcode.opcode)) { | 864 | } else if (auto str_static = std::get_if<StoreStaticToAddressOpcode>(&cur_opcode.opcode)) { |
| @@ -874,7 +874,7 @@ void DmntCheatVm::Execute(const CheatProcessMetadata& metadata) { | |||
| 874 | case 2: | 874 | case 2: |
| 875 | case 4: | 875 | case 4: |
| 876 | case 8: | 876 | case 8: |
| 877 | callbacks->MemoryWrite(dst_address, &dst_value, str_static->bit_width); | 877 | callbacks->MemoryWriteUnsafe(dst_address, &dst_value, str_static->bit_width); |
| 878 | break; | 878 | break; |
| 879 | } | 879 | } |
| 880 | // Increment register if relevant. | 880 | // Increment register if relevant. |
| @@ -1032,7 +1032,7 @@ void DmntCheatVm::Execute(const CheatProcessMetadata& metadata) { | |||
| 1032 | case 2: | 1032 | case 2: |
| 1033 | case 4: | 1033 | case 4: |
| 1034 | case 8: | 1034 | case 8: |
| 1035 | callbacks->MemoryWrite(dst_address, &dst_value, str_register->bit_width); | 1035 | callbacks->MemoryWriteUnsafe(dst_address, &dst_value, str_register->bit_width); |
| 1036 | break; | 1036 | break; |
| 1037 | } | 1037 | } |
| 1038 | 1038 | ||
| @@ -1111,7 +1111,8 @@ void DmntCheatVm::Execute(const CheatProcessMetadata& metadata) { | |||
| 1111 | case 2: | 1111 | case 2: |
| 1112 | case 4: | 1112 | case 4: |
| 1113 | case 8: | 1113 | case 8: |
| 1114 | callbacks->MemoryRead(cond_address, &cond_value, begin_reg_cond->bit_width); | 1114 | callbacks->MemoryReadUnsafe(cond_address, &cond_value, |
| 1115 | begin_reg_cond->bit_width); | ||
| 1115 | break; | 1116 | break; |
| 1116 | } | 1117 | } |
| 1117 | } | 1118 | } |
| @@ -1253,7 +1254,7 @@ void DmntCheatVm::Execute(const CheatProcessMetadata& metadata) { | |||
| 1253 | case 2: | 1254 | case 2: |
| 1254 | case 4: | 1255 | case 4: |
| 1255 | case 8: | 1256 | case 8: |
| 1256 | callbacks->MemoryRead(val_address, &log_value, debug_log->bit_width); | 1257 | callbacks->MemoryReadUnsafe(val_address, &log_value, debug_log->bit_width); |
| 1257 | break; | 1258 | break; |
| 1258 | } | 1259 | } |
| 1259 | } | 1260 | } |
diff --git a/src/core/memory/dmnt_cheat_vm.h b/src/core/memory/dmnt_cheat_vm.h index 32797dcd7..fed6a24ad 100644 --- a/src/core/memory/dmnt_cheat_vm.h +++ b/src/core/memory/dmnt_cheat_vm.h | |||
| @@ -266,8 +266,8 @@ public: | |||
| 266 | public: | 266 | public: |
| 267 | virtual ~Callbacks(); | 267 | virtual ~Callbacks(); |
| 268 | 268 | ||
| 269 | virtual void MemoryRead(VAddr address, void* data, u64 size) = 0; | 269 | virtual void MemoryReadUnsafe(VAddr address, void* data, u64 size) = 0; |
| 270 | virtual void MemoryWrite(VAddr address, const void* data, u64 size) = 0; | 270 | virtual void MemoryWriteUnsafe(VAddr address, const void* data, u64 size) = 0; |
| 271 | 271 | ||
| 272 | virtual u64 HidKeysDown() = 0; | 272 | virtual u64 HidKeysDown() = 0; |
| 273 | 273 | ||