【问题标题】:DirectX9 CreateDevice() returns D3DERR_INVALIDCALL in injected DLL for VMT hookingDirectX9 CreateDevice() 在注入的 DLL 中返回 D3DERR_INVALIDCALL 用于 VMT 挂钩
【发布时间】:2019-08-07 15:18:34
【问题描述】:

我想修改 DirectX-Application 的行为(即我想通过注入代码(作为 DLL)来实现类似于 OrfeasZ [https://github.com/OrfeasZ/Statman/releases] as Onscreen-Info for Hitman 2 的 Statman-Application 的程序)并挂钩 DirectX DeviceInterface VMT。

由于有关如何为 DirectX11 应用程序执行此操作的资源非常有限,我首先想通过创建一个程序来了解如何在 DX9 中执行此操作,该程序可以获取任何 DirectX9 应用程序的 DeviceInterface 指针。我在我的 DLL 的 DllMain() 函数中编写了这段代码(这几乎是该线程 Hooking DirectX EndScene from an injected DLL 的第三个答案的 1:1 复制/粘贴):

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 应用程序时(我已经在 Civilization V 和 Total War: Shogun 2 中尝试过),它会打开一个窗口,因此它实际上能够从 d3d9.dll 获取 Direct3DCreate9 函数在游戏中,但pD3D->CreateDevice() 总是返回 `D3DERR_INVALIDCALL。我真的不明白这可能是什么原因,特别是因为这个程序的其余部分工作完美。有谁知道缺少/错了什么?

【问题讨论】:

    标签: c++ winapi directx reverse-engineering


    【解决方案1】:

    D3DERR_INVALIDCALL

    方法调用无效。例如,方法的参数可能不 是一个有效的指针。

    根据错误信息,此问题可能是由 IDirect3D9::CreateDevice 方法的无效参数引起的。你需要初始化指针:

       IDirect3DDevice9 *pReturnedDeviceInterface = NULL;
    

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

    【讨论】:

      猜你喜欢
      • 2012-08-08
      • 2010-12-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多