updated according to review

This commit is contained in:
tomvita 2025-01-09 16:26:56 +08:00
parent 4e5a067a7b
commit 11afc3ad3c
3 changed files with 38 additions and 34 deletions

View File

@ -49,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, 2 = Alias, 3 = Aslr, 4 = none). + M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr, 4 = non-relative).
+ 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.
@ -65,7 +65,7 @@ If the condition is not met, all instructions until the appropriate End or Else
`1TMCXrAA AAAAAAAA VVVVVVVV (VVVVVVVV)` `1TMCXrAA AAAAAAAA VVVVVVVV (VVVVVVVV)`
+ 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 read from (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr, 4 = none). + M: Memory region to read from (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr, 4 = non-relative).
+ C: Condition to use, see below. + C: Condition to use, see below.
+ X: Operand Type, see below. + X: Operand Type, see below.
+ r: Offset Register (operand types 1). + r: Offset Register (operand types 1).
@ -131,7 +131,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, 2 = Alias, 3 = Aslr, 4 = none). + M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr, 4 = non-relative).
+ 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.
@ -154,7 +154,7 @@ Code type 0x5 allows loading a value from memory into a register, either using a
`5TMR3SAA AAAAAAAA` `5TMR3SAA 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, 2 = Alias, 3 = Aslr, 4 = none). + M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr, 4 = non-relative).
+ R: Register to load value into. + R: Register to load value into.
+ S: Register to use as offset register. + S: Register to use as offset register.
+ A: Immediate offset to use from memory region base. + A: Immediate offset to use from memory region base.
@ -408,7 +408,7 @@ Code type 0xC3 reads or writes a static register with a given register.
Code type 0xC4 enters or skips a conditional block based on whether a key combination is pressed. Code type 0xC4 enters or skips a conditional block based on whether a key combination is pressed.
#### Encoding #### Encoding
`C4r000kk kkkkkkkk` `C4r00000 kkkkkkkk kkkkkkkk`
+ r: Auto-repeat, see below. + r: Auto-repeat, see below.
+ kkkkkkkkkk: Keypad mask to check against output of `hidKeysDown()`. + kkkkkkkkkk: Keypad mask to check against output of `hidKeysDown()`.

View File

@ -473,9 +473,9 @@ namespace ams::dmnt::cheat::impl {
break; break;
case CheatVmOpcodeType_BeginExtendedKeypressConditionalBlock: case CheatVmOpcodeType_BeginExtendedKeypressConditionalBlock:
{ {
/* C4r000kk kkkkkkkk */ /* C4r00000 kkkkkkkk kkkkkkkk */
/* Read additional words. */ /* Read additional words. */
opcode.begin_ext_keypress_cond.key_mask = (((u64)first_dword & 0xFF) << 32ul) | ((u64)GetNextDword()); opcode.begin_ext_keypress_cond.key_mask = (u64)GetNextDword() << 32ul | (u64)GetNextDword();
opcode.begin_ext_keypress_cond.auto_repeat = ((first_dword >> 20) & 0xF) != 0; opcode.begin_ext_keypress_cond.auto_repeat = ((first_dword >> 20) & 0xF) != 0;
} }
break; break;
@ -753,7 +753,7 @@ namespace ams::dmnt::cheat::impl {
return metadata->alias_extents.base + rel_address; return metadata->alias_extents.base + rel_address;
case MemoryAccessType_Aslr: case MemoryAccessType_Aslr:
return metadata->aslr_extents.base + rel_address; return metadata->aslr_extents.base + rel_address;
case MemoryAccessType_Blank: case MemoryAccessType_NonRelative:
return rel_address; return rel_address;
} }
} }
@ -790,7 +790,7 @@ namespace ams::dmnt::cheat::impl {
return true; return true;
} }
static u64 keyold = 0; static u64 s_keyold = 0;
void CheatVirtualMachine::Execute(const CheatProcessMetadata *metadata) { void CheatVirtualMachine::Execute(const CheatProcessMetadata *metadata) {
CheatVmOpcode cur_opcode; CheatVmOpcode cur_opcode;
u64 kHeld = 0; u64 kHeld = 0;
@ -1011,7 +1011,7 @@ namespace ams::dmnt::cheat::impl {
case CheatVmOpcodeType_BeginExtendedKeypressConditionalBlock: case CheatVmOpcodeType_BeginExtendedKeypressConditionalBlock:
/* Check for keypress. */ /* Check for keypress. */
if (!cur_opcode.begin_ext_keypress_cond.auto_repeat) { if (!cur_opcode.begin_ext_keypress_cond.auto_repeat) {
if ((cur_opcode.begin_ext_keypress_cond.key_mask & kHeld) != (cur_opcode.begin_ext_keypress_cond.key_mask) || (cur_opcode.begin_ext_keypress_cond.key_mask & keyold) == (cur_opcode.begin_ext_keypress_cond.key_mask)) { if ((cur_opcode.begin_ext_keypress_cond.key_mask & kHeld) != (cur_opcode.begin_ext_keypress_cond.key_mask) || (cur_opcode.begin_ext_keypress_cond.key_mask & s_keyold) == (cur_opcode.begin_ext_keypress_cond.key_mask)) {
/* Keys not pressed. Skip conditional block. */ /* Keys not pressed. Skip conditional block. */
this->SkipConditionalBlock(true); this->SkipConditionalBlock(true);
} }
@ -1061,29 +1061,33 @@ namespace ams::dmnt::cheat::impl {
res_val = operand_1_value; res_val = operand_1_value;
break; break;
case RegisterArithmeticType_FloatAddition: case RegisterArithmeticType_FloatAddition:
if (cur_opcode.perform_math_reg.bit_width == 4) if (cur_opcode.perform_math_reg.bit_width == 4) {
*(float *)&res_val = *(float *)&operand_1_value + *(float *)&operand_2_value; res_val = std::bit_cast<std::uint32_t>(std::bit_cast<float>(static_cast<uint32_t>(operand_1_value)) + std::bit_cast<float>(static_cast<uint32_t>(operand_2_value)));
if (cur_opcode.perform_math_reg.bit_width == 8) } else if (cur_opcode.perform_math_reg.bit_width == 8) {
*(double *)&res_val = *(double *)&operand_1_value + *(double *)&operand_2_value; res_val = std::bit_cast<std::uint64_t>(std::bit_cast<double>(operand_1_value) + std::bit_cast<double>(operand_2_value));
}
break;
case RegisterArithmeticType_FloatSubtraction:
if (cur_opcode.perform_math_reg.bit_width == 4) {
res_val = std::bit_cast<std::uint32_t>(std::bit_cast<float>(static_cast<uint32_t>(operand_1_value)) - std::bit_cast<float>(static_cast<uint32_t>(operand_2_value)));
} else if (cur_opcode.perform_math_reg.bit_width == 8) {
res_val = std::bit_cast<std::uint64_t>(std::bit_cast<double>(operand_1_value) - std::bit_cast<double>(operand_2_value));
}
break;
case RegisterArithmeticType_FloatMultiplication:
if (cur_opcode.perform_math_reg.bit_width == 4) {
res_val = std::bit_cast<std::uint32_t>(std::bit_cast<float>(static_cast<uint32_t>(operand_1_value)) * std::bit_cast<float>(static_cast<uint32_t>(operand_2_value)));
} else if (cur_opcode.perform_math_reg.bit_width == 8) {
res_val = std::bit_cast<std::uint64_t>(std::bit_cast<double>(operand_1_value) * std::bit_cast<double>(operand_2_value));
}
break;
case RegisterArithmeticType_FloatDivision:
if (cur_opcode.perform_math_reg.bit_width == 4) {
res_val = std::bit_cast<std::uint32_t>(std::bit_cast<float>(static_cast<uint32_t>(operand_1_value)) / std::bit_cast<float>(static_cast<uint32_t>(operand_2_value)));
} else if (cur_opcode.perform_math_reg.bit_width == 8) {
res_val = std::bit_cast<std::uint64_t>(std::bit_cast<double>(operand_1_value) / std::bit_cast<double>(operand_2_value));
}
break; break;
case RegisterArithmeticType_FloatSubtraction: {
if (cur_opcode.perform_math_reg.bit_width == 4)
*(float *)&res_val = *(float *)&operand_1_value - *(float *)&operand_2_value;
if (cur_opcode.perform_math_reg.bit_width == 8)
*(double *)&res_val = *(double *)&operand_1_value - *(double *)&operand_2_value;
} break;
case RegisterArithmeticType_FloatMultiplication: {
if (cur_opcode.perform_math_reg.bit_width == 4)
*(float *)&res_val = *(float *)&operand_1_value * *(float *)&operand_2_value;
if (cur_opcode.perform_math_reg.bit_width == 8)
*(double *)&res_val = *(double *)&operand_1_value * *(double *)&operand_2_value;
} break;
case RegisterArithmeticType_FloatDivision: {
if (cur_opcode.perform_math_reg.bit_width == 4)
*(float *)&res_val = *(float *)&operand_1_value / *(float *)&operand_2_value;
if (cur_opcode.perform_math_reg.bit_width == 8)
*(double *)&res_val = *(double *)&operand_1_value / *(double *)&operand_2_value;
} break;
} }
@ -1366,7 +1370,7 @@ namespace ams::dmnt::cheat::impl {
break; break;
} }
} }
keyold = kHeld; s_keyold = kHeld;
} }
} }

View File

@ -60,7 +60,7 @@ namespace ams::dmnt::cheat::impl {
MemoryAccessType_Heap = 1, MemoryAccessType_Heap = 1,
MemoryAccessType_Alias = 2, MemoryAccessType_Alias = 2,
MemoryAccessType_Aslr = 3, MemoryAccessType_Aslr = 3,
MemoryAccessType_Blank = 4, MemoryAccessType_NonRelative = 4,
}; };
enum ConditionalComparisonType : u32 { enum ConditionalComparisonType : u32 {