mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-12 10:17:22 +01:00
Hooking via VTable
This commit is contained in:
parent
f3bdea3c43
commit
17c18300b2
2 changed files with 95 additions and 7 deletions
89
Dalamud/Game/Internal/DXGI/DXHookD3D11.cs
Normal file
89
Dalamud/Game/Internal/DXGI/DXHookD3D11.cs
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
using SharpDX.Direct3D;
|
||||
using SharpDX.Direct3D11;
|
||||
using SharpDX.DXGI;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Dalamud.Game.Internal.DXGI
|
||||
{
|
||||
public class DXHookD3D11
|
||||
{
|
||||
const int DXGI_SWAPCHAIN_METHOD_COUNT = 18;
|
||||
const int D3D11_DEVICE_METHOD_COUNT = 43;
|
||||
|
||||
public static SharpDX.DXGI.SwapChainDescription CreateSwapChainDescription(IntPtr renderForm)
|
||||
{
|
||||
return new SharpDX.DXGI.SwapChainDescription
|
||||
{
|
||||
BufferCount = 1,
|
||||
Flags = SharpDX.DXGI.SwapChainFlags.None,
|
||||
IsWindowed = true,
|
||||
ModeDescription = new SharpDX.DXGI.ModeDescription(100, 100, new Rational(60, 1), SharpDX.DXGI.Format.R8G8B8A8_UNorm),
|
||||
OutputHandle = renderForm,
|
||||
SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0),
|
||||
SwapEffect = SharpDX.DXGI.SwapEffect.Discard,
|
||||
Usage = SharpDX.DXGI.Usage.RenderTargetOutput
|
||||
};
|
||||
}
|
||||
|
||||
protected IntPtr[] GetVTblAddresses(IntPtr pointer, int numberOfMethods)
|
||||
{
|
||||
return GetVTblAddresses(pointer, 0, numberOfMethods);
|
||||
}
|
||||
|
||||
protected IntPtr[] GetVTblAddresses(IntPtr pointer, int startIndex, int numberOfMethods)
|
||||
{
|
||||
List<IntPtr> vtblAddresses = new List<IntPtr>();
|
||||
IntPtr vTable = Marshal.ReadIntPtr(pointer);
|
||||
for (int i = startIndex; i < startIndex + numberOfMethods; i++)
|
||||
vtblAddresses.Add(Marshal.ReadIntPtr(vTable, i * IntPtr.Size)); // using IntPtr.Size allows us to support both 32 and 64-bit processes
|
||||
|
||||
return vtblAddresses.ToArray();
|
||||
}
|
||||
|
||||
List<IntPtr> _d3d11VTblAddresses = null;
|
||||
List<IntPtr> _dxgiSwapChainVTblAddresses = null;
|
||||
|
||||
#region Internal device resources
|
||||
SharpDX.Direct3D11.Device _device;
|
||||
SharpDX.DXGI.SwapChain _swapChain;
|
||||
SharpDX.Windows.RenderForm _renderForm;
|
||||
#endregion
|
||||
|
||||
#region Main device resources
|
||||
public SharpDX.Windows.RenderForm RenderForm { get => _renderForm; set => _renderForm = value; }
|
||||
#endregion
|
||||
|
||||
public IntPtr Hook()
|
||||
{
|
||||
|
||||
if (_d3d11VTblAddresses == null)
|
||||
{
|
||||
_d3d11VTblAddresses = new List<IntPtr>();
|
||||
_dxgiSwapChainVTblAddresses = new List<IntPtr>();
|
||||
|
||||
#region Get Device and SwapChain method addresses
|
||||
// Create temporary device + swapchain and determine method addresses
|
||||
RenderForm = new SharpDX.Windows.RenderForm();
|
||||
SharpDX.Direct3D11.Device.CreateWithSwapChain(
|
||||
DriverType.Hardware,
|
||||
DeviceCreationFlags.BgraSupport,
|
||||
CreateSwapChainDescription(RenderForm.Handle),
|
||||
out _device,
|
||||
out _swapChain
|
||||
);
|
||||
if (_device != null && _swapChain != null)
|
||||
{
|
||||
_d3d11VTblAddresses.AddRange(GetVTblAddresses(_device.NativePointer, D3D11_DEVICE_METHOD_COUNT));
|
||||
_dxgiSwapChainVTblAddresses.AddRange(GetVTblAddresses(_swapChain.NativePointer, DXGI_SWAPCHAIN_METHOD_COUNT));
|
||||
}
|
||||
_device.Dispose();
|
||||
_swapChain.Dispose();
|
||||
#endregion
|
||||
}
|
||||
|
||||
return _dxgiSwapChainVTblAddresses[8];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -27,7 +27,7 @@ namespace Dalamud.Interface
|
|||
|
||||
private readonly Hook<PresentDelegate> presentHook;
|
||||
|
||||
private SwapChainAddressResolver Address { get; }
|
||||
private DXHookD3D11 dXHookD3D11 = new DXHookD3D11();
|
||||
|
||||
private RawDX11Scene scene;
|
||||
|
||||
|
|
@ -38,16 +38,15 @@ namespace Dalamud.Interface
|
|||
|
||||
public InterfaceManager(SigScanner scanner)
|
||||
{
|
||||
Address = new SwapChainAddressResolver();
|
||||
Address.Setup(scanner);
|
||||
|
||||
IntPtr addr = dXHookD3D11.Hook();
|
||||
Log.Verbose("===== S W A P C H A I N =====");
|
||||
Log.Verbose("Present address {Present}", Address.Present);
|
||||
Log.Verbose("Present address {Present}", addr);
|
||||
|
||||
this.presentHook =
|
||||
new Hook<PresentDelegate>(Address.Present,
|
||||
new PresentDelegate(PresentDetour),
|
||||
this);
|
||||
new Hook<PresentDelegate>(addr,
|
||||
new PresentDelegate(PresentDetour),
|
||||
this);
|
||||
}
|
||||
|
||||
public void Enable()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue