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)`
+ 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.
+ A: Immediate offset to use from memory region base.
+ 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)`
+ 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.
+ X: Operand Type, see below.
+ 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`
+ 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.
+ 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`
+ 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.
+ S: Register to use as offset register.
+ 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.
#### Encoding
`C4r000kk kkkkkkkk`
`C4r00000 kkkkkkkk kkkkkkkk`
+ r: Auto-repeat, see below.
+ kkkkkkkkkk: Keypad mask to check against output of `hidKeysDown()`.

View File

@ -473,9 +473,9 @@ namespace ams::dmnt::cheat::impl {
break;
case CheatVmOpcodeType_BeginExtendedKeypressConditionalBlock:
{
/* C4r000kk kkkkkkkk */
/* C4r00000 kkkkkkkk kkkkkkkk */
/* 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;
}
break;
@ -753,7 +753,7 @@ namespace ams::dmnt::cheat::impl {
return metadata->alias_extents.base + rel_address;
case MemoryAccessType_Aslr:
return metadata->aslr_extents.base + rel_address;
case MemoryAccessType_Blank:
case MemoryAccessType_NonRelative:
return rel_address;
}
}
@ -790,7 +790,7 @@ namespace ams::dmnt::cheat::impl {
return true;
}
static u64 keyold = 0;
static u64 s_keyold = 0;
void CheatVirtualMachine::Execute(const CheatProcessMetadata *metadata) {
CheatVmOpcode cur_opcode;
u64 kHeld = 0;
@ -1011,7 +1011,7 @@ namespace ams::dmnt::cheat::impl {
case CheatVmOpcodeType_BeginExtendedKeypressConditionalBlock:
/* Check for keypress. */
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. */
this->SkipConditionalBlock(true);
}
@ -1061,29 +1061,33 @@ namespace ams::dmnt::cheat::impl {
res_val = operand_1_value;
break;
case RegisterArithmeticType_FloatAddition:
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;
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_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;
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;
}
}
keyold = kHeld;
s_keyold = kHeld;
}
}

View File

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