x64 驱动全局hook d3d9 的例子
时间: 2024-01-04 13:45:39 浏览: 282
在 Windows x64 下全局 Hook D3D9 驱动需要使用驱动程序来实现,下面是一个简单的示例代码:
```c
#include <ntddk.h>
#include <d3d9.h>
#pragma comment(lib, "winmm.lib")
typedef struct _D3D9_DEVICE_CALLBACKS {
PVOID Present;
PVOID Reset;
} D3D9_DEVICE_CALLBACKS, *PD3D9_DEVICE_CALLBACKS;
typedef struct _D3D9_CALLBACKS {
PVOID Direct3DCreate9;
D3D9_DEVICE_CALLBACKS DeviceCallbacks;
} D3D9_CALLBACKS, *PD3D9_CALLBACKS;
DRIVER_INITIALIZE DriverEntry;
DRIVER_UNLOAD DriverUnload;
D3D9_CALLBACKS g_D3D9Callbacks = { 0 };
VOID OnD3D9Present(IDirect3DDevice9* pDevice)
{
DbgPrint("D3D9 Present called\n");
}
VOID OnD3D9Reset(IDirect3DDevice9* pDevice, D3DPRESENT_PARAMETERS* pPresentationParameters)
{
DbgPrint("D3D9 Reset called\n");
}
NTSTATUS OnDeviceControl(PDEVICE_OBJECT pDeviceObject, PIRP pIrp)
{
PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
switch (pIrpStack->Parameters.DeviceIoControl.IoControlCode)
{
case IOCTL_D3D9_REGISTER_CALLBACKS:
g_D3D9Callbacks = *(PD3D9_CALLBACKS)pIrpStack->Parameters.DeviceIoControl.Type3InputBuffer;
if (g_D3D9Callbacks.Direct3DCreate9)
{
PVOID pDirect3D = ((LPDIRECT3D(__stdcall*)(UINT))g_D3D9Callbacks.Direct3DCreate9)(D3D_SDK_VERSION);
if (pDirect3D)
{
LPDIRECT3DDEVICE9 pDevice = NULL;
D3DPRESENT_PARAMETERS PresentationParameters = { 0 };
PresentationParameters.BackBufferWidth = 640;
PresentationParameters.BackBufferHeight = 480;
PresentationParameters.BackBufferFormat = D3DFMT_X8R8G8B8;
PresentationParameters.BackBufferCount = 1;
PresentationParameters.MultiSampleType = D3DMULTISAMPLE_NONE;
PresentationParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
PresentationParameters.hDeviceWindow = NULL;
PresentationParameters.Windowed = TRUE;
PresentationParameters.EnableAutoDepthStencil = FALSE;
PresentationParameters.Flags = 0;
((LPDIRECT3D9)pDirect3D)->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, NULL, D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&PresentationParameters, &pDevice);
if (pDevice)
{
if (g_D3D9Callbacks.DeviceCallbacks.Present)
{
((VOID(__stdcall*)(IDirect3DDevice9*))g_D3D9Callbacks.DeviceCallbacks.Present)(pDevice);
}
if (g_D3D9Callbacks.DeviceCallbacks.Reset)
{
((VOID(__stdcall*)(IDirect3DDevice9*, D3DPRESENT_PARAMETERS*))g_D3D9Callbacks.DeviceCallbacks.Reset)(pDevice, &PresentationParameters);
}
pDevice->Release();
}
((LPDIRECT3D9)pDirect3D)->Release();
}
}
break;
}
pIrp->IoStatus.Status = STATUS_SUCCESS;
pIrp->IoStatus.Information = 0;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath)
{
NTSTATUS status = STATUS_SUCCESS;
PDEVICE_OBJECT pDeviceObject = NULL;
UNICODE_STRING deviceName = RTL_CONSTANT_STRING(L"\\Device\\D3D9Hook");
UNICODE_STRING symbolicLinkName = RTL_CONSTANT_STRING(L"\\DosDevices\\D3D9Hook");
IoCreateDevice(pDriverObject, 0, &deviceName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &pDeviceObject);
IoCreateSymbolicLink(&symbolicLinkName, &deviceName);
pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = OnDeviceControl;
pDriverObject->DriverUnload = DriverUnload;
return STATUS_SUCCESS;
}
VOID DriverUnload(PDRIVER_OBJECT pDriverObject)
{
UNICODE_STRING symbolicLinkName = RTL_CONSTANT_STRING(L"\\DosDevices\\D3D9Hook");
IoDeleteSymbolicLink(&symbolicLinkName);
IoDeleteDevice(pDriverObject->DeviceObject);
}
```
下面是一个用户模式程序调用驱动程序的示例代码:
```c
#include <Windows.h>
#include <cstdio>
#include <d3d9.h>
#define IOCTL_D3D9_REGISTER_CALLBACKS CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)
typedef struct _D3D9_DEVICE_CALLBACKS {
PVOID Present;
PVOID Reset;
} D3D9_DEVICE_CALLBACKS, *PD3D9_DEVICE_CALLBACKS;
typedef struct _D3D9_CALLBACKS {
PVOID Direct3DCreate9;
D3D9_DEVICE_CALLBACKS DeviceCallbacks;
} D3D9_CALLBACKS, *PD3D9_CALLBACKS;
PD3D9_CALLBACKS g_pD3D9Callbacks = NULL;
HANDLE g_hDevice = INVALID_HANDLE_VALUE;
VOID OnD3D9Present(IDirect3DDevice9* pDevice)
{
printf("D3D9 Present called\n");
}
VOID OnD3D9Reset(IDirect3DDevice9* pDevice, D3DPRESENT_PARAMETERS* pPresentationParameters)
{
printf("D3D9 Reset called\n");
}
BOOL OpenDevice()
{
g_hDevice = CreateFile(L"\\\\.\\D3D9Hook", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
return g_hDevice != INVALID_HANDLE_VALUE;
}
VOID CloseDevice()
{
if (g_hDevice != INVALID_HANDLE_VALUE) {
CloseHandle(g_hDevice);
g_hDevice = INVALID_HANDLE_VALUE;
}
}
BOOL RegisterCallbacks()
{
D3D9_CALLBACKS callbacks = { 0 };
callbacks.Direct3DCreate9 = (PVOID)GetProcAddress(GetModuleHandle(L"d3d9.dll"), "Direct3DCreate9");
callbacks.DeviceCallbacks.Present = (PVOID)OnD3D9Present;
callbacks.DeviceCallbacks.Reset = (PVOID)OnD3D9Reset;
return DeviceIoControl(g_hDevice, IOCTL_D3D9_REGISTER_CALLBACKS, &callbacks, sizeof(callbacks), NULL, 0, NULL, NULL);
}
int main()
{
if (!OpenDevice())
{
printf("OpenDevice failed.\n");
return 1;
}
if (!RegisterCallbacks())
{
printf("RegisterCallbacks failed.\n");
CloseDevice();
return 1;
}
IDirect3D9* pDirect3D = Direct3DCreate9(D3D_SDK_VERSION);
if (pDirect3D)
{
IDirect3DDevice9* pDevice = NULL;
D3DPRESENT_PARAMETERS PresentationParameters = { 0 };
PresentationParameters.BackBufferWidth = 640;
PresentationParameters.BackBufferHeight = 480;
PresentationParameters.BackBufferFormat = D3DFMT_X8R8G8B8;
PresentationParameters.BackBufferCount = 1;
PresentationParameters.MultiSampleType = D3DMULTISAMPLE_NONE;
PresentationParameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
PresentationParameters.hDeviceWindow = NULL;
PresentationParameters.Windowed = TRUE;
PresentationParameters.EnableAutoDepthStencil = FALSE;
PresentationParameters.Flags = 0;
pDirect3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, NULL, D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&PresentationParameters, &pDevice);
if (pDevice)
{
pDevice->Release();
}
pDirect3D->Release();
}
CloseDevice();
return 0;
}
```
需要注意的是,这只是一个简单的示例,实际应用中可能需要更多的代码来处理不同的 D3D9 API 调用。另外,由于驱动程序需要在内核模式下运行,因此需要使用 Windows DDK 和 Visual Studio 等开发工具来编写和构建驱动程序。
阅读全文