Creating DirectX objects directly from DllMain() fails. I have tried starting a new thread, create the objects there and them get vtable/addresses of the functions I'm about to hook.
I'm using Microsoft Detours, DetourTransactionCommit() cannot be called from another thread than DllMain thread.
I have also tried waiting for the thread to finish collecting the addresses, like this:
BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved)
{
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
{
std::thread(InitializeHooks).detach();
while (!_done)
{
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
// ...
break;
}
}
return TRUE;
}
But doing this, it gets stuck whenever it tries to call any DirectX function.
I'm getting the DirectX function addresses like this:
void InitializeHooks()
{
if (HMODULE d3d9Module = GetModuleHandle("d3d9.dll"))
{
typedef IDirect3D9* (WINAPI* Direct3DCreate9Func)(UINT SDKVersion);
Direct3DCreate9Func d3d9Create = (Direct3DCreate9Func)GetProcAddress(d3d9Module, "Direct3DCreate9");
if (d3d9Create)
{
IDirect3D9* d3d9 = d3d9Create(D3D_SDK_VERSION);
if (d3d9)
{
D3DPRESENT_PARAMETERS d3dpp = {};
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.hDeviceWindow = GetDesktopWindow();
IDirect3DDevice9* device = nullptr;
if (SUCCEEDED(d3d9->CreateDevice(
D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
GetDesktopWindow(),
D3DCREATE_HARDWARE_VERTEXPROCESSING,
&d3dpp,
&device)))
{
void* deviceVTable = *(void**)device;
HookVirtualMethod(
(PVOID*)&originalD3D9Present,
(PVOID)HookedD3D9Present,
deviceVTable,
17
);
device->Release();
}
d3d9->Release();
}
}
}
// ...
}
I have tested collecting the address from a different process and my hooks worked correctly:
void HookVirtualMethod(PVOID* ppOriginal, PVOID pDetour)
{
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(ppOriginal, pDetour);
r = DetourTransactionCommit();
}
// ...
originalD3D9Present = reinterpret_cast<D3D9Present>(0x00007ffd891c8c90);
originalD3D11Draw = reinterpret_cast<D3D11Draw>(0x00007ffdbd7cd0b0);
originalD3D11DrawIndexed = reinterpret_cast<D3D11DrawIndexed>(0x00007ffdbd7cdc30);
originalDXGIPresent = reinterpret_cast<DXGIPresent>(0x00007ffdbe2e18c0);
HookVirtualMethod((PVOID*)&originalD3D9Present, (PVOID)HookedD3D9Present);
HookVirtualMethod((PVOID*)&originalD3D11Draw, (PVOID)HookedD3D11Draw);
HookVirtualMethod((PVOID*)&originalD3D11DrawIndexed, (PVOID)HookedD3D11DrawIndexed);
HookVirtualMethod((PVOID*)&originalDXGIPresent, (PVOID)HookedDXGIPresent);
How I could get the addresses from inside the DLL in this case?
InitializeHooks()but not wait for it inside dll entry pointDllMainis not a thread, it is an entry point. And thread creation is explicitly listed among things you should never perform from withinDllMain. Whatever you are trying to do here, trying to do it withinDllMainis certainly not a good idea.