ANTICHAT

ANTICHAT (https://forum.antichat.xyz/index.php)
-   Общие вопросы программирования (https://forum.antichat.xyz/forumdisplay.php?f=206)
-   -   ImGui directx hook, крашит, хелп. (https://forum.antichat.xyz/showthread.php?t=1422802)

ImmortalDev 18.02.2022 23:44

Нашел рабочий directx hook для гта са, при инжекте все ок, рисовал маленький черный квадратик как надо.

Но, когда я попытался встроить сюда ImGui, при инжекте просто напросто крашит игру.

В чем тут может проблема? Не пинайте сильно, в этой теме не особо шарю.

Код:

C++:





Код:

// dllmain.cpp : Defines the entry point for the DLL application.
#include "framework.h"
//#include "imgui.h"
#include "imgui_impl_dx9.h"
#include "imgui_impl_win32.h"
typedef
HRESULT
(
__stdcall
*
_EndScene
)
(
IDirect3DDevice9
*
pDevice
)
;
_EndScene oEndScene
;
const
char
*
windowName
=
"GTA: San Andreas"
;
HWND  window
=
FindWindowA
(
NULL
,
windowName
)
;
IDirect3DDevice9
*
pDevice
;
bool
initialized
=
false
;
void
InitImGui
(
IDirect3DDevice9
*
pDevice
)
{
D3DDEVICE_CREATION_PARAMETERS CP
;
pDevice
->
GetCreationParameters
(
&
CP
)
;
//hWnd = CP.hFocusWindow;
ImGuiIO
&
io
=
ImGui
::
GetIO
(
)
;
(
void
)
io
;
io
.
IniFilename
=
NULL
;
io
.
ConfigFlags
|=
ImGuiConfigFlags_NavEnableKeyboard
;
io
.
Fonts
->
AddFontDefault
(
)
;
ImGui_ImplWin32_Init
(
window
)
;
ImGui_ImplDX9_Init
(
pDevice
)
;
initialized
=
true
;
return
;
}
HRESULT __stdcall
hkEndScene
(
IDirect3DDevice9
*
pDevice
)
{
if
(
!
initialized
)
InitImGui
(
pDevice
)
;
else
{
ImGui_ImplDX9_NewFrame
(
)
;
ImGui_ImplWin32_NewFrame
(
)
;
ImGui
::
NewFrame
(
)
;
//ImGui::ShowDemoWindow(&bShow);
ImGui
::
EndFrame
(
)
;
ImGui
::
Render
(
)
;
ImGui_ImplDX9_RenderDrawData
(
ImGui
::
GetDrawData
(
)
)
;
}
return
oEndScene
(
pDevice
)
;
}
DWORD APIENTRY
MainThread
(
LPVOID lparam
)
{
while
(
!
GetModuleHandleA
(
"d3d9.dll"
)
)
//waiting till d3d9.dll gets loaded
{
Sleep
(
1
)
;
}
// Endscene hook
void
*
*
vTableDevice
=
*
(
void
*
*
*
)
(
*
(
DWORD
*
)
0xC97C28
)
;
VTableHookManager
*
vmtHooks
=
new
VTableHookManager
(
vTableDevice
,
119
)
;
oEndScene
=
(
_EndScene
)
vmtHooks
->
Hook
(
42
,
(
void
*
)
hkEndScene
)
;
////////////////////////////////////////////////////////////////////////////////
return
false
;
}
BOOL APIENTRY
DllMain
(
HMODULE hModule
,
DWORD  ul_reason_for_call
,
LPVOID lpReserved
)
{
switch
(
ul_reason_for_call
)
{
case
DLL_PROCESS_ATTACH
:
CreateThread
(
0
,
0
,
MainThread
,
hModule
,
0
,
0
)
;
case
DLL_THREAD_ATTACH
:
case
DLL_THREAD_DETACH
:
case
DLL_PROCESS_DETACH
:
break
;
}
return
TRUE
;
}


F0RQU1N and 19.02.2022 05:37

У тебч же даже createcontext нету

zTechnology 19.02.2022 12:54

C++:





Код:

// dllmain.cpp : Defines the entry point for the DLL application.
#include "framework.h"
//#include "imgui.h"
#include "imgui_impl_dx9.h"
#include "imgui_impl_win32.h"
typedef
HRESULT
(
__stdcall
*
_EndScene
)
(
IDirect3DDevice9
*
pDevice
)
;
_EndScene oEndScene
;
bool
initialized
=
false
;
void
InitImGui
(
IDirect3DDevice9
*
pDevice
)
{
D3DDEVICE_CREATION_PARAMETERS CP
;
pDevice
->
GetCreationParameters
(
&
CP
)
;
//hWnd = CP.hFocusWindow;
ImGui
::
CreateContext
(
)
;
ImGuiIO
&
io
=
ImGui
::
GetIO
(
)
;
(
void
)
io
;
io
.
IniFilename
=
NULL
;
io
.
ConfigFlags
|=
ImGuiConfigFlags_NavEnableKeyboard
;
io
.
Fonts
->
AddFontDefault
(
)
;
ImGui_ImplWin32_Init
(
window
)
;
ImGui_ImplDX9_Init
(
pDevice
)
;
initialized
=
true
;
return
;
}
HRESULT __stdcall
hkEndScene
(
IDirect3DDevice9
*
pDevice
)
{
if
(
!
initialized
)
InitImGui
(
pDevice
)
;
else
{
ImGui_ImplDX9_NewFrame
(
)
;
ImGui_ImplWin32_NewFrame
(
)
;
ImGui
::
NewFrame
(
)
;
ImGui
::
Render
(
)
;
ImGui_ImplDX9_RenderDrawData
(
ImGui
::
GetDrawData
(
)
)
;
}
return
oEndScene
(
pDevice
)
;
}
DWORD APIENTRY
MainThread
(
LPVOID lparam
)
{
while
(
!
GetModuleHandleA
(
"d3d9.dll"
)
)
//waiting till d3d9.dll gets loaded
{
Sleep
(
1
)
;
}
HWND  window
=
FindWindowA
(
NULL
,
"GTA: San Andreas"
)
;
// Endscene hook
void
*
*
vTableDevice
=
*
(
void
*
*
*
)
(
*
(
DWORD
*
)
0xC97C28
)
;
VTableHookManager
*
vmtHooks
=
new
VTableHookManager
(
vTableDevice
,
119
)
;
oEndScene
=
(
_EndScene
)
vmtHooks
->
Hook
(
42
,
(
void
*
)
hkEndScene
)
;
////////////////////////////////////////////////////////////////////////////////
return
false
;
}
BOOL APIENTRY
DllMain
(
HMODULE hModule
,
DWORD  ul_reason_for_call
,
LPVOID lpReserved
)
{
switch
(
ul_reason_for_call
)
{
case
DLL_PROCESS_ATTACH
:
CreateThread
(
0
,
0
,
MainThread
,
hModule
,
0
,
0
)
;
case
DLL_THREAD_ATTACH
:
case
DLL_THREAD_DETACH
:
case
DLL_PROCESS_DETACH
:
break
;
}
return
TRUE
;
}


ImmortalDev 19.02.2022 14:48

Цитата:

Сообщение от zTechnology

C++:





Код:

// dllmain.cpp : Defines the entry point for the DLL application.
#include "framework.h"
//#include "imgui.h"
#include "imgui_impl_dx9.h"
#include "imgui_impl_win32.h"
typedef
HRESULT
(
__stdcall
*
_EndScene
)
(
IDirect3DDevice9
*
pDevice
)
;
_EndScene oEndScene
;
bool
initialized
=
false
;
void
InitImGui
(
IDirect3DDevice9
*
pDevice
)
{
D3DDEVICE_CREATION_PARAMETERS CP
;
pDevice
->
GetCreationParameters
(
&
CP
)
;
//hWnd = CP.hFocusWindow;
ImGui
::
CreateContext
(
)
;
ImGuiIO
&
io
=
ImGui
::
GetIO
(
)
;
(
void
)
io
;
io
.
IniFilename
=
NULL
;
io
.
ConfigFlags
|=
ImGuiConfigFlags_NavEnableKeyboard
;
io
.
Fonts
->
AddFontDefault
(
)
;
ImGui_ImplWin32_Init
(
window
)
;
ImGui_ImplDX9_Init
(
pDevice
)
;
initialized
=
true
;
return
;
}
HRESULT __stdcall
hkEndScene
(
IDirect3DDevice9
*
pDevice
)
{
if
(
!
initialized
)
InitImGui
(
pDevice
)
;
else
{
ImGui_ImplDX9_NewFrame
(
)
;
ImGui_ImplWin32_NewFrame
(
)
;
ImGui
::
NewFrame
(
)
;
ImGui
::
Render
(
)
;
ImGui_ImplDX9_RenderDrawData
(
ImGui
::
GetDrawData
(
)
)
;
}
return
oEndScene
(
pDevice
)
;
}
DWORD APIENTRY
MainThread
(
LPVOID lparam
)
{
while
(
!
GetModuleHandleA
(
"d3d9.dll"
)
)
//waiting till d3d9.dll gets loaded
{
Sleep
(
1
)
;
}
HWND  window
=
FindWindowA
(
NULL
,
"GTA: San Andreas"
)
;
// Endscene hook
void
*
*
vTableDevice
=
*
(
void
*
*
*
)
(
*
(
DWORD
*
)
0xC97C28
)
;
VTableHookManager
*
vmtHooks
=
new
VTableHookManager
(
vTableDevice
,
119
)
;
oEndScene
=
(
_EndScene
)
vmtHooks
->
Hook
(
42
,
(
void
*
)
hkEndScene
)
;
////////////////////////////////////////////////////////////////////////////////
return
false
;
}
BOOL APIENTRY
DllMain
(
HMODULE hModule
,
DWORD  ul_reason_for_call
,
LPVOID lpReserved
)
{
switch
(
ul_reason_for_call
)
{
case
DLL_PROCESS_ATTACH
:
CreateThread
(
0
,
0
,
MainThread
,
hModule
,
0
,
0
)
;
case
DLL_THREAD_ATTACH
:
case
DLL_THREAD_DETACH
:
case
DLL_PROCESS_DETACH
:
break
;
}
return
TRUE
;
}



Хм, большое спасибо, это правда работает)

Правда первый раз крашнуло, но я в енд сцене потом добавил EndRender и все заработало!

zTechnology 19.02.2022 15:18

Цитата:

Сообщение от ImmortalDev

Хм, большое спасибо, это правда работает)
Правда первый раз крашнуло, но я в енд сцене потом добавил EndRender и все заработало!

endframe не всегда нужен. Если у тебя нет чилда, хук будет крашить т.к. нет окна и нет endframe'a, если сделать:

C++:





Код:

HRESULT __stdcall
hkEndScene
(
IDirect3DDevice9
*
pDevice
)
{
if
(
!
initialized
)
InitImGui
(
pDevice
)
;
else
{
ImGui_ImplDX9_NewFrame
(
)
;
ImGui_ImplWin32_NewFrame
(
)
;
ImGui
::
NewFrame
(
)
;
ImGui
::
Begin
(
"test"
,
nullptr
)
;
{
}
ImGui
::
End
(
)
;
ImGui
::
Render
(
)
;
ImGui_ImplDX9_RenderDrawData
(
ImGui
::
GetDrawData
(
)
)
;
}
return
oEndScene
(
pDevice
)
;
}



то крашить не будет, а если сделать так:

C++:





Код:

HRESULT __stdcall
hkEndScene
(
IDirect3DDevice9
*
pDevice
)
{
if
(
!
initialized
)
InitImGui
(
pDevice
)
;
else
{
ImGui_ImplDX9_NewFrame
(
)
;
ImGui_ImplWin32_NewFrame
(
)
;
ImGui
::
NewFrame
(
)
;
ImGui
::
EndFrame
(
)
;
ImGui
::
Render
(
)
;
ImGui_ImplDX9_RenderDrawData
(
ImGui
::
GetDrawData
(
)
)
;
}
return
oEndScene
(
pDevice
)
;
}



то так тоже не будет, т.к. не рендерится окно, при рендере окна(begin) endframe не нужен

ImmortalDev 19.02.2022 18:09

Цитата:

Сообщение от zTechnology

endframe не всегда нужен. Если у тебя нет чилда, хук будет крашить т.к. нет окна и нет endframe'a, если сделать:

C++:





Код:

HRESULT __stdcall
hkEndScene
(
IDirect3DDevice9
*
pDevice
)
{
if
(
!
initialized
)
InitImGui
(
pDevice
)
;
else
{
ImGui_ImplDX9_NewFrame
(
)
;
ImGui_ImplWin32_NewFrame
(
)
;
ImGui
::
NewFrame
(
)
;
ImGui
::
Begin
(
"test"
,
nullptr
)
;
{
}
ImGui
::
End
(
)
;
ImGui
::
Render
(
)
;
ImGui_ImplDX9_RenderDrawData
(
ImGui
::
GetDrawData
(
)
)
;
}
return
oEndScene
(
pDevice
)
;
}



то крашить не будет, а если сделать так:

C++:





Код:

HRESULT __stdcall
hkEndScene
(
IDirect3DDevice9
*
pDevice
)
{
if
(
!
initialized
)
InitImGui
(
pDevice
)
;
else
{
ImGui_ImplDX9_NewFrame
(
)
;
ImGui_ImplWin32_NewFrame
(
)
;
ImGui
::
NewFrame
(
)
;
ImGui
::
EndFrame
(
)
;
ImGui
::
Render
(
)
;
ImGui_ImplDX9_RenderDrawData
(
ImGui
::
GetDrawData
(
)
)
;
}
return
oEndScene
(
pDevice
)
;
}



то так тоже не будет, т.к. не рендерится окно, при рендере окна(begin) endframe не нужен

Cпасибо тебе большое, но у меня к тебе еще один вопрос.

Как убрать захват мыши в игре, ну то есть, я нарисовал окно, но пододвинуть его/изменить не могу, т.к игра не дает.

zTechnology 19.02.2022 18:10

Цитата:

Сообщение от ImmortalDev

Cпасибо тебе большое, но у меня к тебе еще один вопрос.
Как убрать захват мыши в игре, ну то есть, я нарисовал окно, но пододвинуть его/изменить не могу, т.к игра не дает.

windproc ещё нужен вроде как

ImmortalDev 19.02.2022 19:29

Цитата:

Сообщение от zTechnology

windproc ещё нужен вроде как

Я создал

C++:





Код:

extern
IMGUI_IMPL_API LRESULT
ImGui_ImplWin32_WndProcHandler
(
HWND hWnd
,
UINT msg
,
WPARAM wParam
,
LPARAM lParam
)
;
typedef
LRESULT
(
CALLBACK
*
WNDPROC
)
(
HWND
,
UINT
,
WPARAM
,
LPARAM
)
;
LRESULT APIENTRY
WndProc
(
HWND hwnd
,
UINT uMsg
,
WPARAM wParam
,
LPARAM lParam
)
{
if
(
true
&&
ImGui_ImplWin32_WndProcHandler
(
hwnd
,
uMsg
,
wParam
,
lParam
)
)
return
true
;
return
CallWindowProc
(
oriWndProc
,
hwnd
,
uMsg
,
wParam
,
lParam
)
;
}



и вызываю его в MainThread

C++:





Код:

oriWndProc
=
(
WNDPROC
)
SetWindowLongPtr
(
window
,
GWL_WNDPROC
,
(
LONG_PTR
)
WndProc
)
;



Все ок, вроде не крашит, но каковы действия дальше? Нужно как то перехватывать нажатия? Что мне дальше делать с windproc?

zTechnology 19.02.2022 19:31

Цитата:

Сообщение от ImmortalDev

Я создал

C++:





Код:

extern
IMGUI_IMPL_API LRESULT
ImGui_ImplWin32_WndProcHandler
(
HWND hWnd
,
UINT msg
,
WPARAM wParam
,
LPARAM lParam
)
;
typedef
LRESULT
(
CALLBACK
*
WNDPROC
)
(
HWND
,
UINT
,
WPARAM
,
LPARAM
)
;
LRESULT APIENTRY
WndProc
(
HWND hwnd
,
UINT uMsg
,
WPARAM wParam
,
LPARAM lParam
)
{
if
(
true
&&
ImGui_ImplWin32_WndProcHandler
(
hwnd
,
uMsg
,
wParam
,
lParam
)
)
return
true
;
return
CallWindowProc
(
oriWndProc
,
hwnd
,
uMsg
,
wParam
,
lParam
)
;
}



и вызываю его в MainThread

C++:





Код:

oriWndProc
=
(
WNDPROC
)
SetWindowLongPtr
(
window
,
GWL_WNDPROC
,
(
LONG_PTR
)
WndProc
)
;



Все ок, вроде не крашит, но каковы действия дальше? Нужно как то перехватывать нажатия? Что мне дальше делать с windproc?

C++:





Код:

extern
IMGUI_IMPL_API LRESULT
ImGui_ImplWin32_WndProcHandler
(
HWND hWnd
,
UINT msg
,
WPARAM wParam
,
LPARAM lParam
)
;
typedef
LRESULT
(
CALLBACK
*
WNDPROC
)
(
HWND
,
UINT
,
WPARAM
,
LPARAM
)
;
LRESULT APIENTRY
WndProc
(
HWND hwnd
,
UINT uMsg
,
WPARAM wParam
,
LPARAM lParam
)
{
if
(
true
&&
ImGui_ImplWin32_WndProcHandler
(
hwnd
,
uMsg
,
wParam
,
lParam
)
)
return
true
;
switch
(
uMsg
)
{
case
WM_LBUTTONDOWN
:
case
WM_LBUTTONDBLCLK
:
case
WM_RBUTTONDOWN
:
case
WM_RBUTTONDBLCLK
:
case
WM_MBUTTONDOWN
:
case
WM_MBUTTONDBLCLK
:
case
WM_XBUTTONDOWN
:
case
WM_XBUTTONDBLCLK
:
case
WM_MOUSEWHEEL
:
case
WM_LBUTTONUP
:
case
WM_RBUTTONUP
:
case
WM_MBUTTONUP
:
case
WM_XBUTTONUP
:
case
WM_MOUSEMOVE
:
return
true
;
}
return
CallWindowProc
(
oriWndProc
,
hwnd
,
uMsg
,
wParam
,
lParam
)
;
}


ImmortalDev 19.02.2022 20:07

Цитата:

Сообщение от zTechnology

C++:





Код:

extern
IMGUI_IMPL_API LRESULT
ImGui_ImplWin32_WndProcHandler
(
HWND hWnd
,
UINT msg
,
WPARAM wParam
,
LPARAM lParam
)
;
typedef
LRESULT
(
CALLBACK
*
WNDPROC
)
(
HWND
,
UINT
,
WPARAM
,
LPARAM
)
;
LRESULT APIENTRY
WndProc
(
HWND hwnd
,
UINT uMsg
,
WPARAM wParam
,
LPARAM lParam
)
{
if
(
true
&&
ImGui_ImplWin32_WndProcHandler
(
hwnd
,
uMsg
,
wParam
,
lParam
)
)
return
true
;
switch
(
uMsg
)
{
case
WM_LBUTTONDOWN
:
case
WM_LBUTTONDBLCLK
:
case
WM_RBUTTONDOWN
:
case
WM_RBUTTONDBLCLK
:
case
WM_MBUTTONDOWN
:
case
WM_MBUTTONDBLCLK
:
case
WM_XBUTTONDOWN
:
case
WM_XBUTTONDBLCLK
:
case
WM_MOUSEWHEEL
:
case
WM_LBUTTONUP
:
case
WM_RBUTTONUP
:
case
WM_MBUTTONUP
:
case
WM_XBUTTONUP
:
case
WM_MOUSEMOVE
:
return
true
;
}
return
CallWindowProc
(
oriWndProc
,
hwnd
,
uMsg
,
wParam
,
lParam
)
;
}



Написал вот такой обработчик, но, все равно не работает.

C++:





[CODE]
if
(
true
&&
ImGui_ImplWin32_WndProcHandler
(
hwnd
,
uMsg
,
wParam
,
lParam
)
)
return
true
;
ImGuiIO
&
io
=
ImGui
::
GetIO
(
)
;
switch
(
uMsg
)
{
case
WM_LBUTTONDOWN
:
io
.
MouseDown
[
0
]
=
true
;
return
true
;
case
WM_LBUTTONUP
:
io
.
MouseDown
[
0
]
=
false
;
return
true
;
case
WM_RBUTTONDOWN
:
io
.
MouseDown
[
1
]
=
true
;
return
true
;
case
WM_RBUTTONUP
:
io
.
MouseDown
[
1
]
=
false
;
return
true
;
case
WM_MBUTTONDOWN
:
io
.
MouseDown
[
2
]
=
true
;
return
true
;
case
WM_MBUTTONUP
:
io
.
MouseDown
[
2
]
=
false
;
return
true
;
case
WM_MOUSEWHEEL
:
io
.
MouseWheel
+=
GET_WHEEL_DELTA_WPARAM
(
wParam
)
>
0
?
+
1.0f
:
-
1.0f
;
return
true
;
case
WM_MOUSEMOVE
:
io
.
MousePos
.
x
=
(
signed
short
)
(
lParam
)
;
io
.
MousePos
.
y
=
(
signed
short
)
(
lParam
>>
16
)
;
return
true
;
case
WM_KEYDOWN
:
if
(
wParam

0
&&
wParam



Время: 08:54