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 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).
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)`
+ 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.
+ A: Immediate offset to use from memory region base.
+ V: Value to write.
@ -63,7 +65,7 @@ If the condition is not met, all instructions until the appropriate conditional
`1TMC00AA 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).
+ M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr).
+ C: Condition to use, see below.
+ A: Immediate offset to use from memory region base.
+ 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`
+ 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.
+ A: Immediate offset to use from memory region base.

View file

@ -74,6 +74,10 @@ Result dmntchtResumeCheatProcess(void) {
return _dmntchtCmdVoid(&g_dmntchtSrv, 65005);
}
Result dmntchtForceCloseCheatProcess(void) {
return _dmntchtCmdVoid(&g_dmntchtSrv, 65006);
}
static Result _dmntchtGetCount(u64 *out_count, u32 cmd_id) {
return serviceDispatchOut(&g_dmntchtSrv, cmd_id, *out_count);
}
@ -171,6 +175,13 @@ Result dmntchtResetStaticRegisters() {
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) {
return _dmntchtGetCount(out_count, 65300);
}

View file

@ -66,6 +66,7 @@ Result dmntchtHasCheatProcess(bool *out);
Result dmntchtGetCheatProcessEvent(Event *event);
Result dmntchtGetCheatProcessMetadata(DmntCheatProcessMetadata *out_metadata);
Result dmntchtForceOpenCheatProcess(void);
Result dmntchtForceCloseCheatProcess(void);
Result dmntchtGetCheatProcessMappingCount(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 dmntchtWriteStaticRegister(u8 which, u64 value);
Result dmntchtResetStaticRegisters();
Result dmntchtSetMasterCheat(DmntCheatDefinition *cheat);
Result dmntchtGetFrozenAddressCount(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();
}
Result CheatService::ForceCloseCheatProcess() {
return dmnt::cheat::impl::ForceCloseCheatProcess();
}
/* ========================================================================================= */
/* =================================== Memory Commands =================================== */
/* ========================================================================================= */
@ -116,6 +120,10 @@ namespace ams::dmnt::cheat {
return dmnt::cheat::impl::ResetStaticRegisters();
}
Result CheatService::SetMasterCheat(const CheatDefinition &cheat) {
return dmnt::cheat::impl::SetMasterCheat(cheat);
}
/* ========================================================================================= */
/* =================================== Address Commands ================================== */
/* ========================================================================================= */

View file

@ -24,6 +24,7 @@
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<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)) \
@ -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, 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)) \
@ -56,6 +58,7 @@ namespace ams::dmnt::cheat {
Result ForceOpenCheatProcess();
Result PauseCheatProcess();
Result ResumeCheatProcess();
Result ForceCloseCheatProcess();
Result GetCheatProcessMappingCount(sf::Out<u64> out_count);
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 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);

View file

@ -301,6 +301,11 @@ namespace ams::dmnt::cheat::impl {
return this->AttachToApplicationProcess(false);
}
Result ForceCloseCheatProcess() {
this->CloseActiveCheatProcess();
return ResultSuccess();
}
Result ReadCheatProcessMemoryUnsafe(u64 proc_addr, void *out_data, size_t size) {
return svcReadDebugProcessMemory(out_data, this->GetCheatProcessHandle(), proc_addr, size);
}
@ -520,6 +525,9 @@ namespace ams::dmnt::cheat::impl {
/* Trigger a VM reload. */
this->SetNeedsReloadVm(true);
/* Set output id. */
*out_id = new_entry->cheat_id;
return ResultSuccess();
}
@ -537,6 +545,25 @@ namespace ams::dmnt::cheat::impl {
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) {
std::scoped_lock lk(this->cheat_lock);
@ -1187,6 +1214,10 @@ namespace ams::dmnt::cheat::impl {
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) {
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);
}
Result SetMasterCheat(const CheatDefinition &def) {
return GetReference(g_cheat_process_manager).SetMasterCheat(def);
}
Result ReadStaticRegister(u64 *out, size_t which) {
return GetReference(g_cheat_process_manager).ReadStaticRegister(out, which);
}

View file

@ -26,6 +26,7 @@ namespace ams::dmnt::cheat::impl {
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);
@ -45,6 +46,7 @@ namespace ams::dmnt::cheat::impl {
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();

View file

@ -721,6 +721,10 @@ namespace ams::dmnt::cheat::impl {
return metadata->main_nso_extents.base + rel_address;
case MemoryAccessType_Heap:
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

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