Before, game capture would find addresses to important graphics functions by creating a graphics context for the desired API inside of the hook, and then find the function addresses that way. The big problem with that is that the context could often cause the hooked application to crash, especially if another hook was active. This bypasses that entire need by a simple console application that creates the contexts, finds the hook address offsets and then returns them via console output.
101 lines
2.3 KiB
C++
101 lines
2.3 KiB
C++
#define _CRT_SECURE_NO_WARNINGS
|
|
#include <stdio.h>
|
|
#include <windows.h>
|
|
#include <d3d9.h>
|
|
#include "get-graphics-offsets.h"
|
|
|
|
typedef HRESULT (WINAPI *d3d9createex_t)(UINT, IDirect3D9Ex**);
|
|
|
|
struct d3d9_info {
|
|
HMODULE module;
|
|
HWND hwnd;
|
|
IDirect3D9Ex *d3d9ex;
|
|
IDirect3DDevice9Ex *device;
|
|
IDirect3DSwapChain9 *swap;
|
|
};
|
|
|
|
static inline bool d3d9_init(d3d9_info &info)
|
|
{
|
|
d3d9createex_t create;
|
|
HRESULT hr;
|
|
|
|
info.hwnd = CreateWindowExA(0, DUMMY_WNDCLASS, "d3d9 get-offset window",
|
|
WS_POPUP, 0, 0, 1, 1, nullptr, nullptr,
|
|
GetModuleHandleA(nullptr), nullptr);
|
|
if (!info.hwnd) {
|
|
return false;
|
|
}
|
|
|
|
info.module = LoadLibraryA("d3d9.dll");
|
|
if (!info.module) {
|
|
return false;
|
|
}
|
|
|
|
create = (d3d9createex_t)GetProcAddress(info.module,
|
|
"Direct3DCreate9Ex");
|
|
if (!create) {
|
|
return false;
|
|
}
|
|
|
|
hr = create(D3D_SDK_VERSION, &info.d3d9ex);
|
|
if (FAILED(hr)) {
|
|
return false;
|
|
}
|
|
|
|
D3DPRESENT_PARAMETERS pp = {};
|
|
pp.Windowed = true;
|
|
pp.SwapEffect = D3DSWAPEFFECT_FLIP;
|
|
pp.BackBufferFormat = D3DFMT_A8R8G8B8;
|
|
pp.BackBufferWidth = 2;
|
|
pp.BackBufferHeight = 2;
|
|
pp.BackBufferCount = 1;
|
|
pp.hDeviceWindow = info.hwnd;
|
|
pp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
|
|
|
|
hr = info.d3d9ex->CreateDeviceEx(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
|
|
info.hwnd,
|
|
D3DCREATE_HARDWARE_VERTEXPROCESSING |
|
|
D3DCREATE_NOWINDOWCHANGES, &pp, nullptr, &info.device);
|
|
if (FAILED(hr)) {
|
|
return false;
|
|
}
|
|
|
|
hr = info.device->GetSwapChain(0, &info.swap);
|
|
if (FAILED(hr)) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static inline void d3d9_free(d3d9_info &info)
|
|
{
|
|
if (info.swap)
|
|
info.swap->Release();
|
|
if (info.device)
|
|
info.device->Release();
|
|
if (info.d3d9ex)
|
|
info.d3d9ex->Release();
|
|
if (info.hwnd)
|
|
DestroyWindow(info.hwnd);
|
|
}
|
|
|
|
void get_d3d9_offsets(struct d3d9_offsets *offsets)
|
|
{
|
|
d3d9_info info = {};
|
|
bool success = d3d9_init(info);
|
|
|
|
if (success) {
|
|
offsets->present = vtable_offset(info.module, info.device, 17);
|
|
offsets->reset = vtable_offset(info.module, info.device, 16);
|
|
offsets->present_ex = vtable_offset(info.module, info.device,
|
|
121);
|
|
offsets->reset_ex = vtable_offset(info.module, info.device,
|
|
132);
|
|
offsets->present_swap = vtable_offset(info.module, info.swap,
|
|
3);
|
|
}
|
|
|
|
d3d9_free(info);
|
|
}
|