好的,基本上,我正在尝试将DLL注入到游戏中,用于外部菜单进行调试,并且我的钩子工作得非常好,我可以在屏幕上呈现一个普通的正方形,但是当我试图渲染imgui时,一些游戏DirectX就会死掉,而其他一些游戏根本就不会呈现。这个问题没有任何意义,因为我已经尝试了所有的东西,我已经切换了库,尝试了不同的编译设置,并且刚刚开始做一些随机的操作,但是仍然没有用,我使用的挂钩库是min钩子(我正在使用kiero,但是尝试找出切换到手动获取D3D设备的问题)。
正如我前面说的,我的钩子工作得很好,我可以在屏幕上没有问题地呈现一个正方形,但是我不能呈现imgui (是的,我检查了它是imgui的DX9版本),代码:
long __stdcall EndSceneHook(IDirect3DDevice9* pDevice) // Our hooked endscene
{
D3DRECT BarRect = { 100, 100, 200, 200 };
pDevice->Clear(1, &BarRect, D3DCLEAR_TARGET, D3DCOLOR_ARGB(255, 0, 255, 0), 0.0f, 0);
if (!EndSceneInit) {
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO();
ImGui_ImplWin32_Init(TrackmaniaWindow);
ImGui_ImplDX9_Init(pDevice);
EndSceneInit = true;
return OldEndScene(pDevice);
}
ImGui_ImplDX9_NewFrame();
ImGui_ImplWin32_NewFrame();
ImGui::NewFrame();
ImGui::ShowDemoWindow();
ImGui::EndFrame();
ImGui::Render();
ImGui_ImplDX9_RenderDrawData(ImGui::GetDrawData());
return OldEndScene(pDevice); // Call original ensdcene so the game can draw
}
如果你想说我忘了重新设置钩子,但游戏几乎从不调用它,所以我可能做错了,代码:
long __stdcall ResetHook(IDirect3DDevice9* pDevice, D3DPRESENT_PARAMETERS Parameters) {
/* Delete imgui to avoid errors */
ImGui_ImplDX9_Shutdown();
ImGui_ImplWin32_Shutdown();
ImGui::DestroyContext();
/* Check if its actually being called */
if (!ResetInit) {
std::cout << "Reset called correctly" << std::endl;
ResetInit = true;
}
/* Return old function */
return OldReset(pDevice, Parameters);
}
以防万一,我确实搞砸了其中一个函数的挂钩过程,我还将包括我用来实际挂钩它们的代码。
if (MH_CreateHook(vTable[42], EndSceneHook, (void**)&OldEndScene) != MH_OK)
ThrowError(MinHook_Hook_Creation_Failed);
if (MH_CreateHook(vTable[16],OldReset,(void**)&OldReset)!=MH_OK)
ThrowError(MinHook_Hook_Creation_Failed);
MH_EnableHook(MH_ALL_HOOKS);
发布于 2022-07-17 00:52:17
好的,所以我已经解决了这个问题,但是万一其他人需要帮助,我已经找到了一些修复方法来解释为什么会崩溃/不呈现。
首先是EnumWindow()
,如果您正在使用EnumWindows()
获取目标进程HWND,那么这很可能是您的一个或全部问题,对于内部欺骗,在游戏加载时使用GetForegroundWindow()
,或者您可以使用FindWindow(0,"Window Name")
(用于外部和内部游戏都需要加载)。
void MainThread(){
HWND ProcessWindow = 0;
WaitForProcessToLoad(GameHandle); // This is just an example of waiting for the game to load
ProcessWindow = GetForegroundWindow(); // We got the HWND
// or
ProcessWindow = FindWindow(0,"Thing.exe");
}
为了从第二个可能的问题开始,确保您的挂钩函数的替换函数实际上是传递正确的参数(这是如果您的钩子立即崩溃),并确保您正在返回原始函数。
确保您的WndProc函数工作正常(如果您不知道如何运行,那么谷歌DX9挂钩教程并复制+粘贴那里的代码)。
最后一个修复是如何将imgui呈现到屏幕上,如果imgui在第一个补丁之后没有呈现,那么很可能是因为您没有调用所需的函数,这是一个正确生成imgui呈现的示例。
long __stdcall EndSceneHook(IDirect3DDevice9* pDevice) // Our hooked endscene
{
if (!EndSceneInit) {
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO();
ImGui::StyleColorsDark();
ImGui_ImplWin32_Init(Window);
ImGui_ImplDX9_Init(pDevice);
EndSceneInit = true;
return OldEndScene(pDevice);
}
ImGui_ImplDX9_NewFrame();
ImGui_ImplWin32_NewFrame();
ImGui::NewFrame();
ImGui::ShowDemoWindow();
ImGui::EndFrame();
ImGui::Render();
ImGui_ImplDX9_RenderDrawData(ImGui::GetDrawData());
return OldEndScene(pDevice); // Call original ensdcene so the game can draw
}
如果这些修正都不起作用,那么谷歌错误或者youtube DX9链接教程
https://stackoverflow.com/questions/73007919
复制相似问题