ANTICHAT

ANTICHAT (https://forum.antichat.xyz/index.php)
-   С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby (https://forum.antichat.xyz/forumdisplay.php?f=24)
-   -   [ASI] Хукаем d3d9 (https://forum.antichat.xyz/showthread.php?t=1332712)

CleanLegend 07.04.2019 23:56

Привет. Сегодня разберем как хукать d3d9 для рисования квадратов или своего меню.​

Что нам нужно хукануть для полноценного рисования?

- Present/EndScene (Вывод на экран информации)

- Reset (Перезагрузка интерфейса)

Подключаем заголовки:

C++:





Код:

#include
#include
#include
#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "d3dx9.lib")



Создаем прототип и экземпляр:

C++:





Код:

typedef
HRESULT
(
WINAPI
*
_EndScene
)
(
IDirect3DDevice9
*
)
;
//прототип
_EndScene oEndScene
;
//экземпляр прототипа, для возврата оригинала
typedef
HRESULT
(
WINAPI
*
_Reset
)
(
IDirect3DDevice9
*
,
D3DPRESENT_PARAMETERS
*
)
;
_Reset oReset
;



Функции подмены:

C++:





Код:

HRESULT WINAPI
myEndScene
(
IDirect3DDevice9
*
m_pDevice
)
{
return
oEndScene
(
m_pDevice
)
;
// возврат оригинала
}
HRESULT WINAPI
myReset
(
IDirect3DDevice9
*
m_pDevice
,
D3DPRESENT_PARAMETERS
*
pPresentationParameters
)
{
auto
result
=
oReset
(
m_pDevice
,
pPresentationParameters
)
;
return
result
;
}



Функция хука:

C++:





Код:

void
InitHook
(
)
{
void
*
*
vTableDevice
=
*
(
void
*
*
*
)
(
*
(
DWORD
*
)
0xC97C28
)
;
// адрес Device
VMTHookManager
*
vmtHooks
=
new
VMTHookManager
(
vTableDevice
)
;
oEndScene
=
(
_EndScene
)
vmtHooks
->
Hook
(
42
,
(
void
*
)
myEndScene
)
;
// 42 - номер EndScene
oReset
=
(
_Reset
)
vmtHooks
->
Hook
(
16
,
(
void
*
)
myReset
)
;
// 16 - номер Reset
}



В точке входа создаем поток и в нем вызываем хук:

C++:





Код:

int
WINAPI
Thread
(
)
{
while
(
*
(
DWORD
*
)
0xC8D4C0
!=
9
)
// проверка на статус загрузки игры
Sleep
(
100
)
;
InitHook
(
)
;
return
0
;
}
BOOL WINAPI
DllMain
(
HMODULE hModule
,
DWORD dwReason
,
LPVOID lpReserved
)
{
if
(
dwReason
==
DLL_PROCESS_ATTACH
)
CreateThread
(
NULL
,
NULL
,
(
LPTHREAD_START_ROUTINE
)
Thread
,
NULL
,
NULL
,
NULL
)
;
return
TRUE
;
}



Пример для тестирования:

C++:





Код:

void
DrawRect
(
LPDIRECT3DDEVICE9 m_pDevice
,
int
X
,
int
Y
,
int
L
,
int
H
,
D3DCOLOR color
)
{
D3DRECT rect
=
{
X
,
Y
,
X
+
L
,
Y
+
H
}
;
m_pDevice
->
Clear
(
1
,
&
rect
,
D3DCLEAR_TARGET
,
color
,
0
,
0
)
;
}
HRESULT WINAPI
myEndScene
(
IDirect3DDevice9
*
m_pDevice
)
{
DrawRect
(
m_pDevice
,
250
,
250
,
10
,
10
,
0xFFFF0000
)
;
return
oEndScene
(
m_pDevice
)
;
}



Получаем:

https://i.imgur.com/qAEN8Gn.png

Класс VMTHookManager

Цитата:

Сообщение от Спойлер


C++:





[CODE]
VMTHookManager
::
VMTHookManager
(
void
*
*
vTable
)
:
m_vTable
(
vTable
)
{
m_numberFuncs
=
GetNumberOfFunctions
(
)
;
//getting the number of virtual functions
m_originalFuncs
=
new
void
*
[
m_numberFuncs
]
;
// allocating memory so we can save here the addresses of the original functions
for
(
unsigned
short
i
=
0
;
i

(
bufferOriginalFunc
)
;
//worked, return the original address
}
bool
VMTHookManager
::
Unhook
(
unsigned
short
index
)
{
if
(
!
toHook
(
index
)
)
// checking if it failed
{
return
false
;
// return false, didn't work
}
return
true
;
// return true, worked
}
void
VMTHookManager
::
UnhookAll
(
)
{
for
(
int
index
=
0
;
index




Цитата:

Сообщение от Спойлер


C++:





Код:

class
VMTHookManager
{
public
:
VMTHookManager
(
void
*
*
vTable
)
;
//constructor
~
VMTHookManager
(
)
;
//destructor
void
*
GetFunctionAddyByIndex
(
unsigned
short
index
)
;
// getting the address of a function in the vtable by index
void
*
Hook
(
unsigned
short
index
,
void
*
ourFunction
)
;
// hooking the virtual function by index
bool
Unhook
(
unsigned
short
index
)
;
// unhooking the virtual function by index
void
UnhookAll
(
)
;
//unhook all the functions
private
:
//member variables
void
*
*
m_vTable
;
// the vtable of some object
unsigned
short
m_numberFuncs
;
// number of virtual functions
void
*
*
m_originalFuncs
=
nullptr
;
// we'll save the original addresses here
unsigned
short
GetNumberOfFunctions
(
)
;
//get the number of virtual functions
bool
toHook
(
unsigned
short
index
,
bool
hook
=
false
,
void
*
ourFunction
=
nullptr
,
uintptr_t
*
bufferOriginalFunc
=
nullptr
)
;
//function used to hook/unhook
}
;





rraggerr 08.04.2019 05:48

Present:

C++:





Код:

typedef
HRESULT
(
WINAPI
*
_Present
)
(
IDirect3DDevice9
*
,
const
RECT
*
,
const
RECT
*
,
HWND
,
const
RGNDATA
*
)
;
//прототип
_Present oPresent
;
//экземпляр прототипа, для возврата оригинала
HRESULT WINAPI
hooked_Present
(
IDirect3DDevice9
*
pDevice
,
const
RECT
*
pSourceRect
,
const
RECT
*
pDestRect
,
HWND hdest
,
const
RGNDATA
*
pDirtyRegion
)
{
return
oPresent
(
pDevice
,
pSourceRect
,
pDestRect
,
hdest
,
RGNDATA
,
pDirtyRegion
)
;
// возврат оригинала
}
oPresent
=
(
_Present
)
vmtHooks
->
Hook
(
17
,
(
void
*
)
hooked_Present
)
;


deropleat 08.04.2019 06:46

Немного другой хук, который не требует очистки девайса под итог.

VMTHook.h

C++:





Код:

#pragma once
#include
#include
#include
#include
class
VMTHook
{
private
:
std
::
uintptr_t
*
*
BaseClass
=
nullptr
;
std
::
unique_ptr

CurrentVTF
=
nullptr
;
std
::
uintptr_t
*
OriginalVTF
=
nullptr
;
std
::
size_t TotalFuncs
=
0
;
public
:
VMTHook
(
void
)
=
default
;
VMTHook
(
void
*
BaseClass
)
{
this
->
BaseClass
=
static_cast

(
BaseClass
)
;
while
(
static_cast

(
*
this
->
BaseClass
)
[
this
->
TotalFuncs
]
)
++
this
->
TotalFuncs
;
const
std
::
size_t TableSize
=
this
->
TotalFuncs
*
sizeof
(
std
::
uintptr_t
)
;
this
->
OriginalVTF
=
*
this
->
BaseClass
;
this
->
CurrentVTF
=
std
::
make_unique

(
this
->
TotalFuncs
)
;
std
::
memcpy
(
this
->
CurrentVTF
.
get
(
)
,
this
->
OriginalVTF
,
TableSize
)
;
*
this
->
BaseClass
=
this
->
CurrentVTF
.
get
(
)
;
}
;
~
VMTHook
(
)
{
*
this
->
BaseClass
=
this
->
OriginalVTF
;
}
;
template

inline
const
Fn
GetOrigIndex
(
std
::
size_t FunctionIndex
)
{
return
reinterpret_cast

(
this
->
OriginalVTF
[
FunctionIndex
]
)
;
}
inline
bool
TableIndexHook
(
void
*
new_function
,
const
std
::
size_t FunctionIndex
)
{
if
(
FunctionIndex
>
this
->
TotalFuncs
)
return
false
;
this
->
CurrentVTF
[
FunctionIndex
]
=
reinterpret_cast

(
new_function
)
;
return
true
;
}
inline
bool
TableIndexUnHook
(
const
std
::
size_t FunctionIndex
)
{
if
(
FunctionIndex
>
this
->
TotalFuncs
)
return
false
;
this
->
CurrentVTF
[
FunctionIndex
]
=
this
->
OriginalVTF
[
FunctionIndex
]
;
return
true
;
}
inline
std
::
size_t
GetMaxIndex
(
)
{
return
this
->
TotalFuncs
;
}
}
;



Hooks.cpp

C++:





Код:

using
PresentFn
=
long
(
__stdcall
*
)
(
IDirect3DDevice9
*
,
const
RECT
*
,
const
RECT
*
,
HWND
,
const
RGNDATA
*
)
;
long
__stdcall g_pHooks
::
Present
(
IDirect3DDevice9
*
pDevice
,
const
RECT
*
pSourceRect
,
const
RECT
*
pDestRect
,
HWND hDestWindowOverride
,
const
RGNDATA
*
pDirtyRegion
)
{
static
auto
OriginalFunc
=
MyDevice
->
GetOrigIndex

(
17
)
;
if
(
!
init
)
g_pRender
->
Init
(
pDevice
,
init
)
;
g_pRender
->
PaintBegin
(
)
;
g_pRender
->
SizeReset
(
)
;
pDevice
->
SetRenderState
(
D3DRS_SRGBWRITEENABLE
,
false
)
;
g_pMenu
->
MyDevice
=
pDevice
;
g_pMenu
->
Update
(
)
;
return
OriginalFunc
(
pDevice
,
pSourceRect
,
pDestRect
,
hDestWindowOverride
,
pDirtyRegion
)
;
}



Render.cpp

C++:





Код:

void
CRender
::
Line
(
int
sX
,
int
sY
,
int
eX
,
int
eY
,
D3DCOLOR D3DCOLOR
)
{
vertex pVertex
[
2
]
=
{
{
sX
,
sY
,
0.0f
,
1.0f
,
D3DCOLOR
}
,
{
eX
,
eY
,
0.0f
,
1.0f
,
D3DCOLOR
}
}
;
MyDevice
->
SetRenderState
(
D3DRS_LIGHTING
,
FALSE
)
;
MyDevice
->
SetRenderState
(
D3DRS_ZENABLE
,
D3DZB_FALSE
)
;
MyDevice
->
SetRenderState
(
D3DRS_FOGENABLE
,
FALSE
)
;
MyDevice
->
SetRenderState
(
D3DRS_CULLMODE
,
D3DCULL_NONE
)
;
MyDevice
->
SetRenderState
(
D3DRS_ALPHABLENDENABLE
,
TRUE
)
;
MyDevice
->
SetRenderState
(
D3DRS_SRCBLEND
,
D3DBLEND_SRCALPHA
)
;
MyDevice
->
SetRenderState
(
D3DRS_DESTBLEND
,
D3DBLEND_INVSRCALPHA
)
;
MyDevice
->
SetRenderState
(
D3DRS_LIGHTING
,
FALSE
)
;
MyDevice
->
SetRenderState
(
D3DRS_STENCILENABLE
,
FALSE
)
;
MyDevice
->
SetTexture
(
0
,
NULL
)
;
MyDevice
->
SetPixelShader
(
NULL
)
;
MyDevice
->
SetFVF
(
D3DFVF_XYZRHW
|
D3DFVF_DIFFUSE
|
D3DFVF_TEX1
)
;
MyDevice
->
DrawPrimitiveUP
(
D3DPT_LINELIST
,
1
,
&
pVertex
,
sizeof
(
vertex
)
)
;
}



48BRHEEGO_4.jpgderopleat · 8 Апр 2019 в 05:46' data-fancybox="lb-post-323608" data-lb-caption-extra-html="" data-lb-sidebar-href="" data-single-image="1" data-src="/proxy.php?image=https%3A%2F%2Fpp.userapi.com%2Fc85 0524%2Fv850524518%2Ff4913%2F48BRHEEGO_4.jpg&hash=8 7c49eff87663a7fd396f76b793a072a" style="cursor: pointer;" title="48BRHEEGO_4.jpg">
https://pp.userapi.com/c850524/v8505...8BRHEEGO_4.jpg

Musaigen 15.02.2020 14:14

Цитата:

Сообщение от Mozze.cpp

Без MoonLoader'a не работает :/

Делай как в собейте, через прокси-либу.

loganhackerdff 26.04.2020 00:35

Если я сделаю через хук, на фрапсе будет видно? дарк говорит что если хукать то не будет

BASS_DEVSOFTWARE 26.04.2020 00:45

Цитата:

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

Если я сделаю через хук, на фрапсе будет видно? дарк говорит что если хукать то не будет

Нах тогда спрашивать?

loganhackerdff 26.04.2020 01:06

Цитата:

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

Нах тогда спрашивать?

А вдруг он не шарит

deropleat 21.05.2020 20:45

Цитата:

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

Немного другой хук, который не требует очистки девайса под итог.

VMTHook.h

C++:





Код:

#pragma once
#include
#include
#include
#include
class
VMTHook
{
private
:
std
::
uintptr_t
*
*
BaseClass
=
nullptr
;
std
::
unique_ptr

CurrentVTF
=
nullptr
;
std
::
uintptr_t
*
OriginalVTF
=
nullptr
;
std
::
size_t TotalFuncs
=
0
;
public
:
VMTHook
(
void
)
=
default
;
VMTHook
(
void
*
BaseClass
)
{
this
->
BaseClass
=
static_cast

(
BaseClass
)
;
while
(
static_cast

(
*
this
->
BaseClass
)
[
this
->
TotalFuncs
]
)
++
this
->
TotalFuncs
;
const
std
::
size_t TableSize
=
this
->
TotalFuncs
*
sizeof
(
std
::
uintptr_t
)
;
this
->
OriginalVTF
=
*
this
->
BaseClass
;
this
->
CurrentVTF
=
std
::
make_unique

(
this
->
TotalFuncs
)
;
std
::
memcpy
(
this
->
CurrentVTF
.
get
(
)
,
this
->
OriginalVTF
,
TableSize
)
;
*
this
->
BaseClass
=
this
->
CurrentVTF
.
get
(
)
;
}
;
~
VMTHook
(
)
{
*
this
->
BaseClass
=
this
->
OriginalVTF
;
}
;
template

inline
const
Fn
GetOrigIndex
(
std
::
size_t FunctionIndex
)
{
return
reinterpret_cast

(
this
->
OriginalVTF
[
FunctionIndex
]
)
;
}
inline
bool
TableIndexHook
(
void
*
new_function
,
const
std
::
size_t FunctionIndex
)
{
if
(
FunctionIndex
>
this
->
TotalFuncs
)
return
false
;
this
->
CurrentVTF
[
FunctionIndex
]
=
reinterpret_cast

(
new_function
)
;
return
true
;
}
inline
bool
TableIndexUnHook
(
const
std
::
size_t FunctionIndex
)
{
if
(
FunctionIndex
>
this
->
TotalFuncs
)
return
false
;
this
->
CurrentVTF
[
FunctionIndex
]
=
this
->
OriginalVTF
[
FunctionIndex
]
;
return
true
;
}
inline
std
::
size_t
GetMaxIndex
(
)
{
return
this
->
TotalFuncs
;
}
}
;



Hooks.cpp

C++:





Код:

using
PresentFn
=
long
(
__stdcall
*
)
(
IDirect3DDevice9
*
,
const
RECT
*
,
const
RECT
*
,
HWND
,
const
RGNDATA
*
)
;
long
__stdcall g_pHooks
::
Present
(
IDirect3DDevice9
*
pDevice
,
const
RECT
*
pSourceRect
,
const
RECT
*
pDestRect
,
HWND hDestWindowOverride
,
const
RGNDATA
*
pDirtyRegion
)
{
static
auto
OriginalFunc
=
MyDevice
->
GetOrigIndex

(
17
)
;
if
(
!
init
)
g_pRender
->
Init
(
pDevice
,
init
)
;
g_pRender
->
PaintBegin
(
)
;
g_pRender
->
SizeReset
(
)
;
pDevice
->
SetRenderState
(
D3DRS_SRGBWRITEENABLE
,
false
)
;
g_pMenu
->
MyDevice
=
pDevice
;
g_pMenu
->
Update
(
)
;
return
OriginalFunc
(
pDevice
,
pSourceRect
,
pDestRect
,
hDestWindowOverride
,
pDirtyRegion
)
;
}



Render.cpp

C++:





Код:

void
CRender
::
Line
(
int
sX
,
int
sY
,
int
eX
,
int
eY
,
D3DCOLOR D3DCOLOR
)
{
vertex pVertex
[
2
]
=
{
{
sX
,
sY
,
0.0f
,
1.0f
,
D3DCOLOR
}
,
{
eX
,
eY
,
0.0f
,
1.0f
,
D3DCOLOR
}
}
;
MyDevice
->
SetRenderState
(
D3DRS_LIGHTING
,
FALSE
)
;
MyDevice
->
SetRenderState
(
D3DRS_ZENABLE
,
D3DZB_FALSE
)
;
MyDevice
->
SetRenderState
(
D3DRS_FOGENABLE
,
FALSE
)
;
MyDevice
->
SetRenderState
(
D3DRS_CULLMODE
,
D3DCULL_NONE
)
;
MyDevice
->
SetRenderState
(
D3DRS_ALPHABLENDENABLE
,
TRUE
)
;
MyDevice
->
SetRenderState
(
D3DRS_SRCBLEND
,
D3DBLEND_SRCALPHA
)
;
MyDevice
->
SetRenderState
(
D3DRS_DESTBLEND
,
D3DBLEND_INVSRCALPHA
)
;
MyDevice
->
SetRenderState
(
D3DRS_LIGHTING
,
FALSE
)
;
MyDevice
->
SetRenderState
(
D3DRS_STENCILENABLE
,
FALSE
)
;
MyDevice
->
SetTexture
(
0
,
NULL
)
;
MyDevice
->
SetPixelShader
(
NULL
)
;
MyDevice
->
SetFVF
(
D3DFVF_XYZRHW
|
D3DFVF_DIFFUSE
|
D3DFVF_TEX1
)
;
MyDevice
->
DrawPrimitiveUP
(
D3DPT_LINELIST
,
1
,
&
pVertex
,
sizeof
(
vertex
)
)
;
}



https://pp.userapi.com/c850524/v8505...8BRHEEGO_4.jpg

Решил недавно возобновить свой проект этого рода и стокнулся как раз с проблемой которая изображена на скриншоте - меню рисуется под чатом. Возможно то, что большинство в курсе решения данной проблемы, но все-таки считаю нужным поделиться, мало ли.

Эта проблема возникает исключительно в том случае, если меню было внедрено в игру после прохождения загрузочного окна GTA. Если внедрить в момент самой загрузки, то подобного бага не будет.

Цитата:

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

Если я сделаю через хук, на фрапсе будет видно? дарк говорит что если хукать то не будет

Насколько я знаю, то это зависит от того, что ты будешь хукать.
  • EndScene - не обходит OBS.
  • Present - обходит OBS.
Однако оба хука будут видны на скриншотах. Не проверял на самом деле подлинность информации, но в некоторых играх это действительно так, и думаю, что гташка - не исключение.

Цитата:

Сообщение от Mozze.cpp

Без MoonLoader'a не работает :/

Если в чите присутствуют функции связанные с данной библиотекой - тогда все ясно. Если же ты говоришь конкретно про меню (чистое, без любого СДК) - то такого быть не может. Рисуя подобным образом ты используешь лишь стандартный набор функций директа, которые автоматически доступны за счет использования d3d9 игрой.

И если ты используешь данную библиотеку, то лучше откажись от неё. Для подобного рода читов более уместно будет использовать СДК от собейта. Однако, все зависит от того, какую цель ты ставишь на свой проект. Выпустить чит независящий от чего-либо (СДК собейта) или же аналог каким-то асишкам, сфшкам итп (с СФ, МЛ).

testuser 28.06.2020 02:28

Крашит при выгрузке плагина / выходе из игры. Как пофиксить?

vmprotect 18.12.2022 14:22

cef интерфейс можно вывести через хук ?


Время: 18:46