diff options
| author | TSR Berry <20988865+TSRBerry@users.noreply.github.com> | 2023-04-08 01:22:00 +0200 |
|---|---|---|
| committer | Mary <thog@protonmail.com> | 2023-04-27 23:51:14 +0200 |
| commit | cee712105850ac3385cd0091a923438167433f9f (patch) | |
| tree | 4a5274b21d8b7f938c0d0ce18736d3f2993b11b1 /Ryujinx.HLE/HOS/Tamper | |
| parent | cd124bda587ef09668a971fa1cac1c3f0cfc9f21 (diff) | |
Move solution and projects to src
Diffstat (limited to 'Ryujinx.HLE/HOS/Tamper')
60 files changed, 0 insertions, 2453 deletions
diff --git a/Ryujinx.HLE/HOS/Tamper/AtmosphereCompiler.cs b/Ryujinx.HLE/HOS/Tamper/AtmosphereCompiler.cs deleted file mode 100644 index 7d7af208..00000000 --- a/Ryujinx.HLE/HOS/Tamper/AtmosphereCompiler.cs +++ /dev/null @@ -1,152 +0,0 @@ -using Ryujinx.Common.Logging; -using Ryujinx.HLE.Exceptions; -using Ryujinx.HLE.HOS.Tamper.CodeEmitters; -using Ryujinx.HLE.HOS.Tamper.Operations; -using System; -using System.Collections.Generic; - -namespace Ryujinx.HLE.HOS.Tamper -{ - class AtmosphereCompiler - { - private ulong _exeAddress; - private ulong _heapAddress; - private ulong _aliasAddress; - private ulong _aslrAddress; - private ITamperedProcess _process; - - public AtmosphereCompiler(ulong exeAddress, ulong heapAddress, ulong aliasAddress, ulong aslrAddress, ITamperedProcess process) - { - _exeAddress = exeAddress; - _heapAddress = heapAddress; - _aliasAddress = aliasAddress; - _aslrAddress = aslrAddress; - _process = process; - } - - public ITamperProgram Compile(string name, IEnumerable<string> rawInstructions) - { - string[] addresses = new string[] - { - $" Executable address: 0x{_exeAddress:X16}", - $" Heap address : 0x{_heapAddress:X16}", - $" Alias address : 0x{_aliasAddress:X16}", - $" Aslr address : 0x{_aslrAddress:X16}" - }; - - Logger.Debug?.Print(LogClass.TamperMachine, $"Compiling Atmosphere cheat {name}...\n{string.Join('\n', addresses)}"); - - try - { - return CompileImpl(name, rawInstructions); - } - catch(TamperCompilationException exception) - { - // Just print the message without the stack trace. - Logger.Error?.Print(LogClass.TamperMachine, exception.Message); - } - catch (Exception exception) - { - Logger.Error?.Print(LogClass.TamperMachine, exception.ToString()); - } - - Logger.Error?.Print(LogClass.TamperMachine, "There was a problem while compiling the Atmosphere cheat"); - - return null; - } - - private ITamperProgram CompileImpl(string name, IEnumerable<string> rawInstructions) - { - CompilationContext context = new CompilationContext(_exeAddress, _heapAddress, _aliasAddress, _aslrAddress, _process); - context.BlockStack.Push(new OperationBlock(null)); - - // Parse the instructions. - - foreach (string rawInstruction in rawInstructions) - { - Logger.Debug?.Print(LogClass.TamperMachine, $"Compiling instruction {rawInstruction}"); - - byte[] instruction = InstructionHelper.ParseRawInstruction(rawInstruction); - CodeType codeType = InstructionHelper.GetCodeType(instruction); - - switch (codeType) - { - case CodeType.StoreConstantToAddress: - StoreConstantToAddress.Emit(instruction, context); - break; - case CodeType.BeginMemoryConditionalBlock: - BeginConditionalBlock.Emit(instruction, context); - break; - case CodeType.EndConditionalBlock: - EndConditionalBlock.Emit(instruction, context); - break; - case CodeType.StartEndLoop: - StartEndLoop.Emit(instruction, context); - break; - case CodeType.LoadRegisterWithContant: - LoadRegisterWithConstant.Emit(instruction, context); - break; - case CodeType.LoadRegisterWithMemory: - LoadRegisterWithMemory.Emit(instruction, context); - break; - case CodeType.StoreConstantToMemory: - StoreConstantToMemory.Emit(instruction, context); - break; - case CodeType.LegacyArithmetic: - LegacyArithmetic.Emit(instruction, context); - break; - case CodeType.BeginKeypressConditionalBlock: - BeginConditionalBlock.Emit(instruction, context); - break; - case CodeType.Arithmetic: - Arithmetic.Emit(instruction, context); - break; - case CodeType.StoreRegisterToMemory: - StoreRegisterToMemory.Emit(instruction, context); - break; - case CodeType.BeginRegisterConditionalBlock: - BeginConditionalBlock.Emit(instruction, context); - break; - case CodeType.SaveOrRestoreRegister: - SaveOrRestoreRegister.Emit(instruction, context); - break; - case CodeType.SaveOrRestoreRegisterWithMask: - SaveOrRestoreRegisterWithMask.Emit(instruction, context); - break; - case CodeType.ReadOrWriteStaticRegister: - ReadOrWriteStaticRegister.Emit(instruction, context); - break; - case CodeType.PauseProcess: - PauseProcess.Emit(instruction, context); - break; - case CodeType.ResumeProcess: - ResumeProcess.Emit(instruction, context); - break; - case CodeType.DebugLog: - DebugLog.Emit(instruction, context); - break; - default: - throw new TamperCompilationException($"Code type {codeType} not implemented in Atmosphere cheat"); - } - } - - // Initialize only the registers used. - - Value<ulong> zero = new Value<ulong>(0UL); - int position = 0; - - foreach (Register register in context.Registers.Values) - { - context.CurrentOperations.Insert(position, new OpMov<ulong>(register, zero)); - position++; - } - - if (context.BlockStack.Count != 1) - { - throw new TamperCompilationException($"Reached end of compilation with unmatched conditional(s) or loop(s)"); - } - - return new AtmosphereProgram(name, _process, context.PressedKeys, new Block(context.CurrentOperations)); - } - } -} diff --git a/Ryujinx.HLE/HOS/Tamper/AtmosphereProgram.cs b/Ryujinx.HLE/HOS/Tamper/AtmosphereProgram.cs deleted file mode 100644 index a2aa73a4..00000000 --- a/Ryujinx.HLE/HOS/Tamper/AtmosphereProgram.cs +++ /dev/null @@ -1,33 +0,0 @@ -using Ryujinx.HLE.HOS.Services.Hid; -using Ryujinx.HLE.HOS.Tamper.Operations; - -namespace Ryujinx.HLE.HOS.Tamper -{ - class AtmosphereProgram : ITamperProgram - { - private Parameter<long> _pressedKeys; - private IOperation _entryPoint; - - public string Name { get; } - public bool TampersCodeMemory { get; set; } = false; - public ITamperedProcess Process { get; } - public bool IsEnabled { get; set; } - - public AtmosphereProgram(string name, ITamperedProcess process, Parameter<long> pressedKeys, IOperation entryPoint) - { - Name = name; - Process = process; - _pressedKeys = pressedKeys; - _entryPoint = entryPoint; - } - - public void Execute(ControllerKeys pressedKeys) - { - if (IsEnabled) - { - _pressedKeys.Value = (long)pressedKeys; - _entryPoint.Execute(); - } - } - } -} diff --git a/Ryujinx.HLE/HOS/Tamper/CodeEmitters/Arithmetic.cs b/Ryujinx.HLE/HOS/Tamper/CodeEmitters/Arithmetic.cs deleted file mode 100644 index b7d46d3a..00000000 --- a/Ryujinx.HLE/HOS/Tamper/CodeEmitters/Arithmetic.cs +++ /dev/null @@ -1,105 +0,0 @@ -using Ryujinx.HLE.Exceptions; -using Ryujinx.HLE.HOS.Tamper.Operations; -using System; -using System.Collections.Generic; - -namespace Ryujinx.HLE.HOS.Tamper.CodeEmitters -{ - /// <summary> - /// Code type 9 allows performing arithmetic on registers. - /// </summary> - class Arithmetic - { - private const int OperationWidthIndex = 1; - private const int OperationTypeIndex = 2; - private const int DestinationRegisterIndex = 3; - private const int LeftHandSideRegisterIndex = 4; - private const int UseImmediateAsRhsIndex = 5; - private const int RightHandSideRegisterIndex = 6; - private const int RightHandSideImmediateIndex = 8; - - private const int RightHandSideImmediate8 = 8; - private const int RightHandSideImmediate16 = 16; - - private const byte Add = 0; // lhs + rhs - private const byte Sub = 1; // lhs - rhs - private const byte Mul = 2; // lhs * rhs - private const byte Lsh = 3; // lhs << rhs - private const byte Rsh = 4; // lhs >> rhs - private const byte And = 5; // lhs & rhs - private const byte Or = 6; // lhs | rhs - private const byte Not = 7; // ~lhs (discards right-hand operand) - private const byte Xor = 8; // lhs ^ rhs - private const byte Mov = 9; // lhs (discards right-hand operand) - - public static void Emit(byte[] instruction, CompilationContext context) - { - // 9TCRS0s0 - // T: Width of arithmetic operation(1, 2, 4, or 8 bytes). - // C: Arithmetic operation to apply, see below. - // R: Register to store result in. - // S: Register to use as left - hand operand. - // s: Register to use as right - hand operand. - - // 9TCRS100 VVVVVVVV (VVVVVVVV) - // T: Width of arithmetic operation(1, 2, 4, or 8 bytes). - // C: Arithmetic operation to apply, see below. - // R: Register to store result in. - // S: Register to use as left - hand operand. - // V: Value to use as right - hand operand. - - byte operationWidth = instruction[OperationWidthIndex]; - byte operation = instruction[OperationTypeIndex]; - Register destinationRegister = context.GetRegister(instruction[DestinationRegisterIndex]); - Register leftHandSideRegister = context.GetRegister(instruction[LeftHandSideRegisterIndex]); - byte rightHandSideIsImmediate = instruction[UseImmediateAsRhsIndex]; - IOperand rightHandSideOperand; - - switch (rightHandSideIsImmediate) - { - case 0: - // Use a register as right-hand side. - rightHandSideOperand = context.GetRegister(instruction[RightHandSideRegisterIndex]); - break; - case 1: - // Use an immediate as right-hand side. - int immediateSize = operationWidth <= 4 ? RightHandSideImmediate8 : RightHandSideImmediate16; - ulong immediate = InstructionHelper.GetImmediate(instruction, RightHandSideImmediateIndex, immediateSize); - rightHandSideOperand = new Value<ulong>(immediate); - break; - default: - throw new TamperCompilationException($"Invalid right-hand side switch {rightHandSideIsImmediate} in Atmosphere cheat"); - } - - void Emit(Type operationType, IOperand rhs = null) - { - List<IOperand> operandList = new List<IOperand>(); - operandList.Add(destinationRegister); - operandList.Add(leftHandSideRegister); - - if (rhs != null) - { - operandList.Add(rhs); - } - - InstructionHelper.Emit(operationType, operationWidth, context, operandList.ToArray()); - } - - switch (operation) - { - case Add: Emit(typeof(OpAdd<>), rightHandSideOperand); break; - case Sub: Emit(typeof(OpSub<>), rightHandSideOperand); break; - case Mul: Emit(typeof(OpMul<>), rightHandSideOperand); break; - case Lsh: Emit(typeof(OpLsh<>), rightHandSideOperand); break; - case Rsh: Emit(typeof(OpRsh<>), rightHandSideOperand); break; - case And: Emit(typeof(OpAnd<>), rightHandSideOperand); break; - case Or: Emit(typeof(OpOr<> ), rightHandSideOperand); break; - case Not: Emit(typeof(OpNot<>) ); break; - case Xor: Emit(typeof(OpXor<>), rightHandSideOperand); break; - case Mov: Emit(typeof(OpMov<>) ); break; - default: - throw new TamperCompilationException($"Invalid arithmetic operation {operation} in Atmosphere cheat"); - } - } - } -} diff --git a/Ryujinx.HLE/HOS/Tamper/CodeEmitters/BeginConditionalBlock.cs b/Ryujinx.HLE/HOS/Tamper/CodeEmitters/BeginConditionalBlock.cs deleted file mode 100644 index 5439821c..00000000 --- a/Ryujinx.HLE/HOS/Tamper/CodeEmitters/BeginConditionalBlock.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace Ryujinx.HLE.HOS.Tamper.CodeEmitters -{ - /// <summary> - /// Marks the begin of a conditional block (started by Code Type 1, Code Type 8 or Code Type C0). - /// </summary> - class BeginConditionalBlock - { - public static void Emit(byte[] instruction, CompilationContext context) - { - // Just start a new compilation block and parse the instruction itself at the end. - context.BlockStack.Push(new OperationBlock(instruction)); - } - } -} diff --git a/Ryujinx.HLE/HOS/Tamper/CodeEmitters/DebugLog.cs b/Ryujinx.HLE/HOS/Tamper/CodeEmitters/DebugLog.cs deleted file mode 100644 index 533b362a..00000000 --- a/Ryujinx.HLE/HOS/Tamper/CodeEmitters/DebugLog.cs +++ /dev/null @@ -1,87 +0,0 @@ -using Ryujinx.HLE.Exceptions; -using Ryujinx.HLE.HOS.Tamper.Operations; - -namespace Ryujinx.HLE.HOS.Tamper.CodeEmitters -{ - /// <summary> - /// Code type 0xFFF writes a debug log. - /// </summary> - class DebugLog - { - private const int OperationWidthIndex = 3; - private const int LogIdIndex = 4; - private const int OperandTypeIndex = 5; - private const int RegisterOrMemoryRegionIndex = 6; - private const int OffsetRegisterOrImmediateIndex = 7; - - private const int MemoryRegionWithOffsetImmediate = 0; - private const int MemoryRegionWithOffsetRegister = 1; - private const int AddressRegisterWithOffsetImmediate = 2; - private const int AddressRegisterWithOffsetRegister = 3; - private const int ValueRegister = 4; - - private const int OffsetImmediateSize = 9; - - public static void Emit(byte[] instruction, CompilationContext context) - { - // FFFTIX## - // FFFTI0Ma aaaaaaaa - // FFFTI1Mr - // FFFTI2Ra aaaaaaaa - // FFFTI3Rr - // FFFTI4V0 - // T: Width of memory write (1, 2, 4, or 8 bytes). - // I: Log id. - // X: Operand Type, see below. - // M: Memory Type (operand types 0 and 1). - // R: Address Register (operand types 2 and 3). - // a: Relative Address (operand types 0 and 2). - // r: Offset Register (operand types 1 and 3). - // V: Value Register (operand type 4). - - byte operationWidth = instruction[OperationWidthIndex]; - byte logId = instruction[LogIdIndex]; - byte operandType = instruction[OperandTypeIndex]; - byte registerOrMemoryRegion = instruction[RegisterOrMemoryRegionIndex]; - byte offsetRegisterIndex = instruction[OffsetRegisterOrImmediateIndex]; - ulong immediate; - Register addressRegister; - Register offsetRegister; - IOperand sourceOperand; - - switch (operandType) - { - case MemoryRegionWithOffsetImmediate: - // *(?x + #a) - immediate = InstructionHelper.GetImmediate(instruction, OffsetRegisterOrImmediateIndex, OffsetImmediateSize); - sourceOperand = MemoryHelper.EmitPointer((MemoryRegion)registerOrMemoryRegion, immediate, context); - break; - case MemoryRegionWithOffsetRegister: - // *(?x + $r) - offsetRegister = context.GetRegister(offsetRegisterIndex); - sourceOperand = MemoryHelper.EmitPointer((MemoryRegion)registerOrMemoryRegion, offsetRegister, context); - break; - case AddressRegisterWithOffsetImmediate: - // *($R + #a) - addressRegister = context.GetRegister(registerOrMemoryRegion); - immediate = InstructionHelper.GetImmediate(instruction, OffsetRegisterOrImmediateIndex, OffsetImmediateSize); - sourceOperand = MemoryHelper.EmitPointer(addressRegister, immediate, context); - break; - case AddressRegisterWithOffsetRegister: - // *($R + $r) - addressRegister = context.GetRegister(registerOrMemoryRegion); - offsetRegister = context.GetRegister(offsetRegisterIndex); - sourceOperand = MemoryHelper.EmitPointer(addressRegister, offsetRegister, context); - break; - case ValueRegister: - // $V - sourceOperand = context.GetRegister(registerOrMemoryRegion); - break; - default: - throw new TamperCompilationException($"Invalid operand type {operandType} in Atmosphere cheat"); - } - - InstructionHelper.Emit(typeof(OpLog<>), operationWidth, context, logId, sourceOperand); - } - } -} diff --git a/Ryujinx.HLE/HOS/Tamper/CodeEmitters/EndConditionalBlock.cs b/Ryujinx.HLE/HOS/Tamper/CodeEmitters/EndConditionalBlock.cs deleted file mode 100644 index a25dddde..00000000 --- a/Ryujinx.HLE/HOS/Tamper/CodeEmitters/EndConditionalBlock.cs +++ /dev/null @@ -1,91 +0,0 @@ -using Ryujinx.HLE.Exceptions; -using Ryujinx.HLE.HOS.Tamper.Conditions; -using Ryujinx.HLE.HOS.Tamper.Operations; -using System.Collections.Generic; - -namespace Ryujinx.HLE.HOS.Tamper.CodeEmitters -{ - /// <summary> - /// Code type 2 marks the end of a conditional block (started by Code Type 1, Code Type 8 or Code Type C0). - /// </summary> - class EndConditionalBlock - { - const int TerminationTypeIndex = 1; - - private const byte End = 0; // True end of the conditional. - private const byte Else = 1; // End of the 'then' block and beginning of 'else' block. - - public static void Emit(byte[] instruction, CompilationContext context) - { - Emit(instruction, context, null); - } - - private static void Emit(byte[] instruction, CompilationContext context, IEnumerable<IOperation> operationsElse) - { - // 2X000000 - // X: End type (0 = End, 1 = Else). - - byte terminationType = instruction[TerminationTypeIndex]; - - switch (terminationType) - { - case End: - break; - case Else: - // Start a new operation block with the 'else' instruction to signal that there is the 'then' block just above it. - context.BlockStack.Push(new OperationBlock(instruction)); - return; - default: - throw new TamperCompilationException($"Unknown conditional termination type {terminationType}"); - } - - // Use the conditional begin instruction stored in the stack. - var upperInstruction = context.CurrentBlock.BaseInstruction; - CodeType codeType = InstructionHelper.GetCodeType(upperInstruction); - - // Pop the current block of operations from the stack so control instructions - // for the conditional can be emitted in the upper block. - IEnumerable<IOperation> operations = context.CurrentOperations; - context.BlockStack.Pop(); - - // If the else operations are already set, then the upper block must not be another end. - if (operationsElse != null && codeType == CodeType.EndConditionalBlock) - { - throw new TamperCompilationException($"Expected an upper 'if' conditional instead of 'end conditional'"); - } - - ICondition condition; - - switch (codeType) - { - case CodeType.BeginMemoryConditionalBlock: - condition = MemoryConditional.Emit(upperInstruction, context); - break; - case CodeType.BeginKeypressConditionalBlock: - condition = KeyPressConditional.Emit(upperInstruction, context); - break; - case CodeType.BeginRegisterConditionalBlock: - condition = RegisterConditional.Emit(upperInstruction, context); - break; - case CodeType.EndConditionalBlock: - terminationType = upperInstruction[TerminationTypeIndex]; - // If there is an end instruction above then it must be an else. - if (terminationType != Else) - { - throw new TamperCompilationException($"Expected an upper 'else' conditional instead of {terminationType}"); - } - // Re-run the Emit with the else operations set. - Emit(instruction, context, operations); - return; - default: - throw new TamperCompilationException($"Conditional end does not match code type {codeType} in Atmosphere cheat"); - } - - // Create a conditional block with the current operations and nest it in the upper - // block of the stack. - - IfBlock block = new IfBlock(condition, operations, operationsElse); - context.CurrentOperations.Add(block); - } - } -} diff --git a/Ryujinx.HLE/HOS/Tamper/CodeEmitters/KeyPressConditional.cs b/Ryujinx.HLE/HOS/Tamper/CodeEmitters/KeyPressConditional.cs deleted file mode 100644 index a1758665..00000000 --- a/Ryujinx.HLE/HOS/Tamper/CodeEmitters/KeyPressConditional.cs +++ /dev/null @@ -1,26 +0,0 @@ -using Ryujinx.HLE.HOS.Tamper.Conditions; - -namespace Ryujinx.HLE.HOS.Tamper.CodeEmitters -{ - /// <summary> - /// Code type 8 enters or skips a conditional block based on whether a key combination is pressed. - /// </summary> - class KeyPressConditional - { - private const int InputMaskIndex = 1; - - private const int InputMaskSize = 7; - - public static ICondition Emit(byte[] instruction, CompilationContext context) - { - // 8kkkkkkk - // k: Keypad mask to check against, see below. - // Note that for multiple button combinations, the bitmasks should be ORd together. - // The Keypad Values are the direct output of hidKeysDown(). - - ulong inputMask = InstructionHelper.GetImmediate(instruction, InputMaskIndex, InputMaskSize); - - return new InputMask((long)inputMask, context.PressedKeys); - } - } -} diff --git a/Ryujinx.HLE/HOS/Tamper/CodeEmitters/LegacyArithmetic.cs b/Ryujinx.HLE/HOS/Tamper/CodeEmitters/LegacyArithmetic.cs deleted file mode 100644 index 479c80ec..00000000 --- a/Ryujinx.HLE/HOS/Tamper/CodeEmitters/LegacyArithmetic.cs +++ /dev/null @@ -1,57 +0,0 @@ -using Ryujinx.HLE.Exceptions; -using Ryujinx.HLE.HOS.Tamper.Operations; -using System; - -namespace Ryujinx.HLE.HOS.Tamper.CodeEmitters -{ - /// <summary> - /// Code type 7 allows performing arithmetic on registers. However, it has been deprecated by Code - /// type 9, and is only kept for backwards compatibility. - /// </summary> - class LegacyArithmetic - { - const int OperationWidthIndex = 1; - const int DestinationRegisterIndex = 3; - const int OperationTypeIndex = 4; - const int ValueImmediateIndex = 8; - - const int ValueImmediateSize = 8; - - private const byte Add = 0; // reg += rhs - private const byte Sub = 1; // reg -= rhs - private const byte Mul = 2; // reg *= rhs - private const byte Lsh = 3; // reg <<= rhs - private const byte Rsh = 4; // reg >>= rhs - - public static void Emit(byte[] instruction, CompilationContext context) - { - // 7T0RC000 VVVVVVVV - // T: Width of arithmetic operation(1, 2, 4, or 8 bytes). - // R: Register to apply arithmetic to. - // C: Arithmetic operation to apply, see below. - // V: Value to use for arithmetic operation. - - byte operationWidth = instruction[OperationWidthIndex]; - Register register = context.GetRegister(instruction[DestinationRegisterIndex]); - byte operation = instruction[OperationTypeIndex]; - ulong immediate = InstructionHelper.GetImmediate(instruction, ValueImmediateIndex, ValueImmediateSize); - Value<ulong> rightHandSideValue = new Value<ulong>(immediate); - - void Emit(Type operationType) - { - InstructionHelper.Emit(operationType, operationWidth, context, register, register, rightHandSideValue); - } - - switch (operation) - { - case Add: Emit(typeof(OpAdd<>)); break; - case Sub: Emit(typeof(OpSub<>)); break; - case Mul: Emit(typeof(OpMul<>)); break; - case Lsh: Emit(typeof(OpLsh<>)); break; - case Rsh: Emit(typeof(OpRsh<>)); break; - default: - throw new TamperCompilationException($"Invalid arithmetic operation {operation} in Atmosphere cheat"); - } - } - } -} diff --git a/Ryujinx.HLE/HOS/Tamper/CodeEmitters/LoadRegisterWithConstant.cs b/Ryujinx.HLE/HOS/Tamper/CodeEmitters/LoadRegisterWithConstant.cs deleted file mode 100644 index e4a86d7b..00000000 --- a/Ryujinx.HLE/HOS/Tamper/CodeEmitters/LoadRegisterWithConstant.cs +++ /dev/null @@ -1,28 +0,0 @@ -using Ryujinx.HLE.HOS.Tamper.Operations; - -namespace Ryujinx.HLE.HOS.Tamper.CodeEmitters -{ - /// <summary> - /// Code type 4 allows setting a register to a constant value. - /// </summary> - class LoadRegisterWithConstant - { - const int RegisterIndex = 3; - const int ValueImmediateIndex = 8; - - const int ValueImmediateSize = 16; - - public static void Emit(byte[] instruction, CompilationContext context) - { - // 400R0000 VVVVVVVV VVVVVVVV - // R: Register to use. - // V: Value to load. - - Register destinationRegister = context.GetRegister(instruction[RegisterIndex]); - ulong immediate = InstructionHelper.GetImmediate(instruction, ValueImmediateIndex, ValueImmediateSize); - Value<ulong> sourceValue = new Value<ulong>(immediate); - - context.CurrentOperations.Add(new OpMov<ulong>(destinationRegister, sourceValue)); - } - } -} diff --git a/Ryujinx.HLE/HOS/Tamper/CodeEmitters/LoadRegisterWithMemory.cs b/Ryujinx.HLE/HOS/Tamper/CodeEmitters/LoadRegisterWithMemory.cs deleted file mode 100644 index 87b37a1e..00000000 --- a/Ryujinx.HLE/HOS/Tamper/CodeEmitters/LoadRegisterWithMemory.cs +++ /dev/null @@ -1,58 +0,0 @@ -using Ryujinx.HLE.Exceptions; - -namespace Ryujinx.HLE.HOS.Tamper.CodeEmitters -{ - /// <summary> - /// Code type 5 allows loading a value from memory into a register, either using a fixed address or by - /// dereferencing the destination register. - /// </summary> - class LoadRegisterWithMemory - { - private const int OperationWidthIndex = 1; - private const int MemoryRegionIndex = 2; - private const int DestinationRegisterIndex = 3; - private const int UseDestinationAsSourceIndex = 4; - private const int OffsetImmediateIndex = 6; - - private const int OffsetImmediateSize = 10; - - public static void Emit(byte[] instruction, CompilationContext context) - { - // 5TMR00AA AAAAAAAA - // T: Width of memory read (1, 2, 4, or 8 bytes). - // M: Memory region to write to (0 = Main NSO, 1 = Heap). - // R: Register to load value into. - // A: Immediate offset to use from memory region base. - - // 5TMR10AA AAAAAAAA - // T: Width of memory read(1, 2, 4, or 8 bytes). - // M: Ignored. - // R: Register to use as base address and to load value into. - // A: Immediate offset to use from register R. - - byte operationWidth = instruction[OperationWidthIndex]; - MemoryRegion memoryRegion = (MemoryRegion)instruction[MemoryRegionIndex]; - Register destinationRegister = context.GetRegister(instruction[DestinationRegisterIndex]); - byte useDestinationAsSourceIndex = instruction[UseDestinationAsSourceIndex]; - ulong address = InstructionHelper.GetImmediate(instruction, OffsetImmediateIndex, OffsetImmediateSize); - - Pointer sourceMemory; - - switch (useDestinationAsSourceIndex) - { - case 0: - // Don't use the source register as an additional address offset. - sourceMemory = MemoryHelper.EmitPointer(memoryRegion, address, context); - break; - case 1: - // Use the source register as the base address. - sourceMemory = MemoryHelper.EmitPointer(destinationRegister, address, context); - break; - default: - throw new TamperCompilationException($"Invalid source mode {useDestinationAsSourceIndex} in Atmosphere cheat"); - } - - InstructionHelper.EmitMov(operationWidth, context, destinationRegister, sourceMemory); - } - } -} diff --git a/Ryujinx.HLE/HOS/Tamper/CodeEmitters/MemoryConditional.cs b/Ryujinx.HLE/HOS/Tamper/CodeEmitters/MemoryConditional.cs deleted file mode 100644 index 2048a67b..00000000 --- a/Ryujinx.HLE/HOS/Tamper/CodeEmitters/MemoryConditional.cs +++ /dev/null @@ -1,45 +0,0 @@ -using Ryujinx.HLE.HOS.Tamper.Conditions; - -namespace Ryujinx.HLE.HOS.Tamper.CodeEmitters -{ - /// <summary> - /// Code type 1 performs a comparison of the contents of memory to a static value. - /// If the condition is not met, all instructions until the appropriate conditional block terminator - /// are skipped. - /// </summary> - class MemoryConditional - { - private const int OperationWidthIndex = 1; - private const int MemoryRegionIndex = 2; - private const int ComparisonTypeIndex = 3; - private const int OffsetImmediateIndex = 6; - private const int ValueImmediateIndex = 16; - - private const int OffsetImmediateSize = 10; - private const int ValueImmediateSize4 = 8; - private const int ValueImmediateSize8 = 16; - - public static ICondition Emit(byte[] instruction, CompilationContext context) - { - // 1TMC00AA 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). - // C: Condition to use, see below. - // A: Immediate offset to use from memory region base. - // V: Value to compare to. - - byte operationWidth = instruction[OperationWidthIndex]; - MemoryRegion memoryRegion = (MemoryRegion)instruction[MemoryRegionIndex]; - Comparison comparison = (Comparison)instruction[ComparisonTypeIndex]; - - ulong address = InstructionHelper.GetImmediate(instruction, OffsetImmediateIndex, OffsetImmediateSize); - Pointer sourceMemory = MemoryHelper.EmitPointer(memoryRegion, address, context); - - int valueSize = operationWidth <= 4 ? ValueImmediateSize4 : ValueImmediateSize8; - ulong value = InstructionHelper.GetImmediate(instruction, ValueImmediateIndex, valueSize); - Value<ulong> compareToValue = new Value<ulong>(value); - - return InstructionHelper.CreateCondition(comparison, operationWidth, sourceMemory, compareToValue); - } - } -} diff --git a/Ryujinx.HLE/HOS/Tamper/CodeEmitters/PauseProcess.cs b/Ryujinx.HLE/HOS/Tamper/CodeEmitters/PauseProcess.cs deleted file mode 100644 index 14f99394..00000000 --- a/Ryujinx.HLE/HOS/Tamper/CodeEmitters/PauseProcess.cs +++ /dev/null @@ -1,17 +0,0 @@ -using Ryujinx.HLE.HOS.Tamper.Operations; - -namespace Ryujinx.HLE.HOS.Tamper.CodeEmitters -{ - /// <summary> - /// Code type 0xFF0 pauses the current process. - /// </summary> - class PauseProcess - { - // FF0????? - - public static void Emit(byte[] instruction, CompilationContext context) - { - context.CurrentOperations.Add(new OpProcCtrl(context.Process, true)); - } - } -} diff --git a/Ryujinx.HLE/HOS/Tamper/CodeEmitters/ReadOrWriteStaticRegister.cs b/Ryujinx.HLE/HOS/Tamper/CodeEmitters/ReadOrWriteStaticRegister.cs deleted file mode 100644 index 67775df7..00000000 --- a/Ryujinx.HLE/HOS/Tamper/CodeEmitters/ReadOrWriteStaticRegister.cs +++ /dev/null @@ -1,47 +0,0 @@ -using Ryujinx.HLE.HOS.Tamper.Operations; - -namespace Ryujinx.HLE.HOS.Tamper.CodeEmitters -{ - /// <summary> - /// Code type 0xC3 reads or writes a static register with a given register. - /// NOTE: Registers are saved and restored to a different set of registers than the ones used - /// for the other opcodes (Static Registers). - /// </summary> - class ReadOrWriteStaticRegister - { - private const int StaticRegisterIndex = 5; - private const int RegisterIndex = 7; - - private const byte FirstWriteRegister = 0x80; - - private const int StaticRegisterSize = 2; - - public static void Emit(byte[] instruction, CompilationContext context) - { - // C3000XXx - // XX: Static register index, 0x00 to 0x7F for reading or 0x80 to 0xFF for writing. - // x: Register index. - - ulong staticRegisterIndex = InstructionHelper.GetImmediate(instruction, StaticRegisterIndex, StaticRegisterSize); - Register register = context.GetRegister(instruction[RegisterIndex]); - - IOperand sourceRegister; - IOperand destinationRegister; - - if (staticRegisterIndex < FirstWriteRegister) - { - // Read from static register. - sourceRegister = context.GetStaticRegister((byte)staticRegisterIndex); - destinationRegister = register; - } - else - { - // Write to static register. - sourceRegister = register; - destinationRegister = context.GetStaticRegister((byte)(staticRegisterIndex - FirstWriteRegister)); - } - - context.CurrentOperations.Add(new OpMov<ulong>(destinationRegister, sourceRegister)); - } - } -} diff --git a/Ryujinx.HLE/HOS/Tamper/CodeEmitters/RegisterConditional.cs b/Ryujinx.HLE/HOS/Tamper/CodeEmitters/RegisterConditional.cs deleted file mode 100644 index fcd3a9eb..00000000 --- a/Ryujinx.HLE/HOS/Tamper/CodeEmitters/RegisterConditional.cs +++ /dev/null @@ -1,106 +0,0 @@ -using Ryujinx.HLE.Exceptions; -using Ryujinx.HLE.HOS.Tamper.Conditions; -using Ryujinx.HLE.HOS.Tamper.Operations; - -namespace Ryujinx.HLE.HOS.Tamper.CodeEmitters -{ - /// <summary> - /// Code type 0xC0 performs a comparison of the contents of a register and another value. - /// This code support multiple operand types, see below. If the condition is not met, - /// all instructions until the appropriate conditional block terminator are skipped. - /// </summary> - class RegisterConditional - { - private const int OperationWidthIndex = 2; - private const int ComparisonTypeIndex = 3; - private const int SourceRegisterIndex = 4; - private const int OperandTypeIndex = 5; - private const int RegisterOrMemoryRegionIndex = 6; - private const int OffsetImmediateIndex = 7; - private const int ValueImmediateIndex = 8; - - private const int MemoryRegionWithOffsetImmediate = 0; - private const int MemoryRegionWithOffsetRegister = 1; - private const int AddressRegisterWithOffsetImmediate = 2; - private const int AddressRegisterWithOffsetRegister = 3; - private const int OffsetImmediate = 4; - private const int AddressRegister = 5; - - private const int OffsetImmediateSize = 9; - private const int ValueImmediateSize8 = 8; - private const int ValueImmediateSize16 = 16; - - public static ICondition Emit(byte[] instruction, CompilationContext context) - { - // C0TcSX## - // C0TcS0Ma aaaaaaaa - // C0TcS1Mr - // C0TcS2Ra aaaaaaaa - // C0TcS3Rr - // C0TcS400 VVVVVVVV (VVVVVVVV) - // C0TcS5X0 - // T: Width of memory write(1, 2, 4, or 8 bytes). - // c: Condition to use, see below. - // S: Source Register. - // X: Operand Type, see below. - // M: Memory Type(operand types 0 and 1). - // R: Address Register(operand types 2 and 3). - // a: Relative Address(operand types 0 and 2). - // r: Offset Register(operand types 1 and 3). - // X: Other Register(operand type 5). - // V: Value to compare to(operand type 4). - - byte operationWidth = instruction[OperationWidthIndex]; - Comparison comparison = (Comparison)instruction[ComparisonTypeIndex]; - Register sourceRegister = context.GetRegister(instruction[SourceRegisterIndex]); - byte operandType = instruction[OperandTypeIndex]; - byte registerOrMemoryRegion = instruction[RegisterOrMemoryRegionIndex]; - byte offsetRegisterIndex = instruction[OffsetImmediateIndex]; - ulong offsetImmediate; - ulong valueImmediate; - int valueImmediateSize; - Register addressRegister; - Register offsetRegister; - IOperand sourceOperand; - - switch (operandType) - { - case MemoryRegionWithOffsetImmediate: - // *(?x + #a) - offsetImmediate = InstructionHelper.GetImmediate(instruction, OffsetImmediateIndex, OffsetImmediateSize); - sourceOperand = MemoryHelper.EmitPointer((MemoryRegion)registerOrMemoryRegion, offsetImmediate, context); - break; - case MemoryRegionWithOffsetRegister: - // *(?x + $r) - offsetRegister = context.GetRegister(offsetRegisterIndex); - sourceOperand = MemoryHelper.EmitPointer((MemoryRegion)registerOrMemoryRegion, offsetRegister, context); - break; - case AddressRegisterWithOffsetImmediate: - // *($R + #a) - addressRegister = context.GetRegister(registerOrMemoryRegion); - offsetImmediate = InstructionHelper.GetImmediate(instruction, OffsetImmediateIndex, OffsetImmediateSize); - sourceOperand = MemoryHelper.EmitPointer(addressRegister, offsetImmediate, context); - break; - case AddressRegisterWithOffsetRegister: - // *($R + $r) - addressRegister = context.GetRegister(registerOrMemoryRegion); - offsetRegister = context.GetRegister(offsetRegisterIndex); - sourceOperand = MemoryHelper.EmitPointer(addressRegister, offsetRegister, context); - break; - case OffsetImmediate: - valueImmediateSize = operationWidth <= 4 ? ValueImmediateSize8 : ValueImmediateSize16; - valueImmediate = InstructionHelper.GetImmediate(instruction, ValueImmediateIndex, valueImmediateSize); - sourceOperand = new Value<ulong>(valueImmediate); - break; - case AddressRegister: - // $V - sourceOperand = context.GetRegister(registerOrMemoryRegion); - break; - default: - throw new TamperCompilationException($"Invalid operand type {operandType} in Atmosphere cheat"); - } - - return InstructionHelper.CreateCondition(comparison, operationWidth, sourceRegister, sourceOperand); - } - } -} diff --git a/Ryujinx.HLE/HOS/Tamper/CodeEmitters/ResumeProcess.cs b/Ryujinx.HLE/HOS/Tamper/CodeEmitters/ResumeProcess.cs deleted file mode 100644 index 02f76e22..00000000 --- a/Ryujinx.HLE/HOS/Tamper/CodeEmitters/ResumeProcess.cs +++ /dev/null @@ -1,17 +0,0 @@ -using Ryujinx.HLE.HOS.Tamper.Operations; - -namespace Ryujinx.HLE.HOS.Tamper.CodeEmitters -{ - /// <summary> - /// Code type 0xFF1 resumes the current process. - /// </summary> - class ResumeProcess - { - // FF1????? - - public static void Emit(byte[] instruction, CompilationContext context) - { - context.CurrentOperations.Add(new OpProcCtrl(context.Process, false)); - } - } -} diff --git a/Ryujinx.HLE/HOS/Tamper/CodeEmitters/SaveOrRestoreRegister.cs b/Ryujinx.HLE/HOS/Tamper/CodeEmitters/SaveOrRestoreRegister.cs deleted file mode 100644 index d2e13311..00000000 --- a/Ryujinx.HLE/HOS/Tamper/CodeEmitters/SaveOrRestoreRegister.cs +++ /dev/null @@ -1,65 +0,0 @@ -using Ryujinx.HLE.Exceptions; -using Ryujinx.HLE.HOS.Tamper.Operations; - -namespace Ryujinx.HLE.HOS.Tamper.CodeEmitters -{ - /// <summary> - /// Code type 0xC1 performs saving or restoring of registers. - /// NOTE: Registers are saved and restored to a different set of registers than the ones used - /// for the other opcodes (Save Registers). - /// </summary> - class SaveOrRestoreRegister - { - private const int DestinationRegisterIndex = 3; - private const int SourceRegisterIndex = 5; - private const int OperationTypeIndex = 6; - - private const int RestoreRegister = 0; - private const int SaveRegister = 1; - private const int ClearSavedValue = 2; - private const int ClearRegister = 3; - - public static void Emit(byte[] instruction, CompilationContext context) - { - // C10D0Sx0 - // D: Destination index. - // S: Source index. - // x: Operand Type, see below. - - byte destinationRegIndex = instruction[DestinationRegisterIndex]; - byte sourceRegIndex = instruction[SourceRegisterIndex]; - byte operationType = instruction[OperationTypeIndex]; - Impl(operationType, destinationRegIndex, sourceRegIndex, context); - } - - public static void Impl(byte operationType, byte destinationRegIndex, byte sourceRegIndex, CompilationContext context) - { - IOperand destinationOperand; - IOperand sourceOperand; - - switch (operationType) - { - case RestoreRegister: - destinationOperand = context.GetRegister(destinationRegIndex); - sourceOperand = context.GetSavedRegister(sourceRegIndex); - break; - case SaveRegister: - destinationOperand = context.GetSavedRegister(destinationRegIndex); - sourceOperand = context.GetRegister(sourceRegIndex); - break; - case ClearSavedValue: - destinationOperand = new Value<ulong>(0); - sourceOperand = context.GetSavedRegister(sourceRegIndex); - break; - case ClearRegister: - destinationOperand = new Value<ulong>(0); - sourceOperand = context.GetRegister(sourceRegIndex); - break; - default: - throw new TamperCompilationException($"Invalid register operation type {operationType} in Atmosphere cheat"); - } - - context.CurrentOperations.Add(new OpMov<ulong>(destinationOperand, sourceOperand)); - } - } -} diff --git a/Ryujinx.HLE/HOS/Tamper/CodeEmitters/SaveOrRestoreRegisterWithMask.cs b/Ryujinx.HLE/HOS/Tamper/CodeEmitters/SaveOrRestoreRegisterWithMask.cs deleted file mode 100644 index 2264e9d1..00000000 --- a/Ryujinx.HLE/HOS/Tamper/CodeEmitters/SaveOrRestoreRegisterWithMask.cs +++ /dev/null @@ -1,33 +0,0 @@ -namespace Ryujinx.HLE.HOS.Tamper.CodeEmitters -{ - /// <summary> - /// Code type 0xC2 performs saving or restoring of multiple registers using a bitmask. - /// NOTE: Registers are saved and restored to a different set of registers than the ones used - /// for the other opcodes (Save Registers). - /// </summary> - class SaveOrRestoreRegisterWithMask - { - private const int OperationTypeIndex = 2; - private const int RegisterMaskIndex = 4; - - private const int RegisterMaskSize = 4; - - public static void Emit(byte[] instruction, CompilationContext context) - { - // C2x0XXXX - // x: Operand Type, see below. - // X: 16-bit bitmask, bit i == save or restore register i. - - byte operationType = instruction[OperationTypeIndex]; - ulong mask = InstructionHelper.GetImmediate(instruction, RegisterMaskIndex, RegisterMaskSize); - - for (byte regIndex = 0; mask != 0; mask >>= 1, regIndex++) - { - if ((mask & 0x1) != 0) - { - SaveOrRestoreRegister.Impl(operationType, regIndex, regIndex, context); - } - } - } - } -} diff --git a/Ryujinx.HLE/HOS/Tamper/CodeEmitters/StartEndLoop.cs b/Ryujinx.HLE/HOS/Tamper/CodeEmitters/StartEndLoop.cs deleted file mode 100644 index 1e399b59..00000000 --- a/Ryujinx.HLE/HOS/Tamper/CodeEmitters/StartEndLoop.cs +++ /dev/null @@ -1,72 +0,0 @@ -using Ryujinx.HLE.Exceptions; -using Ryujinx.HLE.HOS.Tamper.Operations; - -namespace Ryujinx.HLE.HOS.Tamper.CodeEmitters -{ - /// <summary> - /// Code type 3 allows for iterating in a loop a fixed number of times. - /// </summary> - class StartEndLoop - { - private const int StartOrEndIndex = 1; - private const int IterationRegisterIndex = 3; - private const int IterationsImmediateIndex = 8; - - private const int IterationsImmediateSize = 8; - - private const byte LoopBegin = 0; - private const byte LoopEnd = 1; - - public static void Emit(byte[] instruction, CompilationContext context) - { - // 300R0000 VVVVVVVV - // R: Register to use as loop counter. - // V: Number of iterations to loop. - - // 310R0000 - - byte mode = instruction[StartOrEndIndex]; - byte iterationRegisterIndex = instruction[IterationRegisterIndex]; - - switch (mode) - { - case LoopBegin: - // Just start a new compilation block and parse the instruction itself at the end. - context.BlockStack.Push(new OperationBlock(instruction)); - return; - case LoopEnd: - break; - default: - throw new TamperCompilationException($"Invalid loop {mode} in Atmosphere cheat"); - } - - // Use the loop begin instruction stored in the stack. - instruction = context.CurrentBlock.BaseInstruction; - CodeType codeType = InstructionHelper.GetCodeType(instruction); - - if (codeType != CodeType.StartEndLoop) - { - throw new TamperCompilationException($"Loop end does not match code type {codeType} in Atmosphere cheat"); - } - - // Validate if the register in the beginning and end are the same. - - byte oldIterationRegisterIndex = instruction[IterationRegisterIndex]; - - if (iterationRegisterIndex != oldIterationRegisterIndex) - { - throw new TamperCompilationException($"The register used for the loop changed from {oldIterationRegisterIndex} to {iterationRegisterIndex} in Atmosphere cheat"); - } - - Register iterationRegister = context.GetRegister(iterationRegisterIndex); - ulong immediate = InstructionHelper.GetImmediate(instruction, IterationsImmediateIndex, IterationsImmediateSize); - - // Create a loop block with the current operations and nest it in the upper - // block of the stack. - - ForBlock block = new ForBlock(immediate, iterationRegister, context.CurrentOperations); - context.BlockStack.Pop(); - context.CurrentOperations.Add(block); - } - } -} diff --git a/Ryujinx.HLE/HOS/Tamper/CodeEmitters/StoreConstantToAddress.cs b/Ryujinx.HLE/HOS/Tamper/CodeEmitters/StoreConstantToAddress.cs deleted file mode 100644 index 933646bd..00000000 --- a/Ryujinx.HLE/HOS/Tamper/CodeEmitters/StoreConstantToAddress.cs +++ /dev/null @@ -1,41 +0,0 @@ -namespace Ryujinx.HLE.HOS.Tamper.CodeEmitters -{ - /// <summary> - /// Code type 0 allows writing a static value to a memory address. - /// </summary> - class StoreConstantToAddress - { - private const int OperationWidthIndex = 1; - private const int MemoryRegionIndex = 2; - private const int OffsetRegisterIndex = 3; - private const int OffsetImmediateIndex = 6; - private const int ValueImmediateIndex = 16; - - private const int OffsetImmediateSize = 10; - private const int ValueImmediateSize8 = 8; - private const int ValueImmediateSize16 = 16; - - public static void Emit(byte[] instruction, CompilationContext context) - { - // 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). - // R: Register to use as an offset from memory region base. - // A: Immediate offset to use from memory region base. - // V: Value to write. - - byte operationWidth = instruction[OperationWidthIndex]; - MemoryRegion memoryRegion = (MemoryRegion)instruction[MemoryRegionIndex]; - Register offsetRegister = context.GetRegister(instruction[OffsetRegisterIndex]); - ulong offsetImmediate = InstructionHelper.GetImmediate(instruction, OffsetImmediateIndex, OffsetImmediateSize); - - Pointer dstMem = MemoryHelper.EmitPointer(memoryRegion, offsetRegister, offsetImmediate, context); - - int valueImmediateSize = operationWidth <= 4 ? ValueImmediateSize8 : ValueImmediateSize16; - ulong valueImmediate = InstructionHelper.GetImmediate(instruction, ValueImmediateIndex, valueImmediateSize); - Value<ulong> storeValue = new Value<ulong>(valueImmediate); - - InstructionHelper.EmitMov(operationWidth, context, dstMem, storeValue); - } - } -} diff --git a/Ryujinx.HLE/HOS/Tamper/CodeEmitters/StoreConstantToMemory.cs b/Ryujinx.HLE/HOS/Tamper/CodeEmitters/StoreConstantToMemory.cs deleted file mode 100644 index 5f036969..00000000 --- a/Ryujinx.HLE/HOS/Tamper/CodeEmitters/StoreConstantToMemory.cs +++ /dev/null @@ -1,71 +0,0 @@ -using Ryujinx.HLE.Exceptions; -using Ryujinx.HLE.HOS.Tamper.Operations; - -namespace Ryujinx.HLE.HOS.Tamper.CodeEmitters -{ - /// <summary> - /// Code type 6 allows writing a fixed value to a memory address specified by a register. - /// </summary> - class StoreConstantToMemory - { - private const int OperationWidthIndex = 1; - private const int AddressRegisterIndex = 3; - private const int IncrementAddressRegisterIndex = 4; - private const int UseOffsetRegisterIndex = 5; - private const int OffsetRegisterIndex = 6; - private const int ValueImmediateIndex = 8; - - private const int ValueImmediateSize = 16; - - public static void Emit(byte[] instruction, CompilationContext context) - { - // 6T0RIor0 VVVVVVVV VVVVVVVV - // T: Width of memory write(1, 2, 4, or 8 bytes). - // R: Register used as base memory address. - // I: Increment register flag(0 = do not increment R, 1 = increment R by T). - // o: Offset register enable flag(0 = do not add r to address, 1 = add r to address). - // r: Register used as offset when o is 1. - // V: Value to write to memory. - - byte operationWidth = instruction[OperationWidthIndex]; - Register sourceRegister = context.GetRegister(instruction[AddressRegisterIndex]); - byte incrementAddressRegister = instruction[IncrementAddressRegisterIndex]; - byte useOffsetRegister = instruction[UseOffsetRegisterIndex]; - ulong immediate = InstructionHelper.GetImmediate(instruction, ValueImmediateIndex, ValueImmediateSize); - Value<ulong> storeValue = new Value<ulong>(immediate); - - Pointer destinationMemory; - - switch (useOffsetRegister) - { - case 0: - // Don't offset the address register by another register. - destinationMemory = MemoryHelper.EmitPointer(sourceRegister, context); - break; - case 1: - // Replace the source address by the sum of the base and offset registers. - Register offsetRegister = context.GetRegister(instruction[OffsetRegisterIndex]); - destinationMemory = MemoryHelper.EmitPointer(sourceRegister, offsetRegister, context); - break; - default: - throw new TamperCompilationException($"Invalid offset mode {useOffsetRegister} in Atmosphere cheat"); - } - - InstructionHelper.EmitMov(operationWidth, context, destinationMemory, storeValue); - - switch (incrementAddressRegister) - { - case 0: - // Don't increment the address register by operationWidth. - break; - case 1: - // Increment the address register by operationWidth. - IOperand increment = new Value<ulong>(operationWidth); - context.CurrentOperations.Add(new OpAdd<ulong>(sourceRegister, sourceRegister, increment)); - break; - default: - throw new TamperCompilationException($"Invalid increment mode {incrementAddressRegister} in Atmosphere cheat"); - } - } - } -} diff --git a/Ryujinx.HLE/HOS/Tamper/CodeEmitters/StoreRegisterToMemory.cs b/Ryujinx.HLE/HOS/Tamper/CodeEmitters/StoreRegisterToMemory.cs deleted file mode 100644 index 422ff298..00000000 --- a/Ryujinx.HLE/HOS/Tamper/CodeEmitters/StoreRegisterToMemory.cs +++ /dev/null @@ -1,99 +0,0 @@ -using Ryujinx.HLE.Exceptions; -using Ryujinx.HLE.HOS.Tamper.Operations; - -namespace Ryujinx.HLE.HOS.Tamper.CodeEmitters -{ - /// <summary> - /// Code type 10 allows writing a register to memory. - /// </summary> - class StoreRegisterToMemory - { - private const int OperationWidthIndex = 1; - private const int SourceRegisterIndex = 2; - private const int AddressRegisterIndex = 3; - private const int IncrementAddressRegisterIndex = 4; - private const int AddressingTypeIndex = 5; - private const int RegisterOrMemoryRegionIndex = 6; - private const int OffsetImmediateIndex = 7; - - private const int AddressRegister = 0; - private const int AddressRegisterWithOffsetRegister = 1; - private const int OffsetImmediate = 2; - private const int MemoryRegionWithOffsetRegister = 3; - private const int MemoryRegionWithOffsetImmediate = 4; - private const int MemoryRegionWithOffsetRegisterAndImmediate = 5; - - private const int OffsetImmediateSize1 = 1; - private const int OffsetImmediateSize9 = 9; - - public static void Emit(byte[] instruction, CompilationContext context) - { - // ATSRIOxa (aaaaaaaa) - // T: Width of memory write (1, 2, 4, or 8 bytes). - // S: Register to write to memory. - // R: Register to use as base address. - // I: Increment register flag (0 = do not increment R, 1 = increment R by T). - // O: Offset type, see below. - // x: Register used as offset when O is 1, Memory type when O is 3, 4 or 5. - // a: Value used as offset when O is 2, 4 or 5. - - byte operationWidth = instruction[OperationWidthIndex]; - Register sourceRegister = context.GetRegister(instruction[SourceRegisterIndex]); - Register addressRegister = context.GetRegister(instruction[AddressRegisterIndex]); - byte incrementAddressRegister = instruction[IncrementAddressRegisterIndex]; - byte offsetType = instruction[AddressingTypeIndex]; - byte registerOrMemoryRegion = instruction[RegisterOrMemoryRegionIndex]; - int immediateSize = instruction.Length <= 8 ? OffsetImmediateSize1 : OffsetImmediateSize9; - ulong immediate = InstructionHelper.GetImmediate(instruction, OffsetImmediateIndex, immediateSize); - - Pointer destinationMemory; - - switch (offsetType) - { - case AddressRegister: - // *($R) = $S - destinationMemory = MemoryHelper.EmitPointer(addressRegister, context); - break; - case AddressRegisterWithOffsetRegister: - // *($R + $x) = $S - Register offsetRegister = context.GetRegister(registerOrMemoryRegion); - destinationMemory = MemoryHelper.EmitPointer(addressRegister, offsetRegister, context); - break; - case OffsetImmediate: - // *(#a) = $S - destinationMemory = MemoryHelper.EmitPointer(addressRegister, immediate, context); - break; - case MemoryRegionWithOffsetRegister: - // *(?x + $R) = $S - destinationMemory = MemoryHelper.EmitPointer((MemoryRegion)registerOrMemoryRegion, addressRegister, context); - break; - case MemoryRegionWithOffsetImmediate: - // *(?x + #a) = $S - destinationMemory = MemoryHelper.EmitPointer((MemoryRegion)registerOrMemoryRegion, immediate, context); - break; - case MemoryRegionWithOffsetRegisterAndImmediate: - // *(?x + #a + $R) = $S - destinationMemory = MemoryHelper.EmitPointer((MemoryRegion)registerOrMemoryRegion, addressRegister, immediate, context); - break; - default: - throw new TamperCompilationException($"Invalid offset type {offsetType} in Atmosphere cheat"); - } - - InstructionHelper.EmitMov(operationWidth, context, destinationMemory, sourceRegister); - - switch (incrementAddressRegister) - { - case 0: - // Don't increment the address register by operationWidth. - break; - case 1: - // Increment the address register by operationWidth. - IOperand increment = new Value<ulong>(operationWidth); - context.CurrentOperations.Add(new OpAdd<ulong>(addressRegister, addressRegister, increment)); - break; - default: - throw new TamperCompilationException($"Invalid increment mode {incrementAddressRegister} in Atmosphere cheat"); - } - } - } -} diff --git a/Ryujinx.HLE/HOS/Tamper/CodeType.cs b/Ryujinx.HLE/HOS/Tamper/CodeType.cs deleted file mode 100644 index 7c4f2286..00000000 --- a/Ryujinx.HLE/HOS/Tamper/CodeType.cs +++ /dev/null @@ -1,110 +0,0 @@ -namespace Ryujinx.HLE.HOS.Tamper -{ - /// <summary> - /// The opcodes specified for the Atmosphere Cheat VM. - /// </summary> - enum CodeType - { - /// <summary> - /// Code type 0 allows writing a static value to a memory address. - /// </summary> - StoreConstantToAddress = 0x0, - - /// <summary> - /// Code type 1 performs a comparison of the contents of memory to a static value. - /// If the condition is not met, all instructions until the appropriate conditional block terminator - /// are skipped. - /// </summary> - BeginMemoryConditionalBlock = 0x1, - - /// <summary> - /// Code type 2 marks the end of a conditional block (started by Code Type 1 or Code Type 8). - /// </summary> - EndConditionalBlock = 0x2, - - /// <summary> - /// Code type 3 allows for iterating in a loop a fixed number of times. - /// </summary> - StartEndLoop = 0x3, - - /// <summary> - /// Code type 4 allows setting a register to a constant value. - /// </summary> - LoadRegisterWithContant = 0x4, - - /// <summary> - /// Code type 5 allows loading a value from memory into a register, either using a fixed address or by - /// dereferencing the destination register. - /// </summary> - LoadRegisterWithMemory = 0x5, - - /// <summary> - /// Code type 6 allows writing a fixed value to a memory address specified by a register. - /// </summary> - StoreConstantToMemory = 0x6, - - /// <summary> - /// Code type 7 allows performing arithmetic on registers. However, it has been deprecated by Code - /// type 9, and is only kept for backwards compatibility. - /// </summary> - LegacyArithmetic = 0x7, - - /// <summary> - /// Code type 8 enters or skips a conditional block based on whether a key combination is pressed. - /// </summary> - BeginKeypressConditionalBlock = 0x8, - - /// <summary> - /// Code type 9 allows performing arithmetic on registers. - /// </summary> - Arithmetic = 0x9, - - /// <summary> - /// Code type 10 allows writing a register to memory. - /// </summary> - StoreRegisterToMemory = 0xA, - - /// <summary> - /// Code type 0xC0 performs a comparison of the contents of a register and another value. - /// This code support multiple operand types, see below. If the condition is not met, - /// all instructions until the appropriate conditional block terminator are skipped. - /// </summary> - BeginRegisterConditionalBlock = 0xC0, - - /// <summary> - /// Code type 0xC1 performs saving or restoring of registers. - /// NOTE: Registers are saved and restored to a different set of registers than the ones used - /// for the other opcodes (Save Registers). - /// </summary> - SaveOrRestoreRegister = 0xC1, - - /// <summary> - /// Code type 0xC2 performs saving or restoring of multiple registers using a bitmask. - /// NOTE: Registers are saved and restored to a different set of registers than the ones used - /// for the other opcodes (Save Registers). - /// </summary> - SaveOrRestoreRegisterWithMask = 0xC2, - - /// <summary> - /// Code type 0xC3 reads or writes a static register with a given register. - /// NOTE: Registers are saved and restored to a different set of registers than the ones used - /// for the other opcodes (Static Registers). - /// </summary> - ReadOrWriteStaticRegister = 0xC3, - - /// <summary> - /// Code type 0xFF0 pauses the current process. - /// </summary> - PauseProcess = 0xFF0, - - /// <summary> - /// Code type 0xFF1 resumes the current process. - /// </summary> - ResumeProcess = 0xFF1, - - /// <summary> - /// Code type 0xFFF writes a debug log. - /// </summary> - DebugLog = 0xFFF - } -} diff --git a/Ryujinx.HLE/HOS/Tamper/Comparison.cs b/Ryujinx.HLE/HOS/Tamper/Comparison.cs deleted file mode 100644 index cd162b1c..00000000 --- a/Ryujinx.HLE/HOS/Tamper/Comparison.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Ryujinx.HLE.HOS.Tamper -{ - /// <summary> - /// The comparisons used by conditional operations. - /// </summary> - enum Comparison - { - Greater = 1, - GreaterOrEqual = 2, - Less = 3, - LessOrEqual = 4, - Equal = 5, - NotEqual = 6 - } -} diff --git a/Ryujinx.HLE/HOS/Tamper/CompilationContext.cs b/Ryujinx.HLE/HOS/Tamper/CompilationContext.cs deleted file mode 100644 index 45a47f44..00000000 --- a/Ryujinx.HLE/HOS/Tamper/CompilationContext.cs +++ /dev/null @@ -1,75 +0,0 @@ -using Ryujinx.HLE.HOS.Tamper.Operations; -using System.Collections.Generic; - -namespace Ryujinx.HLE.HOS.Tamper -{ - class CompilationContext - { - public OperationBlock CurrentBlock => BlockStack.Peek(); - public List<IOperation> CurrentOperations => CurrentBlock.Operations; - - public ITamperedProcess Process { get; } - public Parameter<long> PressedKeys { get; } - public Stack<OperationBlock> BlockStack { get; } - public Dictionary<byte, Register> Registers { get; } - public Dictionary<byte, Register> SavedRegisters { get; } - public Dictionary<byte, Register> StaticRegisters { get; } - public ulong ExeAddress { get; } - public ulong HeapAddress { get; } - public ulong AliasAddress { get; } - public ulong AslrAddress { get; } - - public CompilationContext(ulong exeAddress, ulong heapAddress, ulong aliasAddress, ulong aslrAddress, ITamperedProcess process) - { - Process = process; - PressedKeys = new Parameter<long>(0); - BlockStack = new Stack<OperationBlock>(); - Registers = new Dictionary<byte, Register>(); - SavedRegisters = new Dictionary<byte, Register>(); - StaticRegisters = new Dictionary<byte, Register>(); - ExeAddress = exeAddress; - HeapAddress = heapAddress; - AliasAddress = aliasAddress; - AslrAddress = aslrAddress; - } - - public Register GetRegister(byte index) - { - if (Registers.TryGetValue(index, out Register register)) - { - return register; - } - - register = new Register($"R_{index:X2}"); - Registers.Add(index, register); - - return register; - } - - public Register GetSavedRegister(byte index) - { - if (SavedRegisters.TryGetValue(index, out Register register)) - { - return register; - } - - register = new Register($"S_{index:X2}"); - SavedRegisters.Add(index, register); - - return register; - } - - public Register GetStaticRegister(byte index) - { - if (SavedRegisters.TryGetValue(index, out Register register)) - { - return register; - } - - register = new Register($"T_{index:X2}"); - SavedRegisters.Add(index, register); - - return register; - } - } -} diff --git a/Ryujinx.HLE/HOS/Tamper/Conditions/CondEQ.cs b/Ryujinx.HLE/HOS/Tamper/Conditions/CondEQ.cs deleted file mode 100644 index ad5bd223..00000000 --- a/Ryujinx.HLE/HOS/Tamper/Conditions/CondEQ.cs +++ /dev/null @@ -1,21 +0,0 @@ -using Ryujinx.HLE.HOS.Tamper.Operations; - -namespace Ryujinx.HLE.HOS.Tamper.Conditions -{ - class CondEQ<T> : ICondition where T : unmanaged - { - private IOperand _lhs; - private IOperand _rhs; - - public CondEQ(IOperand lhs, IOperand rhs) - { - _lhs = lhs; - _rhs = rhs; - } - - public bool Evaluate() - { - return (dynamic)_lhs.Get<T>() == (dynamic)_rhs.Get<T>(); - } - } -} diff --git a/Ryujinx.HLE/HOS/Tamper/Conditions/CondGE.cs b/Ryujinx.HLE/HOS/Tamper/Conditions/CondGE.cs deleted file mode 100644 index d9ad6d81..00000000 --- a/Ryujinx.HLE/HOS/Tamper/Conditions/CondGE.cs +++ /dev/null @@ -1,21 +0,0 @@ -using Ryujinx.HLE.HOS.Tamper.Operations; - -namespace Ryujinx.HLE.HOS.Tamper.Conditions -{ - class CondGE<T> : ICondition where T : unmanaged - { - private IOperand _lhs; - private IOperand _rhs; - - public CondGE(IOperand lhs, IOperand rhs) - { - _lhs = lhs; - _rhs = rhs; - } - - public bool Evaluate() - { - return (dynamic)_lhs.Get<T>() >= (dynamic)_rhs.Get<T>(); - } - } -} diff --git a/Ryujinx.HLE/HOS/Tamper/Conditions/CondGT.cs b/Ryujinx.HLE/HOS/Tamper/Conditions/CondGT.cs deleted file mode 100644 index 262457da..00000000 --- a/Ryujinx.HLE/HOS/Tamper/Conditions/CondGT.cs +++ /dev/null @@ -1,21 +0,0 @@ -using Ryujinx.HLE.HOS.Tamper.Operations; - -namespace Ryujinx.HLE.HOS.Tamper.Conditions -{ - class CondGT<T> : ICondition where T : unmanaged - { - private IOperand _lhs; - private IOperand _rhs; - - public CondGT(IOperand lhs, IOperand rhs) - { - _lhs = lhs; - _rhs = rhs; - } - - public bool Evaluate() - { - return (dynamic)_lhs.Get<T>() > (dynamic)_rhs.Get<T>(); - } - } -} diff --git a/Ryujinx.HLE/HOS/Tamper/Conditions/CondLE.cs b/Ryujinx.HLE/HOS/Tamper/Conditions/CondLE.cs deleted file mode 100644 index fd488bc1..00000000 --- a/Ryujinx.HLE/HOS/Tamper/Conditions/CondLE.cs +++ /dev/null @@ -1,21 +0,0 @@ -using Ryujinx.HLE.HOS.Tamper.Operations; - -namespace Ryujinx.HLE.HOS.Tamper.Conditions -{ - class CondLE<T> : ICondition where T : unmanaged - { - private IOperand _lhs; - private IOperand _rhs; - - public CondLE(IOperand lhs, IOperand rhs) - { - _lhs = lhs; - _rhs = rhs; - } - - public bool Evaluate() - { - return (dynamic)_lhs.Get<T>() <= (dynamic)_rhs.Get<T>(); - } - } -} diff --git a/Ryujinx.HLE/HOS/Tamper/Conditions/CondLT.cs b/Ryujinx.HLE/HOS/Tamper/Conditions/CondLT.cs deleted file mode 100644 index 744eb5dc..00000000 --- a/Ryujinx.HLE/HOS/Tamper/Conditions/CondLT.cs +++ /dev/null @@ -1,21 +0,0 @@ -using Ryujinx.HLE.HOS.Tamper.Operations; - -namespace Ryujinx.HLE.HOS.Tamper.Conditions -{ - class CondLT<T> : ICondition where T : unmanaged - { - private IOperand _lhs; - private IOperand _rhs; - - public CondLT(IOperand lhs, IOperand rhs) - { - _lhs = lhs; - _rhs = rhs; - } - - public bool Evaluate() - { - return (dynamic)_lhs.Get<T>() < (dynamic)_rhs.Get<T>(); - } - } -} diff --git a/Ryujinx.HLE/HOS/Tamper/Conditions/CondNE.cs b/Ryujinx.HLE/HOS/Tamper/Conditions/CondNE.cs deleted file mode 100644 index 2709ad92..00000000 --- a/Ryujinx.HLE/HOS/Tamper/Conditions/CondNE.cs +++ /dev/null @@ -1,21 +0,0 @@ -using Ryujinx.HLE.HOS.Tamper.Operations; - -namespace Ryujinx.HLE.HOS.Tamper.Conditions -{ - class CondNE<T> : ICondition where T : unmanaged - { - private IOperand _lhs; - private IOperand _rhs; - - public CondNE(IOperand lhs, IOperand rhs) - { - _lhs = lhs; - _rhs = rhs; - } - - public bool Evaluate() - { - return (dynamic)_lhs.Get<T>() != (dynamic)_rhs.Get<T>(); - } - } -} diff --git a/Ryujinx.HLE/HOS/Tamper/Conditions/ICondition.cs b/Ryujinx.HLE/HOS/Tamper/Conditions/ICondition.cs deleted file mode 100644 index f15ceffe..00000000 --- a/Ryujinx.HLE/HOS/Tamper/Conditions/ICondition.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Ryujinx.HLE.HOS.Tamper.Conditions -{ - interface ICondition - { - bool Evaluate(); - } -} diff --git a/Ryujinx.HLE/HOS/Tamper/Conditions/InputMask.cs b/Ryujinx.HLE/HOS/Tamper/Conditions/InputMask.cs deleted file mode 100644 index 8d75a0e1..00000000 --- a/Ryujinx.HLE/HOS/Tamper/Conditions/InputMask.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace Ryujinx.HLE.HOS.Tamper.Conditions -{ - class InputMask : ICondition - { - private long _mask; - private Parameter<long> _input; - - public InputMask(long mask, Parameter<long> input) - { - _mask = mask; - _input = input; - } - - public bool Evaluate() - { - return (_input.Value & _mask) == _mask; - } - } -} diff --git a/Ryujinx.HLE/HOS/Tamper/ITamperProgram.cs b/Ryujinx.HLE/HOS/Tamper/ITamperProgram.cs deleted file mode 100644 index 8458d95d..00000000 --- a/Ryujinx.HLE/HOS/Tamper/ITamperProgram.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Ryujinx.HLE.HOS.Services.Hid; - -namespace Ryujinx.HLE.HOS.Tamper -{ - interface ITamperProgram - { - bool IsEnabled { get; set; } - string Name { get; } - bool TampersCodeMemory { get; set; } - ITamperedProcess Process { get; } - void Execute(ControllerKeys pressedKeys); - } -} diff --git a/Ryujinx.HLE/HOS/Tamper/ITamperedProcess.cs b/Ryujinx.HLE/HOS/Tamper/ITamperedProcess.cs deleted file mode 100644 index c86e1021..00000000 --- a/Ryujinx.HLE/HOS/Tamper/ITamperedProcess.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Ryujinx.HLE.HOS.Kernel.Process; - -namespace Ryujinx.HLE.HOS.Tamper -{ - interface ITamperedProcess - { - ProcessState State { get; } - - bool TamperedCodeMemory { get; set; } - - T ReadMemory<T>(ulong va) where T : unmanaged; - void WriteMemory<T>(ulong va, T value) where T : unmanaged; - void PauseProcess(); - void ResumeProcess(); - } -} diff --git a/Ryujinx.HLE/HOS/Tamper/InstructionHelper.cs b/Ryujinx.HLE/HOS/Tamper/InstructionHelper.cs deleted file mode 100644 index e85d99c7..00000000 --- a/Ryujinx.HLE/HOS/Tamper/InstructionHelper.cs +++ /dev/null @@ -1,133 +0,0 @@ -using Ryujinx.HLE.Exceptions; -using Ryujinx.HLE.HOS.Tamper.Conditions; -using Ryujinx.HLE.HOS.Tamper.Operations; -using System; -using System.Globalization; - -namespace Ryujinx.HLE.HOS.Tamper -{ - class InstructionHelper - { - private const int CodeTypeIndex = 0; - - public static void Emit(IOperation operation, CompilationContext context) - { - context.CurrentOperations.Add(operation); - } - - public static void Emit(Type instruction, byte width, CompilationContext context, params Object[] operands) - { - Emit((IOperation)Create(instruction, width, operands), context); - } - - public static void EmitMov(byte width, CompilationContext context, IOperand destination, IOperand source) - { - Emit(typeof(OpMov<>), width, context, destination, source); - } - - public static ICondition CreateCondition(Comparison comparison, byte width, IOperand lhs, IOperand rhs) - { - ICondition Create(Type conditionType) - { - return (ICondition)InstructionHelper.Create(conditionType, width, lhs, rhs); - } - - switch (comparison) - { - case Comparison.Greater : return Create(typeof(CondGT<>)); - case Comparison.GreaterOrEqual: return Create(typeof(CondGE<>)); - case Comparison.Less : return Create(typeof(CondLT<>)); - case Comparison.LessOrEqual : return Create(typeof(CondLE<>)); - case Comparison.Equal : return Create(typeof(CondEQ<>)); - case Comparison.NotEqual : return Create(typeof(CondNE<>)); - default: - throw new TamperCompilationException($"Invalid comparison {comparison} in Atmosphere cheat"); - } - } - - public static Object Create(Type instruction, byte width, params Object[] operands) - { - Type realType; - - switch (width) - { - case 1: realType = instruction.MakeGenericType(typeof(byte)); break; - case 2: realType = instruction.MakeGenericType(typeof(ushort)); break; - case 4: realType = instruction.MakeGenericType(typeof(uint)); break; - case 8: realType = instruction.MakeGenericType(typeof(ulong)); break; - default: - throw new TamperCompilationException($"Invalid instruction width {width} in Atmosphere cheat"); - } - - return Activator.CreateInstance(realType, operands); - } - - public static ulong GetImmediate(byte[] instruction, int index, int nybbleCount) - { - ulong value = 0; - - for (int i = 0; i < nybbleCount; i++) - { - value <<= 4; - value |= instruction[index + i]; - } - - return value; - } - - public static CodeType GetCodeType(byte[] instruction) - { - int codeType = instruction[CodeTypeIndex]; - - if (codeType >= 0xC) - { - byte extension = instruction[CodeTypeIndex + 1]; - codeType = (codeType << 4) | extension; - - if (extension == 0xF) - { - extension = instruction[CodeTypeIndex + 2]; - codeType = (codeType << 4) | extension; - } - } - - return (CodeType)codeType; - } - - public static byte[] ParseRawInstruction(string rawInstruction) - { - const int wordSize = 2 * sizeof(uint); - - // Instructions are multi-word, with 32bit words. Split the raw instruction - // and parse each word into individual nybbles of bits. - - var words = rawInstruction.Split((char[])null, StringSplitOptions.RemoveEmptyEntries); - - byte[] instruction = new byte[wordSize * words.Length]; - - if (words.Length == 0) - { - throw new TamperCompilationException("Empty instruction in Atmosphere cheat"); - } - - for (int wordIndex = 0; wordIndex < words.Length; wordIndex++) - { - string word = words[wordIndex]; - - if (word.Length != wordSize) - { - throw new TamperCompilationException($"Invalid word length for {word} in Atmosphere cheat"); - } - - for (int nybbleIndex = 0; nybbleIndex < wordSize; nybbleIndex++) - { - int index = wordIndex * wordSize + nybbleIndex; - - instruction[index] = byte.Parse(word.AsSpan(nybbleIndex, 1), NumberStyles.HexNumber, CultureInfo.InvariantCulture); - } - } - - return instruction; - } - } -} diff --git a/Ryujinx.HLE/HOS/Tamper/MemoryHelper.cs b/Ryujinx.HLE/HOS/Tamper/MemoryHelper.cs deleted file mode 100644 index 1260ed9a..00000000 --- a/Ryujinx.HLE/HOS/Tamper/MemoryHelper.cs +++ /dev/null @@ -1,95 +0,0 @@ -using Ryujinx.HLE.Exceptions; -using Ryujinx.HLE.HOS.Tamper.Operations; - -namespace Ryujinx.HLE.HOS.Tamper -{ - class MemoryHelper - { - public static ulong GetAddressShift(MemoryRegion source, CompilationContext context) - { - switch (source) - { - case MemoryRegion.NSO: - // Memory address is relative to the code start. - return context.ExeAddress; - case MemoryRegion.Heap: - // Memory address is relative to the heap. - return context.HeapAddress; - case MemoryRegion.Alias: - // Memory address is relative to the alias region. - return context.AliasAddress; - case MemoryRegion.Asrl: - // Memory address is relative to the asrl region, which matches the code region. - return context.AslrAddress; - default: - throw new TamperCompilationException($"Invalid memory source {source} in Atmosphere cheat"); - } - } - - private static void EmitAdd(Value<ulong> finalValue, IOperand firstOperand, IOperand secondOperand, CompilationContext context) - { - context.CurrentOperations.Add(new OpAdd<ulong>(finalValue, firstOperand, secondOperand)); - } - - public static Pointer EmitPointer(ulong addressImmediate, CompilationContext context) - { - Value<ulong> addressImmediateValue = new Value<ulong>(addressImmediate); - - return new Pointer(addressImmediateValue, context.Process); - } - - public static Pointer EmitPointer(Register addressRegister, CompilationContext context) - { - return new Pointer(addressRegister, context.Process); - } - - public static Pointer EmitPointer(Register addressRegister, ulong offsetImmediate, CompilationContext context) - { - Value<ulong> offsetImmediateValue = new Value<ulong>(offsetImmediate); - Value<ulong> finalAddressValue = new Value<ulong>(0); - EmitAdd(finalAddressValue, addressRegister, offsetImmediateValue, context); - - return new Pointer(finalAddressValue, context.Process); - } - - public static Pointer EmitPointer(Register addressRegister, Register offsetRegister, CompilationContext context) - { - Value<ulong> finalAddressValue = new Value<ulong>(0); - EmitAdd(finalAddressValue, addressRegister, offsetRegister, context); - - return new Pointer(finalAddressValue, context.Process); - } - - public static Pointer EmitPointer(Register addressRegister, Register offsetRegister, ulong offsetImmediate, CompilationContext context) - { - Value<ulong> offsetImmediateValue = new Value<ulong>(offsetImmediate); - Value<ulong> finalOffsetValue = new Value<ulong>(0); - EmitAdd(finalOffsetValue, offsetRegister, offsetImmediateValue, context); - Value<ulong> finalAddressValue = new Value<ulong>(0); - EmitAdd(finalAddressValue, addressRegister, finalOffsetValue, context); - - return new Pointer(finalAddressValue, context.Process); - } - - public static Pointer EmitPointer(MemoryRegion memoryRegion, ulong offsetImmediate, CompilationContext context) - { - offsetImmediate += GetAddressShift(memoryRegion, context); - - return EmitPointer(offsetImmediate, context); - } - - public static Pointer EmitPointer(MemoryRegion memoryRegion, Register offsetRegister, CompilationContext context) - { - ulong offsetImmediate = GetAddressShift(memoryRegion, context); - - return EmitPointer(offsetRegister, offsetImmediate, context); - } - - public static Pointer EmitPointer(MemoryRegion memoryRegion, Register offsetRegister, ulong offsetImmediate, CompilationContext context) - { - offsetImmediate += GetAddressShift(memoryRegion, context); - - return EmitPointer(offsetRegister, offsetImmediate, context); - } - } -} diff --git a/Ryujinx.HLE/HOS/Tamper/MemoryRegion.cs b/Ryujinx.HLE/HOS/Tamper/MemoryRegion.cs deleted file mode 100644 index 766e3eed..00000000 --- a/Ryujinx.HLE/HOS/Tamper/MemoryRegion.cs +++ /dev/null @@ -1,29 +0,0 @@ -namespace Ryujinx.HLE.HOS.Tamper -{ - /// <summary> - /// The regions in the virtual address space of the process that are used as base address of memory operations. - /// </summary> - enum MemoryRegion - { - /// <summary> - /// The position of the NSO associated with the cheat in the virtual address space. - /// NOTE: A game can have several NSOs, but the cheat only associates itself with one. - /// </summary> - NSO = 0x0, - - /// <summary> - /// The address of the heap, as determined by the kernel. - /// </summary> - Heap = 0x1, - - /// <summary> - /// The address of the alias region, as determined by the kernel. - /// </summary> - Alias = 0x2, - - /// <summary> - /// The address of the code region with address space layout randomization included. - /// </summary> - Asrl = 0x3, - } -} diff --git a/Ryujinx.HLE/HOS/Tamper/OperationBlock.cs b/Ryujinx.HLE/HOS/Tamper/OperationBlock.cs deleted file mode 100644 index c16c2812..00000000 --- a/Ryujinx.HLE/HOS/Tamper/OperationBlock.cs +++ /dev/null @@ -1,17 +0,0 @@ -using Ryujinx.HLE.HOS.Tamper.Operations; -using System.Collections.Generic; - -namespace Ryujinx.HLE.HOS.Tamper -{ - readonly struct OperationBlock - { - public byte[] BaseInstruction { get; } - public List<IOperation> Operations { get; } - - public OperationBlock(byte[] baseInstruction) - { - BaseInstruction = baseInstruction; - Operations = new List<IOperation>(); - } - } -} diff --git a/Ryujinx.HLE/HOS/Tamper/Operations/Block.cs b/Ryujinx.HLE/HOS/Tamper/Operations/Block.cs deleted file mode 100644 index d81daa90..00000000 --- a/Ryujinx.HLE/HOS/Tamper/Operations/Block.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System.Collections.Generic; - -namespace Ryujinx.HLE.HOS.Tamper.Operations -{ - class Block : IOperation - { - private IEnumerable<IOperation> _operations; - - public Block(IEnumerable<IOperation> operations) - { - _operations = operations; - } - - public Block(params IOperation[] operations) - { - _operations = operations; - } - - public void Execute() - { - foreach (IOperation op in _operations) - { - op.Execute(); - } - } - } -} diff --git a/Ryujinx.HLE/HOS/Tamper/Operations/ForBlock.cs b/Ryujinx.HLE/HOS/Tamper/Operations/ForBlock.cs deleted file mode 100644 index ef95fa2b..00000000 --- a/Ryujinx.HLE/HOS/Tamper/Operations/ForBlock.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System.Collections.Generic; - -namespace Ryujinx.HLE.HOS.Tamper.Operations -{ - class ForBlock : IOperation - { - private ulong _count; - private Register _register; - private IEnumerable<IOperation> _operations; - - public ForBlock(ulong count, Register register, IEnumerable<IOperation> operations) - { - _count = count; - _register = register; - _operations = operations; - } - - public ForBlock(ulong count, Register register, params IOperation[] operations) - { - _count = count; - _register = register; - _operations = operations; - } - - public void Execute() - { - for (ulong i = 0; i < _count; i++) - { - // Set the register and execute the operations so that changing the - // register during runtime does not break iteration. - - _register.Set<ulong>(i); - - foreach (IOperation op in _operations) - { - op.Execute(); - } - } - } - } -} diff --git a/Ryujinx.HLE/HOS/Tamper/Operations/IOperand.cs b/Ryujinx.HLE/HOS/Tamper/Operations/IOperand.cs deleted file mode 100644 index 1aadda0b..00000000 --- a/Ryujinx.HLE/HOS/Tamper/Operations/IOperand.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Ryujinx.HLE.HOS.Tamper.Operations -{ - interface IOperand - { - public T Get<T>() where T : unmanaged; - public void Set<T>(T value) where T : unmanaged; - } -} diff --git a/Ryujinx.HLE/HOS/Tamper/Operations/IOperation.cs b/Ryujinx.HLE/HOS/Tamper/Operations/IOperation.cs deleted file mode 100644 index a4474979..00000000 --- a/Ryujinx.HLE/HOS/Tamper/Operations/IOperation.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Ryujinx.HLE.HOS.Tamper.Operations -{ - interface IOperation - { - void Execute(); - } -} diff --git a/Ryujinx.HLE/HOS/Tamper/Operations/IfBlock.cs b/Ryujinx.HLE/HOS/Tamper/Operations/IfBlock.cs deleted file mode 100644 index b7c5684e..00000000 --- a/Ryujinx.HLE/HOS/Tamper/Operations/IfBlock.cs +++ /dev/null @@ -1,34 +0,0 @@ -using Ryujinx.HLE.HOS.Tamper.Conditions; -using System.Collections.Generic; - -namespace Ryujinx.HLE.HOS.Tamper.Operations -{ - class IfBlock : IOperation - { - private ICondition _condition; - private IEnumerable<IOperation> _operationsThen; - private IEnumerable<IOperation> _operationsElse; - - public IfBlock(ICondition condition, IEnumerable<IOperation> operationsThen, IEnumerable<IOperation> operationsElse) - { - _condition = condition; - _operationsThen = operationsThen; - _operationsElse = operationsElse; - } - - public void Execute() - { - IEnumerable<IOperation> operations = _condition.Evaluate() ? _operationsThen : _operationsElse; - - if (operations == null) - { - return; - } - - foreach (IOperation op in operations) - { - op.Execute(); - } - } - } -} diff --git a/Ryujinx.HLE/HOS/Tamper/Operations/OpAdd.cs b/Ryujinx.HLE/HOS/Tamper/Operations/OpAdd.cs deleted file mode 100644 index 214518d7..00000000 --- a/Ryujinx.HLE/HOS/Tamper/Operations/OpAdd.cs +++ /dev/null @@ -1,21 +0,0 @@ -namespace Ryujinx.HLE.HOS.Tamper.Operations -{ - class OpAdd<T> : IOperation where T : unmanaged - { - IOperand _destination; - IOperand _lhs; - IOperand _rhs; - - public OpAdd(IOperand destination, IOperand lhs, IOperand rhs) - { - _destination = destination; - _lhs = lhs; - _rhs = rhs; - } - - public void Execute() - { - _destination.Set((T)((dynamic)_lhs.Get<T>() + (dynamic)_rhs.Get<T>())); - } - } -} diff --git a/Ryujinx.HLE/HOS/Tamper/Operations/OpAnd.cs b/Ryujinx.HLE/HOS/Tamper/Operations/OpAnd.cs deleted file mode 100644 index 366a82b0..00000000 --- a/Ryujinx.HLE/HOS/Tamper/Operations/OpAnd.cs +++ /dev/null @@ -1,21 +0,0 @@ -namespace Ryujinx.HLE.HOS.Tamper.Operations -{ - class OpAnd<T> : IOperation where T : unmanaged - { - IOperand _destination; - IOperand _lhs; - IOperand _rhs; - - public OpAnd(IOperand destination, IOperand lhs, IOperand rhs) - { - _destination = destination; - _lhs = lhs; - _rhs = rhs; - } - - public void Execute() - { - _destination.Set((T)((dynamic)_lhs.Get<T>() & (dynamic)_rhs.Get<T>())); - } - } -} diff --git a/Ryujinx.HLE/HOS/Tamper/Operations/OpLog.cs b/Ryujinx.HLE/HOS/Tamper/Operations/OpLog.cs deleted file mode 100644 index 49f8b41e..00000000 --- a/Ryujinx.HLE/HOS/Tamper/Operations/OpLog.cs +++ /dev/null @@ -1,21 +0,0 @@ -using Ryujinx.Common.Logging; - -namespace Ryujinx.HLE.HOS.Tamper.Operations -{ - class OpLog<T> : IOperation where T : unmanaged - { - int _logId; - IOperand _source; - - public OpLog(int logId, IOperand source) - { - _logId = logId; - _source = source; - } - - public void Execute() - { - Logger.Debug?.Print(LogClass.TamperMachine, $"Tamper debug log id={_logId} value={(dynamic)_source.Get<T>():X}"); - } - } -} diff --git a/Ryujinx.HLE/HOS/Tamper/Operations/OpLsh.cs b/Ryujinx.HLE/HOS/Tamper/Operations/OpLsh.cs deleted file mode 100644 index 34e7c81a..00000000 --- a/Ryujinx.HLE/HOS/Tamper/Operations/OpLsh.cs +++ /dev/null @@ -1,21 +0,0 @@ -namespace Ryujinx.HLE.HOS.Tamper.Operations -{ - class OpLsh<T> : IOperation where T : unmanaged - { - IOperand _destination; - IOperand _lhs; - IOperand _rhs; - - public OpLsh(IOperand destination, IOperand lhs, IOperand rhs) - { - _destination = destination; - _lhs = lhs; - _rhs = rhs; - } - - public void Execute() - { - _destination.Set((T)((dynamic)_lhs.Get<T>() << (dynamic)_rhs.Get<T>())); - } - } -} diff --git a/Ryujinx.HLE/HOS/Tamper/Operations/OpMov.cs b/Ryujinx.HLE/HOS/Tamper/Operations/OpMov.cs deleted file mode 100644 index 5fad38f9..00000000 --- a/Ryujinx.HLE/HOS/Tamper/Operations/OpMov.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace Ryujinx.HLE.HOS.Tamper.Operations -{ - class OpMov<T> : IOperation where T : unmanaged - { - IOperand _destination; - IOperand _source; - - public OpMov(IOperand destination, IOperand source) - { - _destination = destination; - _source = source; - } - - public void Execute() - { - _destination.Set(_source.Get<T>()); - } - } -} diff --git a/Ryujinx.HLE/HOS/Tamper/Operations/OpMul.cs b/Ryujinx.HLE/HOS/Tamper/Operations/OpMul.cs deleted file mode 100644 index 5aa0e34e..00000000 --- a/Ryujinx.HLE/HOS/Tamper/Operations/OpMul.cs +++ /dev/null @@ -1,21 +0,0 @@ -namespace Ryujinx.HLE.HOS.Tamper.Operations -{ - class OpMul<T> : IOperation where T : unmanaged - { - IOperand _destination; - IOperand _lhs; - IOperand _rhs; - - public OpMul(IOperand destination, IOperand lhs, IOperand rhs) - { - _destination = destination; - _lhs = lhs; - _rhs = rhs; - } - - public void Execute() - { - _destination.Set((T)((dynamic)_lhs.Get<T>() * (dynamic)_rhs.Get<T>())); - } - } -} diff --git a/Ryujinx.HLE/HOS/Tamper/Operations/OpNot.cs b/Ryujinx.HLE/HOS/Tamper/Operations/OpNot.cs deleted file mode 100644 index 8a97c3fe..00000000 --- a/Ryujinx.HLE/HOS/Tamper/Operations/OpNot.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace Ryujinx.HLE.HOS.Tamper.Operations -{ - class OpNot<T> : IOperation where T : unmanaged - { - IOperand _destination; - IOperand _source; - - public OpNot(IOperand destination, IOperand source) - { - _destination = destination; - _source = source; - } - - public void Execute() - { - _destination.Set((T)(~(dynamic)_source.Get<T>())); - } - } -} diff --git a/Ryujinx.HLE/HOS/Tamper/Operations/OpOr.cs b/Ryujinx.HLE/HOS/Tamper/Operations/OpOr.cs deleted file mode 100644 index d074de1c..00000000 --- a/Ryujinx.HLE/HOS/Tamper/Operations/OpOr.cs +++ /dev/null @@ -1,21 +0,0 @@ -namespace Ryujinx.HLE.HOS.Tamper.Operations -{ - class OpOr<T> : IOperation where T : unmanaged - { - IOperand _destination; - IOperand _lhs; - IOperand _rhs; - - public OpOr(IOperand destination, IOperand lhs, IOperand rhs) - { - _destination = destination; - _lhs = lhs; - _rhs = rhs; - } - - public void Execute() - { - _destination.Set((T)((dynamic)_lhs.Get<T>() | (dynamic)_rhs.Get<T>())); - } - } -} diff --git a/Ryujinx.HLE/HOS/Tamper/Operations/OpProcCtrl.cs b/Ryujinx.HLE/HOS/Tamper/Operations/OpProcCtrl.cs deleted file mode 100644 index 1b89f450..00000000 --- a/Ryujinx.HLE/HOS/Tamper/Operations/OpProcCtrl.cs +++ /dev/null @@ -1,26 +0,0 @@ -namespace Ryujinx.HLE.HOS.Tamper.Operations -{ - class OpProcCtrl : IOperation - { - private ITamperedProcess _process; - private bool _pause; - - public OpProcCtrl(ITamperedProcess process, bool pause) - { - _process = process; - _pause = pause; - } - - public void Execute() - { - if (_pause) - { - _process.PauseProcess(); - } - else - { - _process.ResumeProcess(); - } - } - } -} diff --git a/Ryujinx.HLE/HOS/Tamper/Operations/OpRsh.cs b/Ryujinx.HLE/HOS/Tamper/Operations/OpRsh.cs deleted file mode 100644 index b08dd957..00000000 --- a/Ryujinx.HLE/HOS/Tamper/Operations/OpRsh.cs +++ /dev/null @@ -1,21 +0,0 @@ -namespace Ryujinx.HLE.HOS.Tamper.Operations -{ - class OpRsh<T> : IOperation where T : unmanaged - { - IOperand _destination; - IOperand _lhs; - IOperand _rhs; - - public OpRsh(IOperand destination, IOperand lhs, IOperand rhs) - { - _destination = destination; - _lhs = lhs; - _rhs = rhs; - } - - public void Execute() - { - _destination.Set((T)((dynamic)_lhs.Get<T>() >> (dynamic)_rhs.Get<T>())); - } - } -} diff --git a/Ryujinx.HLE/HOS/Tamper/Operations/OpSub.cs b/Ryujinx.HLE/HOS/Tamper/Operations/OpSub.cs deleted file mode 100644 index b9c67d04..00000000 --- a/Ryujinx.HLE/HOS/Tamper/Operations/OpSub.cs +++ /dev/null @@ -1,21 +0,0 @@ -namespace Ryujinx.HLE.HOS.Tamper.Operations -{ - class OpSub<T> : IOperation where T : unmanaged - { - IOperand _destination; - IOperand _lhs; - IOperand _rhs; - - public OpSub(IOperand destination, IOperand lhs, IOperand rhs) - { - _destination = destination; - _lhs = lhs; - _rhs = rhs; - } - - public void Execute() - { - _destination.Set((T)((dynamic)_lhs.Get<T>() - (dynamic)_rhs.Get<T>())); - } - } -} diff --git a/Ryujinx.HLE/HOS/Tamper/Operations/OpXor.cs b/Ryujinx.HLE/HOS/Tamper/Operations/OpXor.cs deleted file mode 100644 index 3bbb76a1..00000000 --- a/Ryujinx.HLE/HOS/Tamper/Operations/OpXor.cs +++ /dev/null @@ -1,21 +0,0 @@ -namespace Ryujinx.HLE.HOS.Tamper.Operations -{ - class OpXor<T> : IOperation where T : unmanaged - { - IOperand _destination; - IOperand _lhs; - IOperand _rhs; - - public OpXor(IOperand destination, IOperand lhs, IOperand rhs) - { - _destination = destination; - _lhs = lhs; - _rhs = rhs; - } - - public void Execute() - { - _destination.Set((T)((dynamic)_lhs.Get<T>() ^ (dynamic)_rhs.Get<T>())); - } - } -} diff --git a/Ryujinx.HLE/HOS/Tamper/Parameter.cs b/Ryujinx.HLE/HOS/Tamper/Parameter.cs deleted file mode 100644 index 824c62fe..00000000 --- a/Ryujinx.HLE/HOS/Tamper/Parameter.cs +++ /dev/null @@ -1,12 +0,0 @@ -namespace Ryujinx.HLE.HOS.Tamper -{ - class Parameter<T> - { - public T Value { get; set; } - - public Parameter(T value) - { - Value = value; - } - } -} diff --git a/Ryujinx.HLE/HOS/Tamper/Pointer.cs b/Ryujinx.HLE/HOS/Tamper/Pointer.cs deleted file mode 100644 index 22acf4d5..00000000 --- a/Ryujinx.HLE/HOS/Tamper/Pointer.cs +++ /dev/null @@ -1,32 +0,0 @@ -using Ryujinx.Common.Logging; -using Ryujinx.HLE.HOS.Tamper.Operations; -using System.Runtime.CompilerServices; - -namespace Ryujinx.HLE.HOS.Tamper -{ - class Pointer : IOperand - { - private IOperand _position; - private ITamperedProcess _process; - - public Pointer(IOperand position, ITamperedProcess process) - { - _position = position; - _process = process; - } - - public T Get<T>() where T : unmanaged - { - return _process.ReadMemory<T>(_position.Get<ulong>()); - } - - public void Set<T>(T value) where T : unmanaged - { - ulong position = _position.Get<ulong>(); - - Logger.Debug?.Print(LogClass.TamperMachine, $"0x{position:X16}@{Unsafe.SizeOf<T>()}: {value:X}"); - - _process.WriteMemory(position, value); - } - } -} diff --git a/Ryujinx.HLE/HOS/Tamper/Register.cs b/Ryujinx.HLE/HOS/Tamper/Register.cs deleted file mode 100644 index 01af20de..00000000 --- a/Ryujinx.HLE/HOS/Tamper/Register.cs +++ /dev/null @@ -1,28 +0,0 @@ -using Ryujinx.Common.Logging; -using Ryujinx.HLE.HOS.Tamper.Operations; - -namespace Ryujinx.HLE.HOS.Tamper -{ - class Register : IOperand - { - private ulong _register = 0; - private string _alias; - - public Register(string alias) - { - _alias = alias; - } - - public T Get<T>() where T : unmanaged - { - return (T)(dynamic)_register; - } - - public void Set<T>(T value) where T : unmanaged - { - Logger.Debug?.Print(LogClass.TamperMachine, $"{_alias}: {value}"); - - _register = (ulong)(dynamic)value; - } - } -} diff --git a/Ryujinx.HLE/HOS/Tamper/TamperedKProcess.cs b/Ryujinx.HLE/HOS/Tamper/TamperedKProcess.cs deleted file mode 100644 index be51264a..00000000 --- a/Ryujinx.HLE/HOS/Tamper/TamperedKProcess.cs +++ /dev/null @@ -1,68 +0,0 @@ -using Ryujinx.Common.Logging; -using Ryujinx.HLE.Exceptions; -using Ryujinx.HLE.HOS.Kernel.Process; -using System.Runtime.CompilerServices; - -namespace Ryujinx.HLE.HOS.Tamper -{ - class TamperedKProcess : ITamperedProcess - { - private KProcess _process; - - public ProcessState State => _process.State; - - public bool TamperedCodeMemory { get; set; } = false; - - public TamperedKProcess(KProcess process) - { - _process = process; - } - - private void AssertMemoryRegion<T>(ulong va, bool isWrite) where T : unmanaged - { - ulong size = (ulong)Unsafe.SizeOf<T>(); - - // TODO (Caian): This double check is workaround because CpuMemory.IsRangeMapped reports - // some addresses as mapped even though they are not, i. e. 4 bytes from 0xffffffffffffff70. - if (!_process.CpuMemory.IsMapped(va) || !_process.CpuMemory.IsRangeMapped(va, size)) - { - throw new TamperExecutionException($"Unmapped memory access of {size} bytes at 0x{va:X16}"); - } - - if (!isWrite) - { - return; - } - - // TODO (Caian): The JIT does not support invalidating a code region so writing to code memory may not work - // as intended, so taint the operation to issue a warning later. - if (isWrite && (va >= _process.MemoryManager.CodeRegionStart) && (va + size <= _process.MemoryManager.CodeRegionEnd)) - { - TamperedCodeMemory = true; - } - } - - public T ReadMemory<T>(ulong va) where T : unmanaged - { - AssertMemoryRegion<T>(va, false); - - return _process.CpuMemory.Read<T>(va); - } - - public void WriteMemory<T>(ulong va, T value) where T : unmanaged - { - AssertMemoryRegion<T>(va, true); - _process.CpuMemory.Write(va, value); - } - - public void PauseProcess() - { - Logger.Warning?.Print(LogClass.TamperMachine, "Process pausing is not supported!"); - } - - public void ResumeProcess() - { - Logger.Warning?.Print(LogClass.TamperMachine, "Process resuming is not supported!"); - } - } -}
\ No newline at end of file diff --git a/Ryujinx.HLE/HOS/Tamper/Value.cs b/Ryujinx.HLE/HOS/Tamper/Value.cs deleted file mode 100644 index 865f8e04..00000000 --- a/Ryujinx.HLE/HOS/Tamper/Value.cs +++ /dev/null @@ -1,24 +0,0 @@ -using Ryujinx.HLE.HOS.Tamper.Operations; - -namespace Ryujinx.HLE.HOS.Tamper -{ - class Value<P> : IOperand where P : unmanaged - { - private P _value; - - public Value(P value) - { - _value = value; - } - - public T Get<T>() where T : unmanaged - { - return (T)(dynamic)_value; - } - - public void Set<T>(T value) where T : unmanaged - { - _value = (P)(dynamic)value; - } - } -} |
