dmnt: various cheat changes/suggestions that have been cooking a while

This commit is contained in:
Michael Scire 2021-07-21 19:21:58 -07:00
parent 0c596e682f
commit 389c3b6baa
9 changed files with 74 additions and 4 deletions

View file

@ -19,6 +19,8 @@ This behavior ensures that cheat codes are only loaded when the user would want
In cases where `dmnt` has not activated the cheat manager, but the user wants to make it do so anyway, the cheat manager's service API provides a `ForceOpenCheatProcess` command that homebrew can use. This command will cause the cheat manager to try to force itself to attach to the process. In cases where `dmnt` has not activated the cheat manager, but the user wants to make it do so anyway, the cheat manager's service API provides a `ForceOpenCheatProcess` command that homebrew can use. This command will cause the cheat manager to try to force itself to attach to the process.
In cases where `dmnt` has activated the cheat manager, but the user wants to use an alternate debugger, the cheat manager's service API provides a `ForceCloseCheatProcess` command that homebrew can use. This command will cause the cheat manager to detach itself from the process.
By default, all cheat codes listed in the loaded .txt file will be toggled on. This is configurable by the user by editing the `atmosphere!dmnt_cheats_enabled_by_default` [system setting](configurations.md). By default, all cheat codes listed in the loaded .txt file will be toggled on. This is configurable by the user by editing the `atmosphere!dmnt_cheats_enabled_by_default` [system setting](configurations.md).
Users may use homebrew programs to toggle cheats on and off at runtime via the cheat manager's service API. Users may use homebrew programs to toggle cheats on and off at runtime via the cheat manager's service API.
@ -47,7 +49,7 @@ Code type 0x0 allows writing a static value to a memory address.
`0TMR00AA AAAAAAAA VVVVVVVV (VVVVVVVV)` `0TMR00AA AAAAAAAA VVVVVVVV (VVVVVVVV)`
+ T: Width of memory write (1, 2, 4, or 8 bytes). + T: Width of memory write (1, 2, 4, or 8 bytes).
+ M: Memory region to write to (0 = Main NSO, 1 = Heap). + M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr).
+ R: Register to use as an offset from memory region base. + R: Register to use as an offset from memory region base.
+ A: Immediate offset to use from memory region base. + A: Immediate offset to use from memory region base.
+ V: Value to write. + V: Value to write.
@ -63,7 +65,7 @@ If the condition is not met, all instructions until the appropriate conditional
`1TMC00AA AAAAAAAA VVVVVVVV (VVVVVVVV)` `1TMC00AA AAAAAAAA VVVVVVVV (VVVVVVVV)`
+ T: Width of memory write (1, 2, 4, or 8 bytes). + T: Width of memory write (1, 2, 4, or 8 bytes).
+ M: Memory region to write to (0 = Main NSO, 1 = Heap). + M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr).
+ C: Condition to use, see below. + C: Condition to use, see below.
+ A: Immediate offset to use from memory region base. + A: Immediate offset to use from memory region base.
+ V: Value to compare to. + V: Value to compare to.
@ -120,7 +122,7 @@ Code type 0x5 allows loading a value from memory into a register, either using a
`5TMR00AA AAAAAAAA` `5TMR00AA AAAAAAAA`
+ T: Width of memory read (1, 2, 4, or 8 bytes). + T: Width of memory read (1, 2, 4, or 8 bytes).
+ M: Memory region to write to (0 = Main NSO, 1 = Heap). + M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr).
+ R: Register to load value into. + R: Register to load value into.
+ A: Immediate offset to use from memory region base. + A: Immediate offset to use from memory region base.

View file

@ -74,6 +74,10 @@ Result dmntchtResumeCheatProcess(void) {
return _dmntchtCmdVoid(&g_dmntchtSrv, 65005); return _dmntchtCmdVoid(&g_dmntchtSrv, 65005);
} }
Result dmntchtForceCloseCheatProcess(void) {
return _dmntchtCmdVoid(&g_dmntchtSrv, 65006);
}
static Result _dmntchtGetCount(u64 *out_count, u32 cmd_id) { static Result _dmntchtGetCount(u64 *out_count, u32 cmd_id) {
return serviceDispatchOut(&g_dmntchtSrv, cmd_id, *out_count); return serviceDispatchOut(&g_dmntchtSrv, cmd_id, *out_count);
} }
@ -171,6 +175,13 @@ Result dmntchtResetStaticRegisters() {
return _dmntchtCmdVoid(&g_dmntchtSrv, 65208); return _dmntchtCmdVoid(&g_dmntchtSrv, 65208);
} }
Result dmntchtSetMasterCheat(DmntCheatDefinition *cheat_def) {
return serviceDispatch(&g_dmntchtSrv, 65209,
.buffer_attrs = { SfBufferAttr_In | SfBufferAttr_HipcMapAlias | SfBufferAttr_FixedSize },
.buffers = { { cheat_def, sizeof(*cheat_def) } },
);
}
Result dmntchtGetFrozenAddressCount(u64 *out_count) { Result dmntchtGetFrozenAddressCount(u64 *out_count) {
return _dmntchtGetCount(out_count, 65300); return _dmntchtGetCount(out_count, 65300);
} }

View file

@ -66,6 +66,7 @@ Result dmntchtHasCheatProcess(bool *out);
Result dmntchtGetCheatProcessEvent(Event *event); Result dmntchtGetCheatProcessEvent(Event *event);
Result dmntchtGetCheatProcessMetadata(DmntCheatProcessMetadata *out_metadata); Result dmntchtGetCheatProcessMetadata(DmntCheatProcessMetadata *out_metadata);
Result dmntchtForceOpenCheatProcess(void); Result dmntchtForceOpenCheatProcess(void);
Result dmntchtForceCloseCheatProcess(void);
Result dmntchtGetCheatProcessMappingCount(u64 *out_count); Result dmntchtGetCheatProcessMappingCount(u64 *out_count);
Result dmntchtGetCheatProcessMappings(MemoryInfo *buffer, u64 max_count, u64 offset, u64 *out_count); Result dmntchtGetCheatProcessMappings(MemoryInfo *buffer, u64 max_count, u64 offset, u64 *out_count);
@ -84,6 +85,7 @@ Result dmntchtRemoveCheat(u32 cheat_id);
Result dmntchtReadStaticRegister(u64 *out, u8 which); Result dmntchtReadStaticRegister(u64 *out, u8 which);
Result dmntchtWriteStaticRegister(u8 which, u64 value); Result dmntchtWriteStaticRegister(u8 which, u64 value);
Result dmntchtResetStaticRegisters(); Result dmntchtResetStaticRegisters();
Result dmntchtSetMasterCheat(DmntCheatDefinition *cheat);
Result dmntchtGetFrozenAddressCount(u64 *out_count); Result dmntchtGetFrozenAddressCount(u64 *out_count);
Result dmntchtGetFrozenAddresses(DmntFrozenAddressEntry *buffer, u64 max_count, u64 offset, u64 *out_count); Result dmntchtGetFrozenAddresses(DmntFrozenAddressEntry *buffer, u64 max_count, u64 offset, u64 *out_count);

View file

@ -48,6 +48,10 @@ namespace ams::dmnt::cheat {
return dmnt::cheat::impl::ResumeCheatProcess(); return dmnt::cheat::impl::ResumeCheatProcess();
} }
Result CheatService::ForceCloseCheatProcess() {
return dmnt::cheat::impl::ForceCloseCheatProcess();
}
/* ========================================================================================= */ /* ========================================================================================= */
/* =================================== Memory Commands =================================== */ /* =================================== Memory Commands =================================== */
/* ========================================================================================= */ /* ========================================================================================= */
@ -116,6 +120,10 @@ namespace ams::dmnt::cheat {
return dmnt::cheat::impl::ResetStaticRegisters(); return dmnt::cheat::impl::ResetStaticRegisters();
} }
Result CheatService::SetMasterCheat(const CheatDefinition &cheat) {
return dmnt::cheat::impl::SetMasterCheat(cheat);
}
/* ========================================================================================= */ /* ========================================================================================= */
/* =================================== Address Commands ================================== */ /* =================================== Address Commands ================================== */
/* ========================================================================================= */ /* ========================================================================================= */

View file

@ -24,6 +24,7 @@
AMS_SF_METHOD_INFO(C, H, 65003, Result, ForceOpenCheatProcess, (), ()) \ AMS_SF_METHOD_INFO(C, H, 65003, Result, ForceOpenCheatProcess, (), ()) \
AMS_SF_METHOD_INFO(C, H, 65004, Result, PauseCheatProcess, (), ()) \ AMS_SF_METHOD_INFO(C, H, 65004, Result, PauseCheatProcess, (), ()) \
AMS_SF_METHOD_INFO(C, H, 65005, Result, ResumeCheatProcess, (), ()) \ 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, 65100, Result, GetCheatProcessMappingCount, (sf::Out<u64> out_count), (out_count)) \
AMS_SF_METHOD_INFO(C, H, 65101, Result, GetCheatProcessMappings, (const sf::OutArray<MemoryInfo> &mappings, sf::Out<u64> out_count, u64 offset), (mappings, out_count, offset)) \ AMS_SF_METHOD_INFO(C, H, 65101, Result, GetCheatProcessMappings, (const sf::OutArray<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, 65102, Result, ReadCheatProcessMemory, (const sf::OutBuffer &buffer, u64 address, u64 out_size), (buffer, address, out_size)) \
@ -38,6 +39,7 @@
AMS_SF_METHOD_INFO(C, H, 65206, Result, ReadStaticRegister, (sf::Out<u64> out, u8 which), (out, which)) \ 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, 65207, Result, WriteStaticRegister, (u8 which, u64 value), (which, value)) \
AMS_SF_METHOD_INFO(C, H, 65208, Result, ResetStaticRegisters, (), ()) \ 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, 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, 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, 65302, Result, GetFrozenAddress, (sf::Out<dmnt::cheat::FrozenAddressEntry> entry, u64 address), (entry, address)) \
@ -56,6 +58,7 @@ namespace ams::dmnt::cheat {
Result ForceOpenCheatProcess(); Result ForceOpenCheatProcess();
Result PauseCheatProcess(); Result PauseCheatProcess();
Result ResumeCheatProcess(); Result ResumeCheatProcess();
Result ForceCloseCheatProcess();
Result GetCheatProcessMappingCount(sf::Out<u64> out_count); Result GetCheatProcessMappingCount(sf::Out<u64> out_count);
Result GetCheatProcessMappings(const sf::OutArray<MemoryInfo> &mappings, sf::Out<u64> out_count, u64 offset); Result GetCheatProcessMappings(const sf::OutArray<MemoryInfo> &mappings, sf::Out<u64> out_count, u64 offset);
@ -72,6 +75,7 @@ namespace ams::dmnt::cheat {
Result ReadStaticRegister(sf::Out<u64> out, u8 which); Result ReadStaticRegister(sf::Out<u64> out, u8 which);
Result WriteStaticRegister(u8 which, u64 value); Result WriteStaticRegister(u8 which, u64 value);
Result ResetStaticRegisters(); Result ResetStaticRegisters();
Result SetMasterCheat(const CheatDefinition &cheat);
Result GetFrozenAddressCount(sf::Out<u64> out_count); Result GetFrozenAddressCount(sf::Out<u64> out_count);
Result GetFrozenAddresses(const sf::OutArray<FrozenAddressEntry> &addresses, sf::Out<u64> out_count, u64 offset); Result GetFrozenAddresses(const sf::OutArray<FrozenAddressEntry> &addresses, sf::Out<u64> out_count, u64 offset);

View file

@ -301,6 +301,11 @@ namespace ams::dmnt::cheat::impl {
return this->AttachToApplicationProcess(false); return this->AttachToApplicationProcess(false);
} }
Result ForceCloseCheatProcess() {
this->CloseActiveCheatProcess();
return ResultSuccess();
}
Result ReadCheatProcessMemoryUnsafe(u64 proc_addr, void *out_data, size_t size) { Result ReadCheatProcessMemoryUnsafe(u64 proc_addr, void *out_data, size_t size) {
return svcReadDebugProcessMemory(out_data, this->GetCheatProcessHandle(), proc_addr, size); return svcReadDebugProcessMemory(out_data, this->GetCheatProcessHandle(), proc_addr, size);
} }
@ -520,6 +525,9 @@ namespace ams::dmnt::cheat::impl {
/* Trigger a VM reload. */ /* Trigger a VM reload. */
this->SetNeedsReloadVm(true); this->SetNeedsReloadVm(true);
/* Set output id. */
*out_id = new_entry->cheat_id;
return ResultSuccess(); return ResultSuccess();
} }
@ -537,6 +545,25 @@ namespace ams::dmnt::cheat::impl {
return ResultSuccess(); return ResultSuccess();
} }
Result SetMasterCheat(const CheatDefinition &def) {
std::scoped_lock lk(this->cheat_lock);
R_TRY(this->EnsureCheatProcess());
R_UNLESS(def.num_opcodes != 0, ResultCheatInvalid());
R_UNLESS(def.num_opcodes <= util::size(def.opcodes), ResultCheatInvalid());
CheatEntry *master_entry = this->cheat_entries + 0;
master_entry->enabled = true;
master_entry->definition = def;
/* Trigger a VM reload. */
this->SetNeedsReloadVm(true);
return ResultSuccess();
}
Result ReadStaticRegister(u64 *out, size_t which) { Result ReadStaticRegister(u64 *out, size_t which) {
std::scoped_lock lk(this->cheat_lock); std::scoped_lock lk(this->cheat_lock);
@ -1187,6 +1214,10 @@ namespace ams::dmnt::cheat::impl {
return GetReference(g_cheat_process_manager).ResumeCheatProcess(); return GetReference(g_cheat_process_manager).ResumeCheatProcess();
} }
Result ForceCloseCheatProcess() {
return GetReference(g_cheat_process_manager).ForceCloseCheatProcess();
}
Result ReadCheatProcessMemoryUnsafe(u64 process_addr, void *out_data, size_t size) { Result ReadCheatProcessMemoryUnsafe(u64 process_addr, void *out_data, size_t size) {
return GetReference(g_cheat_process_manager).ReadCheatProcessMemoryUnsafe(process_addr, out_data, size); return GetReference(g_cheat_process_manager).ReadCheatProcessMemoryUnsafe(process_addr, out_data, size);
} }
@ -1247,6 +1278,10 @@ namespace ams::dmnt::cheat::impl {
return GetReference(g_cheat_process_manager).RemoveCheat(cheat_id); return GetReference(g_cheat_process_manager).RemoveCheat(cheat_id);
} }
Result SetMasterCheat(const CheatDefinition &def) {
return GetReference(g_cheat_process_manager).SetMasterCheat(def);
}
Result ReadStaticRegister(u64 *out, size_t which) { Result ReadStaticRegister(u64 *out, size_t which) {
return GetReference(g_cheat_process_manager).ReadStaticRegister(out, which); return GetReference(g_cheat_process_manager).ReadStaticRegister(out, which);
} }

View file

@ -26,6 +26,7 @@ namespace ams::dmnt::cheat::impl {
Result ForceOpenCheatProcess(); Result ForceOpenCheatProcess();
Result PauseCheatProcess(); Result PauseCheatProcess();
Result ResumeCheatProcess(); Result ResumeCheatProcess();
Result ForceCloseCheatProcess();
Result ReadCheatProcessMemoryUnsafe(u64 process_addr, void *out_data, size_t size); Result ReadCheatProcessMemoryUnsafe(u64 process_addr, void *out_data, size_t size);
Result WriteCheatProcessMemoryUnsafe(u64 process_addr, void *data, size_t size); Result WriteCheatProcessMemoryUnsafe(u64 process_addr, void *data, size_t size);
@ -45,6 +46,7 @@ namespace ams::dmnt::cheat::impl {
Result ToggleCheat(u32 cheat_id); Result ToggleCheat(u32 cheat_id);
Result AddCheat(u32 *out_id, const CheatDefinition &def, bool enabled); Result AddCheat(u32 *out_id, const CheatDefinition &def, bool enabled);
Result RemoveCheat(u32 cheat_id); Result RemoveCheat(u32 cheat_id);
Result SetMasterCheat(const CheatDefinition &def);
Result ReadStaticRegister(u64 *out, size_t which); Result ReadStaticRegister(u64 *out, size_t which);
Result WriteStaticRegister(size_t which, u64 value); Result WriteStaticRegister(size_t which, u64 value);
Result ResetStaticRegisters(); Result ResetStaticRegisters();

View file

@ -721,6 +721,10 @@ namespace ams::dmnt::cheat::impl {
return metadata->main_nso_extents.base + rel_address; return metadata->main_nso_extents.base + rel_address;
case MemoryAccessType_Heap: case MemoryAccessType_Heap:
return metadata->heap_extents.base + rel_address; return metadata->heap_extents.base + rel_address;
case MemoryAccessType_Alias:
return metadata->alias_extents.base + rel_address;
case MemoryAccessType_Aslr:
return metadata->aslr_extents.base + rel_address;
} }
} }

View file

@ -56,7 +56,9 @@ namespace ams::dmnt::cheat::impl {
enum MemoryAccessType : u32 { enum MemoryAccessType : u32 {
MemoryAccessType_MainNso = 0, MemoryAccessType_MainNso = 0,
MemoryAccessType_Heap = 1, MemoryAccessType_Heap = 1,
MemoryAccessType_Alias = 2,
MemoryAccessType_Aslr = 3,
}; };
enum ConditionalComparisonType : u32 { enum ConditionalComparisonType : u32 {