.NET 4.x Реализовать хук на D3D9 (DirectX9), чтобы выводить сообщения в чужом окне (игре) - C#

Узнай цену своей работы

Формулировка задачи:

Здравствуйте уважаемые гуру дотНЕТа. Помогите плиз. Хочу реализовать хук на D3D9 (DirectX9), чтобы выводит сообщения в чужом окне (игре) из моего программы. Для этого нашел пример и взял нужную часть кода, но он то работает то не работает, и даже если заработает, через некоторые время игра кращится, в чем причина?
using System.Threading;
using System.Runtime.InteropServices;
using EasyHook;
using System.Windows.Forms;
using System.Diagnostics;
using SharpDX.Direct3D9;
 
public class Main : EasyHook.IEntryPoint
    {
        Device device;
        const int D3D9_DEVICE_METHOD_COUNT = 119;
        const int D3D9Ex_DEVICE_METHOD_COUNT = 15;
        bool _supportsDirect3D9Ex = false;
 
        LocalHook Direct3DDevice_EndSceneHook = null;
        LocalHook Direct3DDevice_ResetHook = null;
        LocalHook Direct3DDevice_PresentHook = null;
        LocalHook Direct3DDeviceEx_PresentExHook = null;
 
        List<IntPtr> id3dDeviceFunctionAddresses = new List<IntPtr>();
 
        protected List<LocalHook> Hooks = new List<LocalHook>();
 
        FileMonInterface Interface;
        public Main(RemoteHooking.IContext InContext, String InChannelName)
        {
            Interface = EasyHook.RemoteHooking.IpcConnectClient<FileMonInterface>(InChannelName);
            Interface.Ping();
        }
 
        public void Run(RemoteHooking.IContext InContext, String InChannelName)
        {
            id3dDeviceFunctionAddresses = new List<IntPtr>();
 
            using (Direct3D d3d = new Direct3D())
            {
                using (var renderForm = new System.Windows.Forms.Form())
                {
                    using (device = new Device(d3d, 0, DeviceType.NullReference, IntPtr.Zero, CreateFlags.HardwareVertexProcessing, new PresentParameters() { BackBufferWidth = 1, BackBufferHeight = 1, DeviceWindowHandle = renderForm.Handle }))
                    {
                        id3dDeviceFunctionAddresses.AddRange(GetVTblAddresses(device.NativePointer, D3D9_DEVICE_METHOD_COUNT));
                    }
                }
            }
            try
            {
                using (Direct3DEx d3dEx = new Direct3DEx())
                {
                    using (var renderForm = new System.Windows.Forms.Form())
                    {
                        using (var deviceEx = new DeviceEx(d3dEx, 0, DeviceType.NullReference, IntPtr.Zero, CreateFlags.HardwareVertexProcessing, new PresentParameters() { BackBufferWidth = 1, BackBufferHeight = 1, DeviceWindowHandle = renderForm.Handle }, new DisplayModeEx() { Width = 800, Height = 600 }))
                        {
                            id3dDeviceFunctionAddresses.AddRange(GetVTblAddresses(deviceEx.NativePointer, D3D9_DEVICE_METHOD_COUNT, D3D9Ex_DEVICE_METHOD_COUNT));
                            _supportsDirect3D9Ex = true;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                _supportsDirect3D9Ex = false;
                MessageBox.Show( ex.ToString());
            }
 
            Direct3DDevice_EndSceneHook = LocalHook.Create(
                id3dDeviceFunctionAddresses[(int)d3d9_indexes.Direct3DDevice9FunctionOrdinals.EndScene],
                new Direct3D9Device_EndSceneDelegate(EndSceneHook),
                this);
 
            unsafe
            {
                if (_supportsDirect3D9Ex)
                {
                    Direct3DDeviceEx_PresentExHook = LocalHook.Create(
                        id3dDeviceFunctionAddresses[(int)d3d9_indexes.Direct3DDevice9ExFunctionOrdinals.PresentEx],
                        new Direct3D9DeviceEx_PresentExDelegate(PresentExHook),
                        this);
                }
 
                Direct3DDevice_PresentHook = LocalHook.Create(
                    id3dDeviceFunctionAddresses[(int)d3d9_indexes.Direct3DDevice9FunctionOrdinals.Present],
                    new Direct3D9Device_PresentDelegate(PresentHook),
                    this);
            }
 
            Direct3DDevice_ResetHook = LocalHook.Create(
                id3dDeviceFunctionAddresses[(int)d3d9_indexes.Direct3DDevice9FunctionOrdinals.Reset],
                new Direct3D9Device_ResetDelegate(ResetHook),
                this);
 
            Direct3DDevice_EndSceneHook.ThreadACL.SetExclusiveACL(new Int32[1]);
            Hooks.Add(Direct3DDevice_EndSceneHook);
 
            Direct3DDevice_PresentHook.ThreadACL.SetExclusiveACL(new Int32[1]);
            Hooks.Add(Direct3DDevice_PresentHook);
 
            if (_supportsDirect3D9Ex)
            {
                Direct3DDeviceEx_PresentExHook.ThreadACL.SetExclusiveACL(new Int32[1]);
                Hooks.Add(Direct3DDeviceEx_PresentExHook);
            }
 
            Direct3DDevice_ResetHook.ThreadACL.SetExclusiveACL(new Int32[1]);
            Hooks.Add(Direct3DDevice_ResetHook);
        }

        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();
        }
 
        [UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true)]
        delegate int Direct3D9Device_EndSceneDelegate(IntPtr device);
 
        bool _isUsingPresent = false;
 
        int EndSceneHook(IntPtr devicePtr)
        {
            Device device = (Device)devicePtr;
 
            if (!_isUsingPresent)
                DoCaptureRenderTarget(device, "EndSceneHook");
 
            device.EndScene();
            return SharpDX.Result.Ok.Code;
        }
             .....................
             // ТУТ УБРАЛ НЕКОТОРЫЕ КОДЫ КОТОРЫЕ СЧИТАЛ НЕ НУЖНЫМ, ИЗ ЗА ОГРАНИЧЕНИЕ НА ФОРУМЕ
              .....................
              
        [UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true)]
        delegate int Direct3D9Device_ResetDelegate(IntPtr device, ref PresentParameters presentParameters);
 
        object _lockRenderTarget = new object();
        Surface _renderTarget;
 
        int ResetHook(IntPtr devicePtr, ref PresentParameters presentParameters)
        {
            //Device device = (Device)devicePtr;
            try
            {
 
                lock (_lockRenderTarget)
                {
                    if (_renderTarget != null)
                    {
                        _renderTarget.Dispose();
                        _renderTarget = null;
                    }
                }
                device.Reset(presentParameters);
                return SharpDX.Result.Ok.Code;
            }
            catch (SharpDX.SharpDXException sde)
            {
                return sde.ResultCode.Code;
            }
            catch (Exception e)
            {
                MessageBox.Show(e.ToString());
                return SharpDX.Result.Ok.Code;
            }
        }
 
        void DoCaptureRenderTarget(Device device, string hook)
        {
            try
            {
                   FontDescription f = new FontDescription()
                   {
                            Height = 16,
                            FaceName = "Arial",
                            Italic = false,
                            Width = 0,
                            MipLevels = 1,
                            CharacterSet = FontCharacterSet.Default,
                            OutputPrecision = FontPrecision.Default,
                            Quality = FontQuality.Antialiased,
                            PitchAndFamily = FontPitchAndFamily.Default | FontPitchAndFamily.DontCare,
                            Weight = FontWeight.Bold
                    };
 
                    SharpDX.Direct3D9.Font font1 = new Font(device, f);
                    
                    font1.DrawText(null, "Hooked", 50, 60, new  SharpDX.ColorBGRA(255f,100f,100f,1f));
 
            }
            catch (Exception e)
            {
                MessageBox.Show(e.ToString());
            }
        }

Решение задачи: «.NET 4.x Реализовать хук на D3D9 (DirectX9), чтобы выводить сообщения в чужом окне (игре)»

textual
Листинг программы
#include "stdafx.h"
#include <windows.h>
#include <cstdio>
#include <d3d9.h>
#include <d3dx9.h>
 
#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "d3dx9.lib")
 
/*Color's*/
#define GREEN            D3DCOLOR_ARGB(255, 000, 255, 000)//Trans(250=SOLID,0=INVISIBLE),Red,Green,Blue
#define BLUE            D3DCOLOR_ARGB(255, 000, 000, 255) 
LPD3DXFONT               m_font = NULL;
 
boolean DrawMessage(LPD3DXFONT font, unsigned int x, unsigned int y, int alpha, unsigned char r, unsigned char g, unsigned char b, LPCSTR Message)
 
{   // Create a colour for the text
 
   D3DCOLOR fontColor = D3DCOLOR_ARGB(alpha, r, g, b);
   RECT rct; //Font
   rct.left=x;
   rct.right=150;
   rct.top=y;
   rct.bottom=rct.top+150;   
   font->DrawTextA(NULL, Message, -1, &rct, 0, fontColor);
   return true;
}
 
//======ВОТ ТУТ
void stuff(LPDIRECT3DDEVICE9 pDevice, D3DCOLOR Color) //Crosshair function by: Hans211
{
        //  D3DCOLOR rectColor = D3DCOLOR_XRGB(255,0,255);   //No point in using alpha because clear & alpha dont work!
    //  D3DRECT BarRect = { 10, 10, 40, 40 }; 
    //  pDevice->Clear(1,&BarRect,  D3DCLEAR_TARGET | D3DCLEAR_TARGET ,rectColor,0,0);
    
    DrawMessage(m_font,40,40,255,255,0,255,  "Привет, Мир!");
}
//======ВОТ ТУТ
 
 
void *DetourFunc(BYTE *src, const BYTE *dst, const int len) // Old detour from GD Forums.
{
BYTE *jmp = (BYTE*)malloc(len+5);
DWORD dwback;
VirtualProtect(src, len, PAGE_READWRITE, &dwback);
memcpy(jmp, src, len); jmp += len;
jmp[0] = 0xE9;
*(DWORD*)(jmp+1) = (DWORD)(src+len - jmp) - 5;
src[0] = 0xE9;
*(DWORD*)(src+1) = (DWORD)(dst - src) - 5;
VirtualProtect(src, len, dwback, &dwback);
return (jmp-len);
}
 
typedef HRESULT(__stdcall* EndScene_)(LPDIRECT3DDEVICE9);
EndScene_ pEndScene;//our define
typedef HRESULT (WINAPI* Reset_) (LPDIRECT3DDEVICE9 pDevice, D3DPRESENT_PARAMETERS* pPresentationParameters);
Reset_ pReset;
 
 
/*Hooked Endscene*/
HRESULT __stdcall EndScene(LPDIRECT3DDEVICE9 pDevice)
{//Calling our Hook.EndScene makes us able to draw.    
    D3DXCreateFont( pDevice, 17, 0, FW_BOLD, 0, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, ANTIALIASED_QUALITY, DEFAULT_PITCH | FF_DONTCARE, TEXT("Arial"), &m_font );
    stuff(pDevice,BLUE); //Drawing
 
     return pEndScene(pDevice);
}
 
 
 
/*Tools for Hooking by Gordon`*/
     bool bCompare(const BYTE* pData, const BYTE* bMask, const char* szMask)//by Gordon`
{
     for(;*szMask;++szMask,++pData,++bMask)
         if(*szMask=='x' && *pData!=*bMask)   return 0;
     return (*szMask) == NULL;
}
DWORD FindPattern(DWORD dwAddress,DWORD dwLen,BYTE *bMask,char * szMask)//by Gordon`
{
     for(DWORD i=0; i<dwLen; i++)
         if (bCompare((BYTE*)(dwAddress+i),bMask,szMask))  return (DWORD)(dwAddress+i);
     return 0;
}
DWORD GetAddressPtr(int index) //by Gordon`
{
  DWORD* VTableStart = 0;  
     DWORD dwDevicePointer = FindPattern((DWORD)GetModuleHandle(L"d3d9.dll"), 0x1280000, (PBYTE)"\xC7\x06\x00\x00\x00\x00\x89\x86\x00\x00\x00\x00\x89\x86", "xx????xx????xx");
     memcpy(&VTableStart, (void*)(dwDevicePointer+2), 4);
     return VTableStart[index];
} 
DWORD FindDevice(DWORD Len)//by Gordon`
{
     DWORD dwObjBase = 0;
         
     dwObjBase = (DWORD)LoadLibrary(L"D3D9.DLL");
     while (dwObjBase++ < dwObjBase + Len)
     {
         if ( (*(WORD*)(dwObjBase + 0x00)) == 0x06C7
           && (*(WORD*)(dwObjBase + 0x06)) == 0x8689
           && (*(WORD*)(dwObjBase + 0x0C)) == 0x8689
           ) { dwObjBase += 2; break; }
     }
     return( dwObjBase );
}
 
/*The Hook*/
void Hook()
{
     PDWORD VTable;
     *(DWORD*)&VTable = *(DWORD*)FindDevice(0x128000);
pEndScene = ( EndScene_ )DetourFunc((PBYTE) VTable[42],(PBYTE)EndScene, 5);//Hooking our endscene
 
Sleep( 100 ); 
}
 
/*DLL Main*/
int WINAPI DllMain(HINSTANCE hInst,DWORD reason,LPVOID reserved)
{
switch(reason)
{
case DLL_PROCESS_ATTACH:
     CreateThread(0, 0, (LPTHREAD_START_ROUTINE) Hook, 0, 0, 0);//Starting our Hook
break;
}
return true;
}

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

7   голосов , оценка 4.429 из 5
Похожие ответы