DirectX9 CreateDevice()在注入的DLL中返回D3DERR_INVALIDCALL以进行VMT挂钩

时间:2019-03-16 20:42:50

标签: c++ winapi directx reverse-engineering

我想通过将代码(如DLL)注入DLL中来修改DirectX-Application的行为(即,我想实现与OrfeasZ [https://github.com/OrfeasZ/Statman/releases]的Statman-Application类似的程序,作为适用于Hitman 2的屏幕信息)。并挂钩DirectX DeviceInterface VMT。

由于有关如何为DirectX11-Application执行此操作的资源非常有限,因此我首先想通过创建获取任何DirectX9-Application的DeviceInterface指针的程序来学习如何在DX9中进行此操作。我在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-Application(我在Civilization V和Total War:Shogun 2中尝试过)时,它会打开一个窗口,因此它实际上能够从d3d9.dll获取Direct3DCreate9函数。在游戏中,但pD3D->CreateDevice()总是返回`D3DERR_INVALIDCALL。我真的不知道这可能是什么原因,尤其是因为该程序的其余部分都可以正常工作。有人知道什么是缺失/错误吗?

1 个答案:

答案 0 :(得分:0)

  

D3DERR_INVALIDCALL

     

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

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

   IDirect3DDevice9 *pReturnedDeviceInterface = NULL;

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