I've written an endscene hook, got the basic idea from whitemagic (thanks apoc)
I'm having some problems with it though, first I have an issue calling the original endscene when my endscene tries to it crashes the game, and secondly I can only get my endscene ran if I step through my code in the debugger, if I just run it it doesn't even run the first time but crashes the game in another manner. Anyway code below, I guess I'm doing something stupid but I've been staring at it for a while now
Code:
public class Hook
{
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
private delegate IntPtr EndSceneDelegate(IntPtr instance);
private static readonly EndSceneDelegate DEL_Original = EndScene;
private static readonly EndSceneDelegate DEL_New = (EndSceneDelegate)Marshal.GetDelegateForFunctionPointer((IntPtr)Interaction.DMA.GeneralFunctions.GetEndscene(), typeof(EndSceneDelegate));
private static readonly uint PTR_Original = (uint)Marshal.GetFunctionPointerForDelegate(DEL_New);
private static readonly uint PTR_New = (uint)Marshal.GetFunctionPointerForDelegate(DEL_Original);
private static readonly byte[] OriginalBytes = Interaction.DMA.RAW.ReadBytes((uint)PTR_Original, 6);
private static readonly byte[] BTS_NewAddress = BitConverter.GetBytes(PTR_New);
private static object MEMLOCK = new object();
private static List<byte> ReplacedBytes = new List<byte>();
private static IntPtr EndScene(IntPtr instance)
{
lock (MEMLOCK)
{
Remove();
DEL_New.DynamicInvoke(instance);
Apply();
return instance;
}
}
public static void create()
{
ReplacedBytes.Add(0x68);
ReplacedBytes.AddRange(BTS_NewAddress);
ReplacedBytes.Add(0xC3);
Apply();
}
private static void Apply()
{
lock (MEMLOCK)
{
Interaction.DMA.RAW.WriteBytes(PTR_Original, ReplacedBytes.ToArray());
}
}
private static void Remove()
{
lock (MEMLOCK)
{
Interaction.DMA.RAW.WriteBytes(PTR_Original, OriginalBytes);
}
}
}