Advertisement
bestplay9384

d3d11hook + 2d

Jun 27th, 2017
800
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 17.73 KB | None | 0 0
  1.     internal class D3DHook
  2.     {
  3.         [StructLayout(LayoutKind.Sequential)]
  4.         internal struct VertexPositionTexture
  5.         {
  6.             public Vector4 Position;
  7.             public Vector2 TexCoord;
  8.  
  9.             public static readonly SharpDX.Direct3D11.InputElement[] inputElements = new[] {
  10.             new SharpDX.Direct3D11.InputElement("POSITION", 0, Format.R32G32B32A32_Float, 0, 0),
  11.             new SharpDX.Direct3D11.InputElement("TEXCOORD",0,Format.R32G32_Float, 16 ,0)
  12.         };
  13.             public static readonly int SizeInBytes = Marshal.SizeOf(typeof(VertexPositionTexture));
  14.             public VertexPositionTexture(Vector4 position, Vector2 texCoord)
  15.             {
  16.                 Position = position;
  17.                 TexCoord = texCoord;
  18.             }
  19.             public VertexPositionTexture(Vector3 position, Vector2 texCoord)
  20.             {
  21.                 Position = new Vector4(position, 1);
  22.                 TexCoord = texCoord;
  23.             }
  24.         }
  25.  
  26.         private enum D3D11DeviceVTbl : short
  27.         {
  28.             // IUnknown
  29.             QueryInterface = 0,
  30.             AddRef = 1,
  31.             Release = 2,
  32.  
  33.             // ID3D11Device
  34.             CreateBuffer = 3,
  35.             CreateTexture1D = 4,
  36.             CreateTexture2D = 5,
  37.             CreateTexture3D = 6,
  38.             CreateShaderResourceView = 7,
  39.             CreateUnorderedAccessView = 8,
  40.             CreateRenderTargetView = 9,
  41.             CreateDepthStencilView = 10,
  42.             CreateInputLayout = 11,
  43.             CreateVertexShader = 12,
  44.             CreateGeometryShader = 13,
  45.             CreateGeometryShaderWithStreamOutput = 14,
  46.             CreatePixelShader = 15,
  47.             CreateHullShader = 16,
  48.             CreateDomainShader = 17,
  49.             CreateComputeShader = 18,
  50.             CreateClassLinkage = 19,
  51.             CreateBlendState = 20,
  52.             CreateDepthStencilState = 21,
  53.             CreateRasterizerState = 22,
  54.             CreateSamplerState = 23,
  55.             CreateQuery = 24,
  56.             CreatePredicate = 25,
  57.             CreateCounter = 26,
  58.             CreateDeferredContext = 27,
  59.             OpenSharedResource = 28,
  60.             CheckFormatSupport = 29,
  61.             CheckMultisampleQualityLevels = 30,
  62.             CheckCounterInfo = 31,
  63.             CheckCounter = 32,
  64.             CheckFeatureSupport = 33,
  65.             GetPrivateData = 34,
  66.             SetPrivateData = 35,
  67.             SetPrivateDataInterface = 36,
  68.             GetFeatureLevel = 37,
  69.             GetCreationFlags = 38,
  70.             GetDeviceRemovedReason = 39,
  71.             GetImmediateContext = 40,
  72.             SetExceptionMode = 41,
  73.             GetExceptionMode = 42,
  74.         }
  75.  
  76.         private const int D3D11_DEVICE_METHOD_COUNT = 43;
  77.  
  78.         private enum DXGISwapChainVTbl : short
  79.         {
  80.             // IUnknown
  81.             QueryInterface = 0,
  82.             AddRef = 1,
  83.             Release = 2,
  84.  
  85.             // IDXGIObject
  86.             SetPrivateData = 3,
  87.             SetPrivateDataInterface = 4,
  88.             GetPrivateData = 5,
  89.             GetParent = 6,
  90.  
  91.             // IDXGIDeviceSubObject
  92.             GetDevice = 7,
  93.  
  94.             // IDXGISwapChain
  95.             Present = 8,
  96.             GetBuffer = 9,
  97.             SetFullscreenState = 10,
  98.             GetFullscreenState = 11,
  99.             GetDesc = 12,
  100.             ResizeBuffers = 13,
  101.             ResizeTarget = 14,
  102.             GetContainingOutput = 15,
  103.             GetFrameStatistics = 16,
  104.             GetLastPresentCount = 17,
  105.         }
  106.  
  107.         string SpriteFX = @"Texture2D SpriteTex;
  108. SamplerState samLinear {
  109.    Filter = MIN_MAG_MIP_LINEAR;
  110.    AddressU = WRAP;
  111.    AddressV = WRAP;
  112. };
  113. struct VertexIn {
  114.    float3 PosNdc : POSITION;
  115.    float2 Tex    : TEXCOORD;
  116.    float4 Color  : COLOR;
  117. };
  118. struct VertexOut {
  119.    float4 PosNdc : SV_POSITION;
  120.    float2 Tex    : TEXCOORD;
  121.    float4 Color  : COLOR;
  122. };
  123. VertexOut VS(VertexIn vin) {
  124.    VertexOut vout;
  125.    vout.PosNdc = float4(vin.PosNdc, 1.0f);
  126.    vout.Tex    = vin.Tex;
  127.    vout.Color  = vin.Color;
  128.    return vout;
  129. };
  130. float4 PS(VertexOut pin) : SV_Target {
  131.    return pin.Color*SpriteTex.Sample(samLinear, pin.Tex);
  132. };
  133. technique11 SpriteTech {
  134.    pass P0 {
  135.        SetVertexShader( CompileShader( vs_5_0, VS() ) );
  136.        SetHullShader( NULL );
  137.        SetDomainShader( NULL );
  138.        SetGeometryShader( NULL );
  139.        SetPixelShader( CompileShader( ps_5_0, PS() ) );
  140.    }
  141. };";
  142.  
  143.         [StructLayout(LayoutKind.Sequential)]
  144.         internal struct SpriteVertex
  145.         {
  146.             public Vector3 Pos;
  147.             public Vector2 Tex;
  148.             public Color4 Color;
  149.         }
  150.  
  151.  
  152.         private const int DXGI_SWAPCHAIN_METHOD_COUNT = 18;
  153.  
  154.         [UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true)]
  155.         private delegate int DXGISwapChain_PresentDelegate(IntPtr swapChainPtr, int syncInterval, /* int */ SharpDX.DXGI.PresentFlags flags);
  156.  
  157.         [UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true)]
  158.         delegate int DXGISwapChain_ResizeTargetDelegate(IntPtr swapChainPtr, ref ModeDescription newTargetParameters);
  159.  
  160.         private List<IntPtr> _d3d11VTblAddresses = null;
  161.         private List<IntPtr> _dxgiSwapChainVTblAddresses = null;
  162.  
  163.         private Hook<DXGISwapChain_PresentDelegate> DXGISwapChain_PresentHook = null;
  164.         private Hook<DXGISwapChain_ResizeTargetDelegate> DXGISwapChain_ResizeTargetHook = null;
  165.  
  166.         SharpDX.Direct3D11.Device _device;
  167.         SharpDX.DXGI.SwapChain _swapChain;
  168.  
  169.         IntPtr _swapChainPointer = IntPtr.Zero;
  170.  
  171.         public const string fontFamily = "Calibri";
  172.         public const float fontSize = 12.0f;
  173.         public static SharpDX.DirectWrite.Factory fontFactory = new SharpDX.DirectWrite.Factory();
  174.         public static SharpDX.DirectWrite.TextFormat font = new SharpDX.DirectWrite.TextFormat(fontFactory, fontFamily, fontSize);
  175.  
  176.         public SharpDX.Direct2D1.DeviceContext d2dContext;
  177.         public Bitmap1 d2dTarget;
  178.  
  179.         KeyedMutex device10Mutex;
  180.         KeyedMutex device11Mutex;
  181.         RenderTarget renderTarget2D;
  182.         RenderTargetView renderTargetView;
  183.         Texture2D textureD3D11;
  184.         SharpDX.Direct3D11.Effect effect;
  185.         InputLayout layoutOverlay;
  186.         SharpDX.Direct3D11.Buffer vertexBufferOverlay;
  187.         Surface _surface;
  188.  
  189.         private static SharpDX.DXGI.SwapChainDescription CreateSwapChainDescription(IntPtr windowHandle)
  190.         {
  191.             return new SharpDX.DXGI.SwapChainDescription
  192.             {
  193.                 BufferCount = 1,
  194.                 Flags = SharpDX.DXGI.SwapChainFlags.None,
  195.                 IsWindowed = true,
  196.                 ModeDescription = new SharpDX.DXGI.ModeDescription(100, 100, new Rational(60, 1), SharpDX.DXGI.Format.R8G8B8A8_UNorm),
  197.                 OutputHandle = windowHandle,
  198.                 SampleDescription = new SharpDX.DXGI.SampleDescription(1, 0),
  199.                 SwapEffect = SharpDX.DXGI.SwapEffect.Discard,
  200.                 Usage = SharpDX.DXGI.Usage.RenderTargetOutput
  201.             };
  202.         }
  203.  
  204.         private static IntPtr[] GetVTblAddresses(IntPtr pointer, int numberOfMethods)
  205.         {
  206.             List<IntPtr> vtblAddresses = new List<IntPtr>();
  207.  
  208.             IntPtr vTable = Marshal.ReadIntPtr(pointer);
  209.             for (int i = 0; i < numberOfMethods; i++)
  210.                 vtblAddresses.Add(Marshal.ReadIntPtr(vTable, i * IntPtr.Size));
  211.  
  212.             return vtblAddresses.ToArray();
  213.         }
  214.  
  215.         public void Hook()
  216.         {
  217.  
  218.             try
  219.             {
  220.  
  221.             Console.WriteLine("Hooking D3D...");
  222.             if (this._d3d11VTblAddresses == null)
  223.             {
  224.                 this._d3d11VTblAddresses = new List<IntPtr>();
  225.                 this._dxgiSwapChainVTblAddresses = new List<IntPtr>();
  226.  
  227.                 SharpDX.Windows.RenderForm _renderForm = new SharpDX.Windows.RenderForm();
  228.  
  229.                 SharpDX.Direct3D11.Device.CreateWithSwapChain(
  230.                         DriverType.Hardware,
  231.                         DeviceCreationFlags.BgraSupport | DeviceCreationFlags.Debug,
  232.                         CreateSwapChainDescription(_renderForm.Handle),
  233.                         out this._device,
  234.                         out this._swapChain);
  235.  
  236.  
  237.                 if (_device != null && _swapChain != null)
  238.                 {
  239.                     Console.WriteLine("Hook: Device created.");
  240.                     this._d3d11VTblAddresses.AddRange(GetVTblAddresses(this._device.NativePointer, D3D11_DEVICE_METHOD_COUNT));
  241.                     this._dxgiSwapChainVTblAddresses.AddRange(GetVTblAddresses(this._swapChain.NativePointer, DXGI_SWAPCHAIN_METHOD_COUNT));
  242.  
  243.  
  244.                         var factory1 = new SharpDX.DXGI.Factory1();
  245.                         // The 1st graphics adapter
  246.                         var adapter1 = factory1.GetAdapter1(0);
  247.  
  248.                         var resource = SharpDX.Direct3D11.Resource.FromSwapChain<Texture2D>(_swapChain, 0);
  249.                         renderTargetView = new RenderTargetView(_device, resource);  
  250.  
  251.                         var context = _device.ImmediateContext;
  252.                         RawViewportF[] viewportf = { new ViewportF(0, 0, resource.Description.Width, resource.Description.Height, 0, 1) };
  253.                    
  254.                         context.OutputMerger.SetTargets(renderTargetView);
  255.                         context.Rasterizer.SetViewports(viewportf);
  256.  
  257.                         textureD3D11 = new Texture2D(_device, new Texture2DDescription
  258.                         {
  259.                             Width = _renderForm.ClientSize.Width,
  260.                             Height = _renderForm.ClientSize.Height,
  261.                             MipLevels = 1,
  262.                             ArraySize = 1,
  263.                             Format = Format.B8G8R8A8_UNorm,
  264.                             SampleDescription = new SampleDescription(1, 0),
  265.                             Usage = ResourceUsage.Default,
  266.                             BindFlags = BindFlags.RenderTarget | BindFlags.ShaderResource,
  267.                             CpuAccessFlags = CpuAccessFlags.None,
  268.                             OptionFlags = ResourceOptionFlags.SharedKeyedmutex
  269.                         });
  270.                         var device10 = new Device10(adapter1, SharpDX.Direct3D10.DeviceCreationFlags.BgraSupport, SharpDX.Direct3D10.FeatureLevel.Level_10_0);
  271.                         var factory2D = new SharpDX.Direct2D1.Factory(SharpDX.Direct2D1.FactoryType.SingleThreaded, DebugLevel.Information);
  272.  
  273.                         // Here we bind the texture we've created on our direct3d11 device through the direct3d10
  274.                         // to the direct 2d render target....
  275.                         var sharedResource = textureD3D11.QueryInterface<SharpDX.DXGI.Resource>();
  276.                         var textureD3D10 = device10.OpenSharedResource<SharpDX.Direct3D10.Texture2D>(sharedResource.SharedHandle);
  277.  
  278.                         _surface = textureD3D10.AsSurface();
  279.                         var rtp = new RenderTargetProperties
  280.                         {
  281.                             MinLevel = SharpDX.Direct2D1.FeatureLevel.Level_10,
  282.                             Type = RenderTargetType.Hardware,
  283.                             PixelFormat = new PixelFormat(Format.Unknown, SharpDX.Direct2D1.AlphaMode.Premultiplied)
  284.                         };
  285.  
  286.                         renderTarget2D = new RenderTarget(factory2D, _surface, rtp);
  287.                         var solidColorBrush = new SolidColorBrush(renderTarget2D, Color.Red);
  288.  
  289.                         device10Mutex = textureD3D10.QueryInterface<KeyedMutex>();
  290.                         device11Mutex = textureD3D11.QueryInterface<KeyedMutex>();
  291.  
  292.                         ShaderBytecode shaderByteCode = ShaderBytecode.Compile(
  293.                             SpriteFX,
  294.                             "fx_5_0",
  295.                             ShaderFlags.EnableStrictness);
  296.  
  297.                         effect = new SharpDX.Direct3D11.Effect(_device, shaderByteCode);
  298.  
  299.                         var verticesText = new DataStream(VertexPositionTexture.SizeInBytes * 4, true, true);
  300.                         verticesText.Write(new VertexPositionTexture(new Vector3(-1, 1, 0), new Vector2(0, 0f)));
  301.                         verticesText.Write(new VertexPositionTexture(new Vector3(1, 1, 0), new Vector2(1, 0)));
  302.                         verticesText.Write(new VertexPositionTexture(new Vector3(-1, -1, 0), new Vector2(0, 1)));
  303.                         verticesText.Write(new VertexPositionTexture(new Vector3(1, -1, 0), new Vector2(1, 1)));
  304.  
  305.                         verticesText.Position = 0;
  306.  
  307.                         // create the overlay vertex layout and buffer
  308.                         SharpDX.Direct3D11.InputElement[] layoutDesc = {
  309.                             new SharpDX.Direct3D11.InputElement("POSITION", 0, SharpDX.DXGI.Format.R32G32B32_Float, 0, 0, InputClassification.PerVertexData, 0),
  310.                             new SharpDX.Direct3D11.InputElement("TEXCOORD", 0, SharpDX.DXGI.Format.R32G32_Float, 12, 0, InputClassification.PerVertexData, 0),
  311.                             new SharpDX.Direct3D11.InputElement("COLOR", 0, SharpDX.DXGI.Format.R32G32B32A32_Float, 20, 0, InputClassification.PerVertexData, 0)
  312.                         };
  313.                         layoutOverlay = new SharpDX.Direct3D11.InputLayout(_device, effect.GetTechniqueByName("SpriteTech").GetPassByIndex(0).Description.Signature, layoutDesc);
  314.                         //layoutOverlay = new InputLayout(_device, effect.GetTechniqueByName("SpriteTech").GetPassByIndex(0).Description.Signature, VertexPositionTexture.inputElements);
  315.                         vertexBufferOverlay = new SharpDX.Direct3D11.Buffer(_device, verticesText, (int)verticesText.Length, ResourceUsage.Default, BindFlags.VertexBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0);
  316.                         verticesText.Close();
  317.  
  318.                     }
  319.                 else
  320.                 {
  321.                     Console.WriteLine("Hook: Device creation failed.");  
  322.                 }
  323.  
  324.             }
  325.  
  326.             }
  327.             catch (Exception e)
  328.             {
  329.                 Console.WriteLine(e.Message);
  330.                 Console.WriteLine(e.StackTrace);
  331.             }
  332.  
  333.             this.DXGISwapChain_PresentHook = new Hook<DXGISwapChain_PresentDelegate>(
  334.                 this._dxgiSwapChainVTblAddresses[(int)DXGISwapChainVTbl.Present],
  335.                 new DXGISwapChain_PresentDelegate(this.PresentHook),
  336.             this);
  337.  
  338.             this.DXGISwapChain_PresentHook.Enable();
  339.  
  340.             this.DXGISwapChain_ResizeTargetHook = new Hook<DXGISwapChain_ResizeTargetDelegate>(
  341.                 _dxgiSwapChainVTblAddresses[(int)DXGISwapChainVTbl.ResizeTarget],
  342.                 new DXGISwapChain_ResizeTargetDelegate(ResizeTargetHook),
  343.                 this);
  344.  
  345.             this.DXGISwapChain_ResizeTargetHook.Enable();
  346.  
  347.             Console.WriteLine("Hook: Hook is in place.");
  348.         }
  349.  
  350.         public void UnHook()
  351.         {
  352.             this.DXGISwapChain_PresentHook.Disable();
  353.             this.DXGISwapChain_ResizeTargetHook.Disable();
  354.         }
  355.  
  356.         /** HOOKED METHODS **/
  357.         public int ResizeTargetHook(IntPtr swapChainPtr, ref ModeDescription newTargetParameters)
  358.         {
  359.             Console.WriteLine("ResizeTargetHook");
  360.             SharpDX.DXGI.SwapChain swapChain = (SharpDX.DXGI.SwapChain)swapChainPtr;
  361.        
  362.             swapChain.ResizeTarget(ref newTargetParameters);
  363.             return this.DXGISwapChain_ResizeTargetHook.Original(swapChainPtr, ref newTargetParameters);
  364.         }
  365.  
  366.         public int PresentHook(IntPtr swapChainPtr, int syncInterval, SharpDX.DXGI.PresentFlags flags)
  367.         {
  368.             Console.WriteLine("PresentHook");
  369.             SharpDX.DXGI.SwapChain swapChain = (SharpDX.DXGI.SwapChain)swapChainPtr;
  370.  
  371.             _device.ImmediateContext.ClearRenderTargetView(renderTargetView, new Color4(0, 0, 0, 0));
  372.  
  373.             device10Mutex.Acquire(0, 100);
  374.        
  375.             renderTarget2D.BeginDraw();
  376.             renderTarget2D.Clear(new Color4(0, 0, 0, 0));
  377.  
  378.             var x = 0;
  379.             var y = 0;
  380.             var textToDraw = "Test String should be drawn on screen...";
  381.             var rectTest = new RectangleF(x, y, font.FontSize * textToDraw.Length+500, font.FontSize);
  382.             var c = new SolidColorBrush(renderTarget2D, new Color4(255, 0, 0, 1));
  383.  
  384.             renderTarget2D.DrawText(textToDraw, font, rectTest, c);
  385.  
  386.             renderTarget2D.EndDraw();
  387.             device10Mutex.Release(0);
  388.  
  389.             device11Mutex.Acquire(0, 100);
  390.             //_device.ImmediateContext.CopyResource(SharpDX.Direct3D11.Resource.FromSwapChain<Texture2D>(_swapChain, 0), _surface);
  391.  
  392.             var srv = new ShaderResourceView(_device, textureD3D11);
  393.             effect.GetVariableByName("SpriteTex").AsShaderResource().SetResource(srv);
  394.             _device.ImmediateContext.InputAssembler.InputLayout = layoutOverlay;
  395.             _device.ImmediateContext.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(vertexBufferOverlay, VertexPositionTexture.SizeInBytes, 0));
  396.             var currentTechnique = effect.GetTechniqueByName("SpriteTech");
  397.  
  398.             for (var pass = 0; pass < currentTechnique.Description.PassCount; ++pass)
  399.             {
  400.                 using (var effectPass = currentTechnique.GetPassByIndex(pass))
  401.                 {
  402.                     effectPass.Apply(_device.ImmediateContext);
  403.                 }
  404.                 _device.ImmediateContext.Draw(4, 0);
  405.             }
  406.             srv.Dispose();
  407.             device11Mutex.Release(0);
  408.  
  409.             swapChain.Present(0, PresentFlags.None);
  410.  
  411.             return this.DXGISwapChain_PresentHook.Original(swapChainPtr, syncInterval, flags);
  412.         }
  413.  
  414.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement