TrampolineTests.cs 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. using System;
  2. using Microsoft.VisualStudio.TestTools.UnitTesting;
  3. using System.Runtime.InteropServices;
  4. using BepInEx.IL2CPP;
  5. using Iced.Intel;
  6. namespace BepInEx.Tests
  7. {
  8. [TestClass]
  9. public class TrampolineTests
  10. {
  11. [DataTestMethod]
  12. [DataRow(64)]
  13. [DataRow(32)]
  14. public void TrampolineTest(int bitness)
  15. {
  16. byte[] exampleCode = new byte[] {
  17. 0x48, 0x89, 0x5C, 0x24, 0x10, 0x48, 0x89, 0x74, 0x24, 0x18, 0x55, 0x57, 0x41, 0x56, 0x48, 0x8D,
  18. 0xAC, 0x24, 0x00, 0xFF, 0xFF, 0xFF, 0x48, 0x81, 0xEC, 0x00, 0x02, 0x00, 0x00, 0x48, 0x8B, 0x05,
  19. 0x18, 0x57, 0x0A, 0x00, 0x48, 0x33, 0xC4, 0x48, 0x89, 0x85, 0xF0, 0x00, 0x00, 0x00, 0x4C, 0x8B,
  20. 0x05, 0x2F, 0x24, 0x0A, 0x00, 0x48, 0x8D, 0x05, 0x78, 0x7C, 0x04, 0x00, 0x33, 0xFF
  21. };
  22. var exampleCodePointer = Marshal.AllocHGlobal(80);
  23. var trampolineCodePointer = Marshal.AllocHGlobal(80);
  24. Marshal.Copy(exampleCode, 0, exampleCodePointer, exampleCode.Length);
  25. void Disassemble(byte[] data, ulong ip)
  26. {
  27. var formatter = new NasmFormatter();
  28. var output = new StringOutput();
  29. var codeReader = new ByteArrayCodeReader(data);
  30. var decoder = Decoder.Create(bitness, codeReader);
  31. decoder.IP = ip;
  32. while (codeReader.CanReadByte)
  33. {
  34. decoder.Decode(out var instr);
  35. formatter.Format(instr, output);
  36. Console.WriteLine($"{instr.IP:X16} {output.ToStringAndReset()}");
  37. }
  38. Console.WriteLine();
  39. }
  40. Console.WriteLine("Original:");
  41. Console.WriteLine();
  42. Disassemble(exampleCode, (ulong)exampleCodePointer.ToInt64());
  43. int trampolineLength = TrampolineGenerator.Generate(exampleCodePointer, new IntPtr(0xBEEF), trampolineCodePointer, bitness);
  44. Console.WriteLine("Modified:");
  45. Console.WriteLine();
  46. Marshal.Copy(exampleCodePointer, exampleCode, 0, exampleCode.Length);
  47. Disassemble(exampleCode, (ulong)exampleCodePointer.ToInt64());
  48. Console.WriteLine();
  49. Console.WriteLine("Trampoline:");
  50. Console.WriteLine();
  51. byte[] trampolineArray = new byte[trampolineLength];
  52. Marshal.Copy(trampolineCodePointer, trampolineArray, 0, trampolineLength);
  53. Disassemble(trampolineArray, (ulong)trampolineCodePointer.ToInt64());
  54. Marshal.FreeHGlobal(exampleCodePointer);
  55. Marshal.FreeHGlobal(trampolineCodePointer);
  56. Assert.IsFalse(false);
  57. }
  58. }
  59. }