MemoryHelper.cs 4.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. using Ryujinx.HLE.Exceptions;
  2. using Ryujinx.HLE.HOS.Tamper.Operations;
  3. namespace Ryujinx.HLE.HOS.Tamper
  4. {
  5. class MemoryHelper
  6. {
  7. public static ulong GetAddressShift(MemoryRegion source, CompilationContext context)
  8. {
  9. switch (source)
  10. {
  11. case MemoryRegion.NSO:
  12. // Memory address is relative to the code start.
  13. return context.ExeAddress;
  14. case MemoryRegion.Heap:
  15. // Memory address is relative to the heap.
  16. return context.HeapAddress;
  17. case MemoryRegion.Alias:
  18. // Memory address is relative to the alias region.
  19. return context.AliasAddress;
  20. case MemoryRegion.Asrl:
  21. // Memory address is relative to the asrl region, which matches the code region.
  22. return context.AslrAddress;
  23. default:
  24. throw new TamperCompilationException($"Invalid memory source {source} in Atmosphere cheat");
  25. }
  26. }
  27. private static void EmitAdd(Value<ulong> finalValue, IOperand firstOperand, IOperand secondOperand, CompilationContext context)
  28. {
  29. context.CurrentOperations.Add(new OpAdd<ulong>(finalValue, firstOperand, secondOperand));
  30. }
  31. public static Pointer EmitPointer(ulong addressImmediate, CompilationContext context)
  32. {
  33. Value<ulong> addressImmediateValue = new Value<ulong>(addressImmediate);
  34. return new Pointer(addressImmediateValue, context.Process);
  35. }
  36. public static Pointer EmitPointer(Register addressRegister, CompilationContext context)
  37. {
  38. return new Pointer(addressRegister, context.Process);
  39. }
  40. public static Pointer EmitPointer(Register addressRegister, ulong offsetImmediate, CompilationContext context)
  41. {
  42. Value<ulong> offsetImmediateValue = new Value<ulong>(offsetImmediate);
  43. Value<ulong> finalAddressValue = new Value<ulong>(0);
  44. EmitAdd(finalAddressValue, addressRegister, offsetImmediateValue, context);
  45. return new Pointer(finalAddressValue, context.Process);
  46. }
  47. public static Pointer EmitPointer(Register addressRegister, Register offsetRegister, CompilationContext context)
  48. {
  49. Value<ulong> finalAddressValue = new Value<ulong>(0);
  50. EmitAdd(finalAddressValue, addressRegister, offsetRegister, context);
  51. return new Pointer(finalAddressValue, context.Process);
  52. }
  53. public static Pointer EmitPointer(Register addressRegister, Register offsetRegister, ulong offsetImmediate, CompilationContext context)
  54. {
  55. Value<ulong> offsetImmediateValue = new Value<ulong>(offsetImmediate);
  56. Value<ulong> finalOffsetValue = new Value<ulong>(0);
  57. EmitAdd(finalOffsetValue, offsetRegister, offsetImmediateValue, context);
  58. Value<ulong> finalAddressValue = new Value<ulong>(0);
  59. EmitAdd(finalAddressValue, addressRegister, finalOffsetValue, context);
  60. return new Pointer(finalAddressValue, context.Process);
  61. }
  62. public static Pointer EmitPointer(MemoryRegion memoryRegion, ulong offsetImmediate, CompilationContext context)
  63. {
  64. offsetImmediate += GetAddressShift(memoryRegion, context);
  65. return EmitPointer(offsetImmediate, context);
  66. }
  67. public static Pointer EmitPointer(MemoryRegion memoryRegion, Register offsetRegister, CompilationContext context)
  68. {
  69. ulong offsetImmediate = GetAddressShift(memoryRegion, context);
  70. return EmitPointer(offsetRegister, offsetImmediate, context);
  71. }
  72. public static Pointer EmitPointer(MemoryRegion memoryRegion, Register offsetRegister, ulong offsetImmediate, CompilationContext context)
  73. {
  74. offsetImmediate += GetAddressShift(memoryRegion, context);
  75. return EmitPointer(offsetRegister, offsetImmediate, context);
  76. }
  77. }
  78. }