mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2025-04-23 13:04:50 +00:00
dmnt_extension
This commit is contained in:
parent
9f8d17b9e6
commit
d00e14d2f9
3 changed files with 85 additions and 5 deletions
|
@ -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).
|
||||
+ M: Memory region to write to (0 = Main NSO, 1 = Heap, 2 = Alias, 3 = Aslr, 4 = none).
|
||||
+ R: Register to use as an offset from memory region base.
|
||||
+ A: Immediate offset to use from memory region base.
|
||||
+ V: Value to write.
|
||||
|
@ -137,6 +137,22 @@ Code type 0x5 allows loading a value from memory into a register, either using a
|
|||
+ R: Register to load value into. (This register is also used as the base memory address).
|
||||
+ A: Immediate offset to use from register R.
|
||||
|
||||
#### Load from Register Address Encoding
|
||||
`5T0R2SAA AAAAAAAA`
|
||||
|
||||
+ T: Width of memory read (1, 2, 4, or 8 bytes).
|
||||
+ R: Register to load value into.
|
||||
+ S: Register to use as the base memory address.
|
||||
+ A: Immediate offset to use from register R.
|
||||
|
||||
#### Load From Fixed Address Encoding with offset register
|
||||
`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).
|
||||
+ R: Register to load value into.
|
||||
+ S: Register to use as offset register.
|
||||
+ A: Immediate offset to use from memory region base.
|
||||
---
|
||||
|
||||
### Code Type 0x6: Store Static Value to Register Memory Address
|
||||
|
@ -215,6 +231,7 @@ Note: This is the direct output of `hidKeysDown()`.
|
|||
+ 0800000: Right Stick Down
|
||||
+ 1000000: SL
|
||||
+ 2000000: SR
|
||||
+ 8000000: when this is set button only activate code once per keydown, need to be release before the code will run again
|
||||
|
||||
---
|
||||
|
||||
|
@ -250,6 +267,10 @@ Code type 0x9 allows performing arithmetic on registers.
|
|||
+ 7: Logical Not (discards right-hand operand)
|
||||
+ 8: Logical Xor
|
||||
+ 9: None/Move (discards right-hand operand)
|
||||
+ 10: Float Addition, Width force to 4 bytes
|
||||
+ 11: Float Multiplication, Width force to 4 bytes
|
||||
+ 12: Double Addition, Width force to 8 bytes
|
||||
+ 13: Double Multiplication, Width force to 8 bytes
|
||||
|
||||
---
|
||||
|
||||
|
@ -303,6 +324,7 @@ C0TcS2Ra aaaaaaaa
|
|||
C0TcS3Rr
|
||||
C0TcS400 VVVVVVVV (VVVVVVVV)
|
||||
C0TcS5X0
|
||||
C0Tcr6Ma aaaaaaaa VVVVVVVV (VVVVVVVV)
|
||||
```
|
||||
|
||||
+ T: Width of memory write (1, 2, 4, or 8 bytes).
|
||||
|
@ -323,6 +345,7 @@ C0TcS5X0
|
|||
+ 3: Register + Offset Register
|
||||
+ 4: Static Value
|
||||
+ 5: Other Register
|
||||
+ 6: Compare [Memory Base + Offset Register + Relative Offset] against Static Value
|
||||
|
||||
#### Conditions
|
||||
+ 1: >
|
||||
|
|
|
@ -228,6 +228,13 @@ namespace ams::dmnt::cheat::impl {
|
|||
this->LogToDebugFile("A Reg Idx: %x\n", opcode->begin_reg_cond.addr_reg_index);
|
||||
this->LogToDebugFile("O Reg Idx: %x\n", opcode->begin_reg_cond.ofs_reg_index);
|
||||
break;
|
||||
case CompareRegisterValueType_OffsetValue:
|
||||
this->LogToDebugFile("Comp Type: Offset Value\n");
|
||||
this->LogToDebugFile("Mem Type: %x\n", opcode->begin_reg_cond.mem_type);
|
||||
this->LogToDebugFile("O Reg Idx: %x\n", opcode->begin_reg_cond.ofs_reg_index);
|
||||
this->LogToDebugFile("Rel Addr: %lx\n", opcode->begin_reg_cond.rel_address);
|
||||
this->LogToDebugFile("Value: %lx\n", opcode->begin_reg_cond.value.bit64);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case CheatVmOpcodeType_SaveRestoreRegister:
|
||||
|
@ -427,7 +434,8 @@ namespace ams::dmnt::cheat::impl {
|
|||
opcode.ldr_memory.bit_width = (first_dword >> 24) & 0xF;
|
||||
opcode.ldr_memory.mem_type = (MemoryAccessType)((first_dword >> 20) & 0xF);
|
||||
opcode.ldr_memory.reg_index = ((first_dword >> 16) & 0xF);
|
||||
opcode.ldr_memory.load_from_reg = ((first_dword >> 12) & 0xF) != 0;
|
||||
opcode.ldr_memory.load_from_reg = ((first_dword >> 12) & 0xF);
|
||||
opcode.ldr_memory.offset_register = ((first_dword >> 8) & 0xF);
|
||||
opcode.ldr_memory.rel_address = ((u64)(first_dword & 0xFF) << 32ul) | ((u64)second_dword);
|
||||
}
|
||||
break;
|
||||
|
@ -525,6 +533,7 @@ namespace ams::dmnt::cheat::impl {
|
|||
/* C0TcS3Rr */
|
||||
/* C0TcS400 VVVVVVVV (VVVVVVVV) */
|
||||
/* C0TcS5X0 */
|
||||
/* C0Tcr6Ma aaaaaaaa VVVVVVVV (VVVVVVVV) */
|
||||
/* C0 = opcode 0xC0 */
|
||||
/* T = bit width */
|
||||
/* c = condition type. */
|
||||
|
@ -565,6 +574,12 @@ namespace ams::dmnt::cheat::impl {
|
|||
opcode.begin_reg_cond.addr_reg_index = ((first_dword >> 4) & 0xF);
|
||||
opcode.begin_reg_cond.ofs_reg_index = (first_dword & 0xF);
|
||||
break;
|
||||
case CompareRegisterValueType_OffsetValue:
|
||||
opcode.begin_reg_cond.mem_type = (MemoryAccessType)((first_dword >> 4) & 0xF);
|
||||
opcode.begin_reg_cond.rel_address = (((u64)(first_dword & 0xF) << 32ul) | ((u64)GetNextDword()));
|
||||
opcode.begin_reg_cond.ofs_reg_index = ((first_dword >> 12) & 0xF);
|
||||
opcode.begin_reg_cond.value = GetNextVmInt(opcode.begin_reg_cond.bit_width);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -734,6 +749,8 @@ 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:
|
||||
return rel_address;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -769,6 +786,7 @@ namespace ams::dmnt::cheat::impl {
|
|||
return true;
|
||||
}
|
||||
|
||||
static u64 keyold = 0;
|
||||
void CheatVirtualMachine::Execute(const CheatProcessMetadata *metadata) {
|
||||
CheatVmOpcode cur_opcode;
|
||||
u64 kHeld = 0;
|
||||
|
@ -896,8 +914,12 @@ namespace ams::dmnt::cheat::impl {
|
|||
{
|
||||
/* Choose source address. */
|
||||
u64 src_address;
|
||||
if (cur_opcode.ldr_memory.load_from_reg) {
|
||||
if (cur_opcode.ldr_memory.load_from_reg == 1) {
|
||||
src_address = m_registers[cur_opcode.ldr_memory.reg_index] + cur_opcode.ldr_memory.rel_address;
|
||||
} else if (cur_opcode.ldr_memory.load_from_reg == 2) {
|
||||
src_address = m_registers[cur_opcode.ldr_memory.offset_register] + cur_opcode.ldr_memory.rel_address;
|
||||
} else if (cur_opcode.ldr_memory.load_from_reg == 3) {
|
||||
src_address = GetCheatProcessAddress(metadata, cur_opcode.ldr_memory.mem_type, m_registers[cur_opcode.ldr_memory.offset_register] + cur_opcode.ldr_memory.rel_address);
|
||||
} else {
|
||||
src_address = GetCheatProcessAddress(metadata, cur_opcode.ldr_memory.mem_type, cur_opcode.ldr_memory.rel_address);
|
||||
}
|
||||
|
@ -977,7 +999,14 @@ namespace ams::dmnt::cheat::impl {
|
|||
break;
|
||||
case CheatVmOpcodeType_BeginKeypressConditionalBlock:
|
||||
/* Check for keypress. */
|
||||
if ((cur_opcode.begin_keypress_cond.key_mask & kHeld) != cur_opcode.begin_keypress_cond.key_mask) {
|
||||
if (cur_opcode.begin_keypress_cond.key_mask > 0x8000000) {
|
||||
const u64 kDown = ~keyold & kHeld;
|
||||
|
||||
if ((cur_opcode.begin_keypress_cond.key_mask & 0x7FFFFFF & kDown) != (cur_opcode.begin_keypress_cond.key_mask & 0x7FFFFFF)) {
|
||||
/* Keys not pressed. Skip conditional block. */
|
||||
this->SkipConditionalBlock(true);
|
||||
}
|
||||
} else if ((cur_opcode.begin_keypress_cond.key_mask & kHeld) != cur_opcode.begin_keypress_cond.key_mask) {
|
||||
/* Keys not pressed. Skip conditional block. */
|
||||
this->SkipConditionalBlock(true);
|
||||
}
|
||||
|
@ -1022,6 +1051,22 @@ namespace ams::dmnt::cheat::impl {
|
|||
case RegisterArithmeticType_None:
|
||||
res_val = operand_1_value;
|
||||
break;
|
||||
case RegisterArithmeticType_FloatAddition: {
|
||||
cur_opcode.perform_math_reg.bit_width = 4;
|
||||
*(float *)&res_val = *(float *)&operand_1_value + *(float *)&operand_2_value;
|
||||
} break;
|
||||
case RegisterArithmeticType_FloatMultiplication: {
|
||||
cur_opcode.perform_math_reg.bit_width = 4;
|
||||
*(float *)&res_val = *(float *)&operand_1_value * *(float *)&operand_2_value;
|
||||
} break;
|
||||
case RegisterArithmeticType_DoubleAddition: {
|
||||
cur_opcode.perform_math_reg.bit_width = 8;
|
||||
*(double *)&res_val = *(double *)&operand_1_value + *(double *)&operand_2_value;
|
||||
} break;
|
||||
case RegisterArithmeticType_DoubleMultiplication: {
|
||||
cur_opcode.perform_math_reg.bit_width = 8;
|
||||
*(double *)&res_val = *(double *)&operand_1_value * *(double *)&operand_2_value;
|
||||
} break;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1140,6 +1185,10 @@ namespace ams::dmnt::cheat::impl {
|
|||
case CompareRegisterValueType_RegisterOfsReg:
|
||||
cond_address = m_registers[cur_opcode.begin_reg_cond.addr_reg_index] + m_registers[cur_opcode.begin_reg_cond.ofs_reg_index];
|
||||
break;
|
||||
case CompareRegisterValueType_OffsetValue:
|
||||
cond_address = GetCheatProcessAddress(metadata, cur_opcode.begin_reg_cond.mem_type, cur_opcode.begin_reg_cond.rel_address + m_registers[cur_opcode.begin_reg_cond.ofs_reg_index]);
|
||||
src_value = GetVmInt(cur_opcode.begin_reg_cond.value, cur_opcode.begin_reg_cond.bit_width);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -1304,6 +1353,7 @@ namespace ams::dmnt::cheat::impl {
|
|||
break;
|
||||
}
|
||||
}
|
||||
keyold = kHeld;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -59,6 +59,7 @@ namespace ams::dmnt::cheat::impl {
|
|||
MemoryAccessType_Heap = 1,
|
||||
MemoryAccessType_Alias = 2,
|
||||
MemoryAccessType_Aslr = 3,
|
||||
MemoryAccessType_Blank = 4,
|
||||
};
|
||||
|
||||
enum ConditionalComparisonType : u32 {
|
||||
|
@ -84,6 +85,10 @@ namespace ams::dmnt::cheat::impl {
|
|||
RegisterArithmeticType_LogicalXor = 8,
|
||||
|
||||
RegisterArithmeticType_None = 9,
|
||||
RegisterArithmeticType_FloatAddition = 10,
|
||||
RegisterArithmeticType_FloatMultiplication = 11,
|
||||
RegisterArithmeticType_DoubleAddition = 12,
|
||||
RegisterArithmeticType_DoubleMultiplication = 13,
|
||||
};
|
||||
|
||||
enum StoreRegisterOffsetType : u32 {
|
||||
|
@ -102,6 +107,7 @@ namespace ams::dmnt::cheat::impl {
|
|||
CompareRegisterValueType_RegisterOfsReg = 3,
|
||||
CompareRegisterValueType_StaticValue = 4,
|
||||
CompareRegisterValueType_OtherRegister = 5,
|
||||
CompareRegisterValueType_OffsetValue = 6,
|
||||
};
|
||||
|
||||
enum SaveRestoreRegisterOpType : u32 {
|
||||
|
@ -161,7 +167,8 @@ namespace ams::dmnt::cheat::impl {
|
|||
u32 bit_width;
|
||||
MemoryAccessType mem_type;
|
||||
u32 reg_index;
|
||||
bool load_from_reg;
|
||||
u8 load_from_reg;
|
||||
u8 offset_register;
|
||||
u64 rel_address;
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue