TamperedKProcess.cs 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. using Ryujinx.Common.Logging;
  2. using Ryujinx.HLE.Exceptions;
  3. using Ryujinx.HLE.HOS.Kernel.Process;
  4. using System.Runtime.CompilerServices;
  5. namespace Ryujinx.HLE.HOS.Tamper
  6. {
  7. class TamperedKProcess : ITamperedProcess
  8. {
  9. private KProcess _process;
  10. public ProcessState State => _process.State;
  11. public TamperedKProcess(KProcess process)
  12. {
  13. this._process = process;
  14. }
  15. private void AssertMemoryRegion<T>(ulong va, bool isWrite) where T : unmanaged
  16. {
  17. ulong size = (ulong)Unsafe.SizeOf<T>();
  18. // TODO (Caian): This double check is workaround because CpuMemory.IsRangeMapped reports
  19. // some addresses as mapped even though they are not, i. e. 4 bytes from 0xffffffffffffff70.
  20. if (!_process.CpuMemory.IsMapped(va) || !_process.CpuMemory.IsRangeMapped(va, size))
  21. {
  22. throw new TamperExecutionException($"Unmapped memory access of {size} bytes at 0x{va:X16}");
  23. }
  24. if (!isWrite)
  25. {
  26. return;
  27. }
  28. // TODO (Caian): It is unknown how PPTC behaves if the tamper modifies memory regions
  29. // belonging to code. So for now just prevent code tampering.
  30. if ((va >= _process.MemoryManager.CodeRegionStart) && (va + size <= _process.MemoryManager.CodeRegionEnd))
  31. {
  32. throw new CodeRegionTamperedException($"Writing {size} bytes to address 0x{va:X16} alters code");
  33. }
  34. }
  35. public T ReadMemory<T>(ulong va) where T : unmanaged
  36. {
  37. AssertMemoryRegion<T>(va, false);
  38. return _process.CpuMemory.Read<T>(va);
  39. }
  40. public void WriteMemory<T>(ulong va, T value) where T : unmanaged
  41. {
  42. AssertMemoryRegion<T>(va, true);
  43. _process.CpuMemory.Write(va, value);
  44. }
  45. public void PauseProcess()
  46. {
  47. Logger.Warning?.Print(LogClass.TamperMachine, "Process pausing is not supported!");
  48. }
  49. public void ResumeProcess()
  50. {
  51. Logger.Warning?.Print(LogClass.TamperMachine, "Process resuming is not supported!");
  52. }
  53. }
  54. }