 |

02.03.2021, 13:10
|
|
Постоянный
Регистрация: 26.03.2016
Сообщений: 660
С нами:
5332594
Репутация:
163
|
|
Всем привет, в данном гайде расскажу как хукнуть рендер warface (directx9 version) с помощью re_virtualtable. Проект у вас уже должен быть готов (dll, x64). Берём классы(спасибо @atizoff) и закидываем в проект. Оффсеты в классах старые, поэтому нужно их обновить. На момент этого гайда (02.03.2021) валидные оффсеты:
C++:
Код:
SSystemGlobalEnvironment
=
0x141E2E880
GetIRenderer
=
0x48
GetDirectDevice
=
0xA770
Далее нам понадобится заинклюдить классы, и библиотеку thread для создания потока. Теперь приступаем к коду! Первым делом создаём поток в точке входа:
C++:
Код:
class
clEntry
{
std
::
thread thread
;
public
:
clEntry
(
)
{
thread
=
std
::
thread
(
[
]
(
)
{
// тут будет наш дальнейший код
}
)
;
}
}
entry
;
В данном случае я использую класс в качестве точки входа. Конструктор класса вызовется при загрзуке модуля в игру, так как мы сразу же создаём объект класса после объявления его самого. Настало время re_virtualtable, качаем его из репозитория и инклюдим. Ну и наконец-то ебашим хук! Создаём экземпляр хука:
C++:
Код:
clVirtualTable
presentHook
;
Перед как ставить хук создадим функцию которая будет его обрабатывать:
C++:
Код:
HRESULT __stdcall
presentHooked
(
IDirect3DDevice9
*
pDevice
,
const
RECT
*
pSourceRect
,
const
RECT
*
pDestRect
,
HWND hDestWindowOverride
,
const
RGNDATA
*
pDirtyRegion
)
{
}
Но это не будет работать правильно, если мы не вызовем оригинальную функцию, поэтому добавляем вызов оригинала в нашу функцию обработчик:
C++:
Код:
return
presentHook
.
call
(
eConvention
::
stdcall
,
pDevice
,
pSourceRect
,
pDestRect
,
hDestWindowOverride
,
pDirtyRegion
)
;
В нашем созданном потоке ждём инициализации SSystemGlobalEnvironment и ставим хук:
C++:
Код:
if
(
!
SSystemGlobalEnvironment
::
Singleton
(
)
)
std
::
this_thread
::
sleep_for
(
std
::
chrono
::
milliseconds
(
100
)
)
;
LPDIRECT3DDEVICE9 pDevice
=
SSystemGlobalEnvironment
::
Singleton
(
)
->
GetIRenderer
(
)
->
GetDirectDevice
(
)
;
LPVOID pInterface
=
*
reinterpret_cast
(
&
pDevice
)
;
presentHook
.
install
(
pDevice
,
17
,
&
presentHooked
)
;
Стоит учесть, что в классах @atizoff возвращаемое значение метода GetDirectDevice - DWORD64, поэтому в классах поменяем его на LPDIRECT3DDEVICE9.
Поскольку там ебанутейший каст, просто оставлю вам это:
C++:
Код:
LPDIRECT3DDEVICE9
GetDirectDevice
(
)
{
return
*
reinterpret_cast
(
this
+
0xA770
)
;
}
Готово! Хук установлен и осталось только проверить его работоспособность, для этого мы рендерим квадрат с помощью данной функции (спасибо @CleanLegend):
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
)
;
}
И всё прекрасно работает:

|
|
|

02.03.2021, 15:49
|
|
Познавший АНТИЧАТ
Регистрация: 02.08.2018
Сообщений: 1,295
С нами:
4095395
Репутация:
183
|
|
Сообщение от RECEIVER
if (!SSystemGlobalEnvironment::Singleton()) std::this_thread::sleep_for(std::chrono::milliseco nds(100)); LPDIRECT3DDEVICE9 pDevice = SSystemGlobalEnvironment::Singleton()->GetIRenderer()->GetDirectDevice(); LPVOID pInterface = *reinterpret_cast(&pDevice); presentHook.install(pDevice, 17, &presentHooked);
C++:
Код:
if
(
SSystemGlobalEnvironment
::
Singleton
(
)
)
{
LPDIRECT3DDEVICE9 pDevice
=
SSystemGlobalEnvironment
::
Singleton
(
)
->
GetIRenderer
(
)
->
GetDirectDevice
(
)
;
LPVOID pInterface
=
*
reinterpret_cast
(
&
pDevice
)
;
presentHook
.
install
(
pDevice
,
17
,
&
presentHooked
)
;
}
и не надо потоки вызывать. а так конкретно этот класс на пустоту проверять бесполезно, он всегда наполнен. в такой проверке науждаются лишь IGameFramework, ICVar (SCVars) (из распрастраннёных), тем не менее отличный гайд!
|
|
|
|
 |
|
Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
|
|
|
|