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