forked from mdbell/Noexes
-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
300 additions
and
1 deletion.
There are no files selected for viewing
Binary file not shown.
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,200 @@ | ||
/* | ||
* Copyright (c) 2018-2020 Atmosphère-NX | ||
* | ||
* This program is free software; you can redistribute it and/or modify it | ||
* under the terms and conditions of the GNU General Public License, | ||
* version 2, as published by the Free Software Foundation. | ||
* | ||
* This program is distributed in the hope it will be useful, but WITHOUT | ||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
* more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
#define NX_SERVICE_ASSUME_NON_DOMAIN | ||
#include "../service_guard.h" | ||
#include "dmntcht.h" | ||
|
||
static Service g_dmntchtSrv; | ||
|
||
NX_GENERATE_SERVICE_GUARD(dmntcht); | ||
|
||
Result _dmntchtInitialize(void) { | ||
return smGetService(&g_dmntchtSrv, "dmnt:cht"); | ||
} | ||
|
||
void _dmntchtCleanup(void) { | ||
serviceClose(&g_dmntchtSrv); | ||
} | ||
|
||
Service* dmntchtGetServiceSession(void) { | ||
return &g_dmntchtSrv; | ||
} | ||
|
||
Result dmntchtHasCheatProcess(bool *out) { | ||
u8 tmp; | ||
Result rc = serviceDispatchOut(&g_dmntchtSrv, 65000, tmp); | ||
if (R_SUCCEEDED(rc) && out) *out = tmp & 1; | ||
return rc; | ||
} | ||
|
||
Result dmntchtGetCheatProcessEvent(Event *event) { | ||
Handle evt_handle; | ||
Result rc = serviceDispatch(&g_dmntchtSrv, 65001, | ||
.out_handle_attrs = { SfOutHandleAttr_HipcCopy }, | ||
.out_handles = &evt_handle, | ||
); | ||
|
||
if (R_SUCCEEDED(rc)) { | ||
eventLoadRemote(event, evt_handle, true); | ||
} | ||
|
||
return rc; | ||
} | ||
|
||
Result dmntchtGetCheatProcessMetadata(DmntCheatProcessMetadata *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) { | ||
return _dmntchtCmdVoid(&g_dmntchtSrv, 65003); | ||
} | ||
|
||
Result dmntchtForceCloseCheatProcess(void) { | ||
return _dmntchtCmdVoid(&g_dmntchtSrv, 65009); | ||
} | ||
|
||
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) { | ||
return serviceDispatchOut(&g_dmntchtSrv, cmd_id, *out_count); | ||
} | ||
|
||
static Result _dmntchtGetEntries(void *buffer, u64 buffer_size, u64 offset, u64 *out_count, u32 cmd_id) { | ||
return serviceDispatchInOut(&g_dmntchtSrv, cmd_id, offset, *out_count, | ||
.buffer_attrs = { SfBufferAttr_Out | SfBufferAttr_HipcMapAlias }, | ||
.buffers = { { buffer, buffer_size } }, | ||
); | ||
} | ||
|
||
static Result _dmntchtCmdInU32NoOut(u32 in, u32 cmd_id) { | ||
return serviceDispatchIn(&g_dmntchtSrv, cmd_id, in); | ||
} | ||
|
||
Result dmntchtGetCheatProcessMappingCount(u64 *out_count) { | ||
return _dmntchtGetCount(out_count, 65100); | ||
} | ||
|
||
Result dmntchtGetCheatProcessMappings(MemoryInfo *buffer, u64 max_count, u64 offset, u64 *out_count) { | ||
return _dmntchtGetEntries(buffer, sizeof(*buffer) * max_count, offset, out_count, 65101); | ||
} | ||
|
||
Result dmntchtReadCheatProcessMemory(u64 address, void *buffer, size_t size) { | ||
const struct { | ||
u64 address; | ||
u64 size; | ||
} in = { address, size }; | ||
return serviceDispatchIn(&g_dmntchtSrv, 65102, in, | ||
.buffer_attrs = { SfBufferAttr_Out | SfBufferAttr_HipcMapAlias }, | ||
.buffers = { { buffer, size } }, | ||
); | ||
} | ||
|
||
Result dmntchtWriteCheatProcessMemory(u64 address, const void *buffer, size_t size) { | ||
const struct { | ||
u64 address; | ||
u64 size; | ||
} in = { address, size }; | ||
return serviceDispatchIn(&g_dmntchtSrv, 65103, in, | ||
.buffer_attrs = { SfBufferAttr_In | SfBufferAttr_HipcMapAlias }, | ||
.buffers = { { buffer, size } }, | ||
); | ||
} | ||
|
||
Result dmntchtQueryCheatProcessMemory(MemoryInfo *mem_info, u64 address){ | ||
return serviceDispatchInOut(&g_dmntchtSrv, 65104, address, *mem_info); | ||
} | ||
|
||
Result dmntchtGetCheatCount(u64 *out_count) { | ||
return _dmntchtGetCount(out_count, 65200); | ||
} | ||
|
||
Result dmntchtGetCheats(DmntCheatEntry *buffer, u64 max_count, u64 offset, u64 *out_count) { | ||
return _dmntchtGetEntries(buffer, sizeof(*buffer) * max_count, offset, out_count, 65201); | ||
} | ||
|
||
Result dmntchtGetCheatById(DmntCheatEntry *out, u32 cheat_id) { | ||
return serviceDispatchIn(&g_dmntchtSrv, 65202, cheat_id, | ||
.buffer_attrs = { SfBufferAttr_Out | SfBufferAttr_HipcMapAlias | SfBufferAttr_FixedSize }, | ||
.buffers = { { out, sizeof(*out) } }, | ||
); | ||
} | ||
|
||
Result dmntchtToggleCheat(u32 cheat_id) { | ||
return _dmntchtCmdInU32NoOut(cheat_id, 65203); | ||
} | ||
|
||
Result dmntchtAddCheat(DmntCheatDefinition *cheat_def, bool enabled, u32 *out_cheat_id) { | ||
const u8 in = enabled != 0; | ||
return serviceDispatchInOut(&g_dmntchtSrv, 65204, in, *out_cheat_id, | ||
.buffer_attrs = { SfBufferAttr_In | SfBufferAttr_HipcMapAlias | SfBufferAttr_FixedSize }, | ||
.buffers = { { cheat_def, sizeof(*cheat_def) } }, | ||
); | ||
} | ||
|
||
Result dmntchtRemoveCheat(u32 cheat_id) { | ||
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) { | ||
return _dmntchtGetCount(out_count, 65300); | ||
} | ||
|
||
Result dmntchtGetFrozenAddresses(DmntFrozenAddressEntry *buffer, u64 max_count, u64 offset, u64 *out_count) { | ||
return _dmntchtGetEntries(buffer, sizeof(*buffer) * max_count, offset, out_count, 65301); | ||
} | ||
|
||
Result dmntchtGetFrozenAddress(DmntFrozenAddressEntry *out, u64 address) { | ||
return serviceDispatchInOut(&g_dmntchtSrv, 65302, address, *out); | ||
} | ||
|
||
Result dmntchtEnableFrozenAddress(u64 address, u64 width, u64 *out_value) { | ||
const struct { | ||
u64 address; | ||
u64 width; | ||
} in = { address, width }; | ||
return serviceDispatchInOut(&g_dmntchtSrv, 65303, in, *out_value); | ||
} | ||
|
||
Result dmntchtDisableFrozenAddress(u64 address) { | ||
return serviceDispatchIn(&g_dmntchtSrv, 65304, address); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
/* | ||
* Copyright (c) 2018-2020 Atmosphère-NX | ||
* | ||
* This program is free software; you can redistribute it and/or modify it | ||
* under the terms and conditions of the GNU General Public License, | ||
* version 2, as published by the Free Software Foundation. | ||
* | ||
* This program is distributed in the hope it will be useful, but WITHOUT | ||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
* more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
#pragma once | ||
#include <switch.h> | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
typedef struct { | ||
u64 base; | ||
u64 size; | ||
} DmntMemoryRegionExtents; | ||
|
||
typedef struct { | ||
u64 process_id; | ||
u64 title_id; | ||
DmntMemoryRegionExtents main_nso_extents; | ||
DmntMemoryRegionExtents heap_extents; | ||
DmntMemoryRegionExtents alias_extents; | ||
DmntMemoryRegionExtents address_space_extents; | ||
u8 main_nso_build_id[0x20]; | ||
} DmntCheatProcessMetadata; | ||
|
||
typedef struct { | ||
char readable_name[0x40]; | ||
uint32_t num_opcodes; | ||
uint32_t opcodes[0x100]; | ||
} DmntCheatDefinition; | ||
|
||
typedef struct { | ||
bool enabled; | ||
uint32_t cheat_id; | ||
DmntCheatDefinition definition; | ||
} DmntCheatEntry; | ||
|
||
typedef struct { | ||
u64 value; | ||
u8 width; | ||
} DmntFrozenAddressValue; | ||
|
||
typedef struct { | ||
u64 address; | ||
DmntFrozenAddressValue value; | ||
} DmntFrozenAddressEntry; | ||
|
||
Result dmntchtInitialize(void); | ||
void dmntchtExit(void); | ||
Service* dmntchtGetServiceSession(void); | ||
|
||
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); | ||
Result dmntchtReadCheatProcessMemory(u64 address, void *buffer, size_t size); | ||
Result dmntchtWriteCheatProcessMemory(u64 address, const void *buffer, size_t size); | ||
Result dmntchtQueryCheatProcessMemory(MemoryInfo *mem_info, u64 address); | ||
Result dmntchtPauseCheatProcess(void); | ||
Result dmntchtResumeCheatProcess(void); | ||
|
||
Result dmntchtGetCheatCount(u64 *out_count); | ||
Result dmntchtGetCheats(DmntCheatEntry *buffer, u64 max_count, u64 offset, u64 *out_count); | ||
Result dmntchtGetCheatById(DmntCheatEntry *out_cheat, u32 cheat_id); | ||
Result dmntchtToggleCheat(u32 cheat_id); | ||
Result dmntchtAddCheat(DmntCheatDefinition *cheat, bool enabled, u32 *out_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 dmntchtGetFrozenAddresses(DmntFrozenAddressEntry *buffer, u64 max_count, u64 offset, u64 *out_count); | ||
Result dmntchtGetFrozenAddress(DmntFrozenAddressEntry *out, u64 address); | ||
Result dmntchtEnableFrozenAddress(u64 address, u64 width, u64 *out_value); | ||
Result dmntchtDisableFrozenAddress(u64 address); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters