mirror of
https://github.com/BepInEx/BepInEx.git
synced 2026-10-20 01:46:13 +00:00
80 lines
2.5 KiB
C#
80 lines
2.5 KiB
C#
using System;
|
|
using System.Runtime.InteropServices;
|
|
using BepInEx.IL2CPP;
|
|
using Iced.Intel;
|
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
|
|
namespace BepInEx.Tests;
|
|
|
|
[TestClass]
|
|
public class TrampolineTests
|
|
{
|
|
[DataTestMethod]
|
|
[DataRow(64)]
|
|
[DataRow(32)]
|
|
public void TrampolineTest(int bitness)
|
|
{
|
|
byte[] exampleCode =
|
|
{
|
|
0x48, 0x89, 0x5C, 0x24, 0x10, 0x48, 0x89, 0x74, 0x24, 0x18, 0x55, 0x57, 0x41, 0x56, 0x48, 0x8D,
|
|
0xAC, 0x24, 0x00, 0xFF, 0xFF, 0xFF, 0x48, 0x81, 0xEC, 0x00, 0x02, 0x00, 0x00, 0x48, 0x8B, 0x05,
|
|
0x18, 0x57, 0x0A, 0x00, 0x48, 0x33, 0xC4, 0x48, 0x89, 0x85, 0xF0, 0x00, 0x00, 0x00, 0x4C, 0x8B,
|
|
0x05, 0x2F, 0x24, 0x0A, 0x00, 0x48, 0x8D, 0x05, 0x78, 0x7C, 0x04, 0x00, 0x33, 0xFF
|
|
};
|
|
|
|
var exampleCodePointer = Marshal.AllocHGlobal(80);
|
|
var trampolineCodePointer = Marshal.AllocHGlobal(80);
|
|
Marshal.Copy(exampleCode, 0, exampleCodePointer, exampleCode.Length);
|
|
|
|
|
|
void Disassemble(byte[] data, ulong ip)
|
|
{
|
|
var formatter = new NasmFormatter();
|
|
var output = new StringOutput();
|
|
var codeReader = new ByteArrayCodeReader(data);
|
|
var decoder = Decoder.Create(bitness, codeReader);
|
|
decoder.IP = ip;
|
|
while (codeReader.CanReadByte)
|
|
{
|
|
decoder.Decode(out var instr);
|
|
formatter.Format(instr, output);
|
|
Console.WriteLine($"{instr.IP:X16} {output.ToStringAndReset()}");
|
|
}
|
|
|
|
Console.WriteLine();
|
|
}
|
|
|
|
|
|
Console.WriteLine("Original:");
|
|
Console.WriteLine();
|
|
|
|
|
|
Disassemble(exampleCode, (ulong) exampleCodePointer.ToInt64());
|
|
|
|
DetourGenerator.CreateTrampolineFromFunction(exampleCodePointer, out var trampolineLength, out _);
|
|
|
|
Console.WriteLine("Modified:");
|
|
Console.WriteLine();
|
|
|
|
|
|
Marshal.Copy(exampleCodePointer, exampleCode, 0, exampleCode.Length);
|
|
Disassemble(exampleCode, (ulong) exampleCodePointer.ToInt64());
|
|
|
|
|
|
Console.WriteLine();
|
|
Console.WriteLine("Trampoline:");
|
|
Console.WriteLine();
|
|
|
|
var trampolineArray = new byte[trampolineLength];
|
|
Marshal.Copy(trampolineCodePointer, trampolineArray, 0, trampolineLength);
|
|
|
|
Disassemble(trampolineArray, (ulong) trampolineCodePointer.ToInt64());
|
|
|
|
|
|
Marshal.FreeHGlobal(exampleCodePointer);
|
|
Marshal.FreeHGlobal(trampolineCodePointer);
|
|
|
|
Assert.IsFalse(false);
|
|
}
|
|
}
|