DirectX9 CreateVice()返回DLL_INVALIDCALL在注射DLL中进行VMT挂钩

DirectX9 CreateDevice() returns D3DERR_INVALIDCALL in injected DLL for VMT hooking

本文关键字:DLL 挂钩 VMT INVALIDCALL CreateVice 返回 DirectX9      更新时间:2023-10-16

我想修改DirectX-Application的行为(即,我想实现类似于Orfeasz [https://github.com/orfeasz/orfeasz/orfeasz/statman/releases by Statman-Application的程序]作为杀手2)的屏幕上的INFO,通过将代码(AS DLL)注入其中并挂接Directx DeviceInterface VMT。

由于如何在DirectX11应用程序上执行此操作的资源非常有限,因此我首先想通过创建一个程序来获取任何DirectX9-Application的DeviceInterface指针来学习DX9中的方法。我在我的dll的DllMain()函数中写了此代码(几乎是从注射的DLL中对此线程挂接DirectX的第三个答案的复制/粘贴):

HMODULE hDLL = GetModuleHandleA("d3d9");
LPDIRECT3D9(__stdcall*pDirect3DCreate9)(UINT) = (LPDIRECT3D9(__stdcall*)(UINT))GetProcAddress(hDLL, "Direct3DCreate9");
LPDIRECT3D9 pD3D = pDirect3DCreate9(D3D_SDK_VERSION);
D3DDISPLAYMODE d3ddm;
HRESULT hRes = pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm);
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory(&d3dpp, sizeof(d3dpp));
d3dpp.Windowed = true;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = d3ddm.Format;
//WNDPROC TempWndProc;
WNDCLASSEX wc = { sizeof(WNDCLASSEX),CS_CLASSDC, WndProc,0L,0L,GetModuleHandle(NULL),NULL,NULL,NULL,NULL,TEXT("1"),NULL };
RegisterClassEx(&wc);
HWND hWnd = CreateWindow(TEXT("1"), NULL, WS_OVERLAPPEDWINDOW, 100, 100, 300, 300, GetDesktopWindow(), NULL, wc.hInstance, NULL);
ShowWindow(hWnd, SW_SHOW);
IDirect3DDevice9 * ppReturnedDeviceInterface;
hRes = pD3D->CreateDevice(
    D3DADAPTER_DEFAULT,
    D3DDEVTYPE_HAL,
    hWnd,
    D3DCREATE_SOFTWARE_VERTEXPROCESSING,
    &d3dpp, &ppReturnedDeviceInterface);
pD3D->Release();
DestroyWindow(hWnd);
if (pD3D == NULL) {
    //printf ("WARNING: D3D FAILED");
    return false;
}
unsigned long* pInterface = (unsigned long*)*((unsigned long*)ppReturnedDeviceInterface);

当我将DLL注入DirectX9-申请中(我已经尝试了文明V和Total War:Shogun:Shogun 2)时,它将打开一个窗口,因此实际上它可以从D3D9.DLL中获取Direct3Dcreate9函数在游戏中,但是pD3D->CreateDevice()总是返回`d3derr_invalidcall。我真的没有得到这样做的原因,尤其是因为该程序的其余部分完美无缺。有人知道缺少/错吗?

d3derr_invalidcall

方法调用无效。例如,方法的参数可能不会 成为有效的指针。

基于错误信息,此问题可能是由IDIRECT3D9 :: CENCETEVICE方法的无效参数引起的。您需要初始化指针:

   IDirect3DDevice9 *pReturnedDeviceInterface = NULL;

还检查hWnd是否是有效的窗口句柄和d3ddm.Format等。