dmnt: move stuff around slightly, add client bindings

This commit is contained in:
Michael Scire 2020-04-24 17:24:15 -07:00
parent be07035954
commit 1d40a08ef9
9 changed files with 95 additions and 51 deletions

View file

@ -33,6 +33,16 @@
+ A reimplementation was added for the `jpegdec` system module (thanks @HookedBehemoth)! + 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. + 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. + 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 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 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). + A number of other minor issues were addressed (and more of Atmosphere was updated to reflect other changes in 10.0.x).

View file

@ -58,8 +58,20 @@ Result dmntchtGetCheatProcessMetadata(DmntCheatProcessMetadata *out_metadata) {
return serviceDispatchOut(&g_dmntchtSrv, 65002, *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) { 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) { static Result _dmntchtGetCount(u64 *out_count, u32 cmd_id) {
@ -142,6 +154,23 @@ Result dmntchtRemoveCheat(u32 cheat_id) {
return _dmntchtCmdInU32NoOut(cheat_id, 65205); 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) { Result dmntchtGetFrozenAddressCount(u64 *out_count) {
return _dmntchtGetCount(out_count, 65300); return _dmntchtGetCount(out_count, 65300);
} }

View file

@ -74,6 +74,8 @@ Result dmntchtGetCheatProcessMappings(MemoryInfo *buffer, u64 max_count, u64 off
Result dmntchtReadCheatProcessMemory(u64 address, void *buffer, size_t size); Result dmntchtReadCheatProcessMemory(u64 address, void *buffer, size_t size);
Result dmntchtWriteCheatProcessMemory(u64 address, const void *buffer, size_t size); Result dmntchtWriteCheatProcessMemory(u64 address, const void *buffer, size_t size);
Result dmntchtQueryCheatProcessMemory(MemoryInfo *mem_info, u64 address); Result dmntchtQueryCheatProcessMemory(MemoryInfo *mem_info, u64 address);
Result dmntchtPauseCheatProcess(void);
Result dmntchtResumeCheatProcess(void);
Result dmntchtGetCheatCount(u64 *out_count); Result dmntchtGetCheatCount(u64 *out_count);
Result dmntchtGetCheats(DmntCheatEntry *buffer, u64 max_count, u64 offset, 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 dmntchtToggleCheat(u32 cheat_id);
Result dmntchtAddCheat(DmntCheatDefinition *cheat, bool enabled, u32 *out_cheat_id); Result dmntchtAddCheat(DmntCheatDefinition *cheat, bool enabled, u32 *out_cheat_id);
Result dmntchtRemoveCheat(u32 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 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

@ -39,6 +39,14 @@ namespace ams::dmnt::cheat {
return ResultSuccess(); return ResultSuccess();
} }
Result CheatService::PauseCheatProcess() {
return dmnt::cheat::impl::PauseCheatProcess();
}
Result CheatService::ResumeCheatProcess() {
return dmnt::cheat::impl::ResumeCheatProcess();
}
/* ========================================================================================= */ /* ========================================================================================= */
/* =================================== Memory Commands =================================== */ /* =================================== Memory Commands =================================== */
/* ========================================================================================= */ /* ========================================================================================= */
@ -66,14 +74,6 @@ namespace ams::dmnt::cheat {
return dmnt::cheat::impl::QueryCheatProcessMemory(mapping.GetPointer(), address); 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 ==================================== */ /* =================================== Cheat Commands ==================================== */
/* ========================================================================================= */ /* ========================================================================================= */

View file

@ -26,6 +26,8 @@ namespace ams::dmnt::cheat {
GetCheatProcessEvent = 65001, GetCheatProcessEvent = 65001,
GetCheatProcessMetadata = 65002, GetCheatProcessMetadata = 65002,
ForceOpenCheatProcess = 65003, ForceOpenCheatProcess = 65003,
PauseCheatProcess = 65004,
ResumeCheatProcess = 65005,
/* Interact with Memory */ /* Interact with Memory */
GetCheatProcessMappingCount = 65100, GetCheatProcessMappingCount = 65100,
@ -33,8 +35,6 @@ namespace ams::dmnt::cheat {
ReadCheatProcessMemory = 65102, ReadCheatProcessMemory = 65102,
WriteCheatProcessMemory = 65103, WriteCheatProcessMemory = 65103,
QueryCheatProcessMemory = 65104, QueryCheatProcessMemory = 65104,
BreakCheatProcess = 65105,
ContinueCheatProcess = 65106,
/* Interact with Cheats */ /* Interact with Cheats */
GetCheatCount = 65200, GetCheatCount = 65200,
@ -59,14 +59,14 @@ namespace ams::dmnt::cheat {
void GetCheatProcessEvent(sf::OutCopyHandle out_event); void GetCheatProcessEvent(sf::OutCopyHandle out_event);
Result GetCheatProcessMetadata(sf::Out<CheatProcessMetadata> out_metadata); Result GetCheatProcessMetadata(sf::Out<CheatProcessMetadata> out_metadata);
Result ForceOpenCheatProcess(); Result ForceOpenCheatProcess();
Result PauseCheatProcess();
Result ResumeCheatProcess();
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);
Result ReadCheatProcessMemory(const sf::OutBuffer &buffer, u64 address, u64 out_size); Result ReadCheatProcessMemory(const sf::OutBuffer &buffer, u64 address, u64 out_size);
Result WriteCheatProcessMemory(const sf::InBuffer &buffer, u64 address, u64 in_size); Result WriteCheatProcessMemory(const sf::InBuffer &buffer, u64 address, u64 in_size);
Result QueryCheatProcessMemory(sf::Out<MemoryInfo> mapping, u64 address); Result QueryCheatProcessMemory(sf::Out<MemoryInfo> mapping, u64 address);
Result BreakCheatProcess();
Result ContinueCheatProcess();
Result GetCheatCount(sf::Out<u64> out_count); Result GetCheatCount(sf::Out<u64> out_count);
Result GetCheats(const sf::OutArray<CheatEntry> &cheats, sf::Out<u64> out_count, u64 offset); Result GetCheats(const sf::OutArray<CheatEntry> &cheats, sf::Out<u64> out_count, u64 offset);
@ -90,14 +90,14 @@ namespace ams::dmnt::cheat {
MAKE_SERVICE_COMMAND_META(GetCheatProcessEvent), MAKE_SERVICE_COMMAND_META(GetCheatProcessEvent),
MAKE_SERVICE_COMMAND_META(GetCheatProcessMetadata), MAKE_SERVICE_COMMAND_META(GetCheatProcessMetadata),
MAKE_SERVICE_COMMAND_META(ForceOpenCheatProcess), MAKE_SERVICE_COMMAND_META(ForceOpenCheatProcess),
MAKE_SERVICE_COMMAND_META(PauseCheatProcess),
MAKE_SERVICE_COMMAND_META(ResumeCheatProcess),
MAKE_SERVICE_COMMAND_META(GetCheatProcessMappingCount), MAKE_SERVICE_COMMAND_META(GetCheatProcessMappingCount),
MAKE_SERVICE_COMMAND_META(GetCheatProcessMappings), MAKE_SERVICE_COMMAND_META(GetCheatProcessMappings),
MAKE_SERVICE_COMMAND_META(ReadCheatProcessMemory), MAKE_SERVICE_COMMAND_META(ReadCheatProcessMemory),
MAKE_SERVICE_COMMAND_META(WriteCheatProcessMemory), MAKE_SERVICE_COMMAND_META(WriteCheatProcessMemory),
MAKE_SERVICE_COMMAND_META(QueryCheatProcessMemory), MAKE_SERVICE_COMMAND_META(QueryCheatProcessMemory),
MAKE_SERVICE_COMMAND_META(BreakCheatProcess),
MAKE_SERVICE_COMMAND_META(ContinueCheatProcess),
MAKE_SERVICE_COMMAND_META(GetCheatCount), MAKE_SERVICE_COMMAND_META(GetCheatCount),
MAKE_SERVICE_COMMAND_META(GetCheats), MAKE_SERVICE_COMMAND_META(GetCheats),

View file

@ -265,13 +265,13 @@ namespace ams::dmnt::cheat::impl {
return ResultSuccess(); return ResultSuccess();
} }
Result BreakCheatProcessUnsafe() { Result PauseCheatProcessUnsafe() {
this->broken_unsafe = true; this->broken_unsafe = true;
this->unsafe_break_event.Clear(); this->unsafe_break_event.Clear();
return svcBreakDebugProcess(this->GetCheatProcessHandle()); return svcBreakDebugProcess(this->GetCheatProcessHandle());
} }
Result ContinueCheatProcessUnsafe() { Result ResumeCheatProcessUnsafe() {
this->broken_unsafe = false; this->broken_unsafe = false;
this->unsafe_break_event.Signal(); this->unsafe_break_event.Signal();
dmnt::cheat::impl::ContinueCheatProcess(this->GetCheatProcessHandle()); dmnt::cheat::impl::ContinueCheatProcess(this->GetCheatProcessHandle());
@ -356,20 +356,20 @@ namespace ams::dmnt::cheat::impl {
return svcQueryDebugProcessMemory(mapping, &tmp, this->GetCheatProcessHandle(), address); return svcQueryDebugProcessMemory(mapping, &tmp, this->GetCheatProcessHandle(), address);
} }
Result BreakCheatProcess() { Result PauseCheatProcess() {
std::scoped_lock lk(this->cheat_lock); std::scoped_lock lk(this->cheat_lock);
R_TRY(this->EnsureCheatProcess()); R_TRY(this->EnsureCheatProcess());
return this->BreakCheatProcessUnsafe(); return this->PauseCheatProcessUnsafe();
} }
Result ContinueCheatProcess() { Result ResumeCheatProcess() {
std::scoped_lock lk(this->cheat_lock); std::scoped_lock lk(this->cheat_lock);
R_TRY(this->EnsureCheatProcess()); R_TRY(this->EnsureCheatProcess());
return this->ContinueCheatProcessUnsafe(); return this->ResumeCheatProcessUnsafe();
} }
Result GetCheatCount(u64 *out_count) { Result GetCheatCount(u64 *out_count) {
@ -1096,6 +1096,14 @@ namespace ams::dmnt::cheat::impl {
return GetReference(g_cheat_process_manager).ForceOpenCheatProcess(); 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) { 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);
} }
@ -1104,12 +1112,12 @@ namespace ams::dmnt::cheat::impl {
return GetReference(g_cheat_process_manager).WriteCheatProcessMemoryUnsafe(process_addr, data, size); return GetReference(g_cheat_process_manager).WriteCheatProcessMemoryUnsafe(process_addr, data, size);
} }
Result BreakCheatProcessUnsafe() { Result PauseCheatProcessUnsafe() {
return GetReference(g_cheat_process_manager).BreakCheatProcessUnsafe(); return GetReference(g_cheat_process_manager).PauseCheatProcessUnsafe();
} }
Result ContinueCheatProcessUnsafe() { Result ResumeCheatProcessUnsafe() {
return GetReference(g_cheat_process_manager).ContinueCheatProcessUnsafe(); return GetReference(g_cheat_process_manager).ResumeCheatProcessUnsafe();
} }
Result GetCheatProcessMappingCount(u64 *out_count) { Result GetCheatProcessMappingCount(u64 *out_count) {
@ -1132,14 +1140,6 @@ namespace ams::dmnt::cheat::impl {
return GetReference(g_cheat_process_manager).QueryCheatProcessMemory(mapping, address); 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) { Result GetCheatCount(u64 *out_count) {
return GetReference(g_cheat_process_manager).GetCheatCount(out_count); return GetReference(g_cheat_process_manager).GetCheatCount(out_count);
} }

View file

@ -24,20 +24,20 @@ namespace ams::dmnt::cheat::impl {
Handle GetCheatProcessEventHandle(); Handle GetCheatProcessEventHandle();
Result GetCheatProcessMetadata(CheatProcessMetadata *out); Result GetCheatProcessMetadata(CheatProcessMetadata *out);
Result ForceOpenCheatProcess(); Result ForceOpenCheatProcess();
Result PauseCheatProcess();
Result ResumeCheatProcess();
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);
Result BreakCheatProcessUnsafe(); Result PauseCheatProcessUnsafe();
Result ContinueCheatProcessUnsafe(); Result ResumeCheatProcessUnsafe();
Result GetCheatProcessMappingCount(u64 *out_count); Result GetCheatProcessMappingCount(u64 *out_count);
Result GetCheatProcessMappings(MemoryInfo *mappings, size_t max_count, u64 *out_count, u64 offset); 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 ReadCheatProcessMemory(u64 proc_addr, void *out_data, size_t size);
Result WriteCheatProcessMemory(u64 proc_addr, const void *data, size_t size); Result WriteCheatProcessMemory(u64 proc_addr, const void *data, size_t size);
Result QueryCheatProcessMemory(MemoryInfo *mapping, u64 address); Result QueryCheatProcessMemory(MemoryInfo *mapping, u64 address);
Result BreakCheatProcess();
Result ContinueCheatProcess();
Result GetCheatCount(u64 *out_count); Result GetCheatCount(u64 *out_count);
Result GetCheats(CheatEntry *cheats, size_t max_count, u64 *out_count, u64 offset); Result GetCheats(CheatEntry *cheats, size_t max_count, u64 *out_count, u64 offset);

View file

@ -247,11 +247,11 @@ namespace ams::dmnt::cheat::impl {
this->LogToDebugFile("Reg Idx: %x\n", opcode->rw_static_reg.idx); this->LogToDebugFile("Reg Idx: %x\n", opcode->rw_static_reg.idx);
this->LogToDebugFile("Stc Idx: %x\n", opcode->rw_static_reg.static_idx); this->LogToDebugFile("Stc Idx: %x\n", opcode->rw_static_reg.static_idx);
break; break;
case CheatVmOpcodeType_BreakProcess: case CheatVmOpcodeType_PauseProcess:
this->LogToDebugFile("Opcode: Break Cheat Process\n"); this->LogToDebugFile("Opcode: Pause Cheat Process\n");
break; break;
case CheatVmOpcodeType_ContinueProcess: case CheatVmOpcodeType_ResumeProcess:
this->LogToDebugFile("Opcode: Continue Cheat Process\n"); this->LogToDebugFile("Opcode: Resume Cheat Process\n");
break; break;
case CheatVmOpcodeType_DebugLog: case CheatVmOpcodeType_DebugLog:
this->LogToDebugFile("Opcode: Debug Log\n"); this->LogToDebugFile("Opcode: Debug Log\n");
@ -596,18 +596,18 @@ namespace ams::dmnt::cheat::impl {
opcode.rw_static_reg.idx = (first_dword & 0xF); opcode.rw_static_reg.idx = (first_dword & 0xF);
} }
break; break;
case CheatVmOpcodeType_BreakProcess: case CheatVmOpcodeType_PauseProcess:
{ {
/* FF0????? */ /* FF0????? */
/* FF0 = opcode 0xFF0 */ /* FF0 = opcode 0xFF0 */
/* Breaks the current process. */ /* Pauses the current process. */
} }
break; break;
case CheatVmOpcodeType_ContinueProcess: case CheatVmOpcodeType_ResumeProcess:
{ {
/* FF1????? */ /* FF1????? */
/* FF1 = opcode 0xFF1 */ /* FF1 = opcode 0xFF1 */
/* Continues the current process. */ /* Resumes the current process. */
} }
break; break;
case CheatVmOpcodeType_DebugLog: 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]; this->static_registers[cur_opcode.rw_static_reg.static_idx] = this->registers[cur_opcode.rw_static_reg.idx];
} }
break; break;
case CheatVmOpcodeType_BreakProcess: case CheatVmOpcodeType_PauseProcess:
dmnt::cheat::impl::BreakCheatProcessUnsafe(); dmnt::cheat::impl::PauseCheatProcessUnsafe();
break; break;
case CheatVmOpcodeType_ContinueProcess: case CheatVmOpcodeType_ResumeProcess:
dmnt::cheat::impl::ContinueCheatProcessUnsafe(); dmnt::cheat::impl::ResumeCheatProcessUnsafe();
break; break;
case CheatVmOpcodeType_DebugLog: case CheatVmOpcodeType_DebugLog:
{ {

View file

@ -49,8 +49,8 @@ namespace ams::dmnt::cheat::impl {
CheatVmOpcodeType_DoubleExtendedWidth = 0xF0, CheatVmOpcodeType_DoubleExtendedWidth = 0xF0,
/* Double-extended width opcodes. */ /* Double-extended width opcodes. */
CheatVmOpcodeType_BreakProcess = 0xFF0, CheatVmOpcodeType_PauseProcess = 0xFF0,
CheatVmOpcodeType_ContinueProcess = 0xFF1, CheatVmOpcodeType_ResumeProcess = 0xFF1,
CheatVmOpcodeType_DebugLog = 0xFFF, CheatVmOpcodeType_DebugLog = 0xFFF,
}; };