简体   繁体   中英

Drawing Overlay inside DX11 Game (CryEngine) with C# and EasyHook

What I want to do:

I have a Game based on CrySDK which is DirectX11 and I want to draw an ingame overlay like the steam overlay.

-> I write C# since I don't know any C++, so I'm looking for ways to do this in C#.

-> I use EasyHook and SharpDX Libaries because it seems this is the best way to go.

-> I found a reference project which is apparently some kind of hack for SC2, I'm just interested in the overlay part however.

-> I use Visual Studio 2013

-> For now I'd be happy if I could draw random stuff inside a game at all

What I did so far:

I was looking through google and SO search results, problem is, that either the stuff is in C++, C or other, the results are from 2010 and not up to date with the current dx11, contain dead links or are unusable for any other reasons. This covers 95% of all I've turned up myself, some usuable hints have been included into my code.

I managed to create a Injector.dll and inject it into the game (at least i think it is injected, haven't had any usuable results so far)

What I have:

The file which does the injection:

...                
// Try inject thingy

            EasyHook.Config.Register("Star Citizen Noise.sc Client Overlay",
                                    //         "Direct3D9Hook.dll",
                                             "SharpDX.dll",
                                             "SharpDX.Direct3D11.dll",
                                             "Injector.dll");

            // Do the inject
            RemoteHooking.Inject(scProcess.Id, InjectionOptions.DoNotRequireStrongName, "Injector.dll", "Injector.dll", "Star Citizen Noise.sc Injector.dll");
            Console.WriteLine("DLL Injected.");
...

The injector.dll itself consists of this file, called Hooks/Graphics/Direct3D11Hook.cs (I tried to keep the structure similar to the oter sc2 reference project)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using System.Runtime.InteropServices;
using EasyHook;
using SharpDX;
using SharpDX.Direct3D11;
using Rectangle = SharpDX.Rectangle;

namespace Injector.Hooks.Graphics
{
    public class Direct3D11Hook : HookBase
    {

        private Device device = null;

        [UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true)]
        private delegate Result EndSceneDelegate(IntPtr devicePointer);

        public delegate void EndSceneEventDelegate(ref IntPtr devicePointer);
        public event EndSceneEventDelegate OnEndScene;

        private Result EndScene(IntPtr devicePointer)
        {
            try
            {
                //this.Log.LogMethodSignatureTypesAndValues(devicePointer);

                //GetOrCreateDevice
                if (this.device == null)
                    this.device = Device.FromPointer<Device>(devicePointer);

                if (this.OnEndScene != null)
                    this.OnEndScene(ref devicePointer);

                System.Drawing.Graphics g = System.Drawing.Graphics.FromHdc(devicePointer);
                //System.Drawing.Graphics g = System.Drawing.Graphics.FromHwndInternal(devicePointer);

                // lets try to draw something
                Pen myPen = new Pen(System.Drawing.Color.Pink, 4);
                System.Drawing.Point P1 = new System.Drawing.Point(50, 50);
                System.Drawing.Point P2 = new System.Drawing.Point(500, 500);
                g.DrawLine(myPen, P1, P2);
                g.Dispose();
                //this.device.EndScene();

                return Result.Ok;
            }
            catch (SharpDXException ex)
            {
                //Log.Warn(ex);
                Console.WriteLine(ex);
                return ex.ResultCode;
            }
            catch (Exception ex)
            {
                //this.Log.Fatal(ex);
                Console.WriteLine(ex);
                return Result.UnexpectedFailure;
            }
        }

        public override void Install()
        {
            try
            {
                EndSceneDelegate esd = new EndSceneDelegate(this.EndScene);

            }
            catch (Exception)
            {

                throw;
            }
        }

        public override void Uninstall()
        {

        }

    }
}

Here I tried to provide an override function for the EndScene function, because i think this is where I need to be. Needless to say, nothing appears to be drawn.

The delegate definitions are somewhat of a copypaste from the reference project however I have yet to find out how to actually hook my function into the render pipeline and/or react to events which might help my cause.

There is also this huge file [ https://github.com/jasonpang/Starcraft2Hook/blob/master/Game/Hooks/Graphics/Direct3D9.cs] which defines function addresses which seems to work for DX9, I don't think that it can just be copy pasted and used for DX11 as well, so probably there are new function addresses in DX11? How can I find those? Where do I need to look? Is it something SharpDX can help me with?

TL;DR

Want to create steam-like overlay for DX11 game, need to hook into D3D stuff and magic and shit, got dll inject working, need help with pipeline injection

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM