Я пытаюсь использовать WinAppDbg для написания плагинов для игры, которая включает в себя перехват и вызов существующих функций в этой игре. После некоторого реверс-инжиниринга я получил RVA и подписи некоторых целевых функций или методов класса. Но вскоре я обнаружил, что документ WinAppDbg только говорит мне, как перехватывать существующие функции, а не вызывать их. Кроме того, обычно адрес целевой функции получается из Process.resolve_label, но у меня есть только RVA. Как я могу подключить функцию с ее RVA? Спасибо!
------------------ Обновление 1 ---------------------- -
Чтобы прояснить, что я пытаюсь сделать, рассмотрим следующий случай:
Существует метод класса с именем bool Player::attack(this, Animal *some_animal)
в some_game.exe
, который будет вызываться когда я нападаю на любое животное. Я хочу отслеживать событие атаки и, возможно, имитировать / инициировать событие атаки, когда захочу.
После изучения файла some_game.pdb я выяснил, что RVA целевой функции, т.е. Player::attack
0x00678840
. И я сделал myplugin.dll
файл, который будет вставлен в процессе игры.
Тогда довольно просто вызвать эту функцию в myplugin.dll
, как это
#include <windows.h>
auto module_addr = reinterpret_cast<unsigned int>(GetModuleHandle(NULL));
attack_func = reinterpret_cast<void(*)(void*, void*)>(0x00678840+module_addr);
attack_func(...)
И перехват также довольно просто с помощью библиотеки Microsoft Detours , сначала определив функцию вспомогательного хука void RegisterStaticHook(RVA sym, void* hook, void** org);
:
#include <windows.h>
// Detours
#include <detours/detours.h>
typedef uint64_t VA;
typedef unsigned int RVA;
template<typename Type>
using Ptr = Type*;
enum class HookErrorCode {
ERR_SUCCESS,
ERR_TRANSACTION_BEGIN,
ERR_UPDATE_THREAD,
ERR_ATTACH,
ERR_DETACH,
ERR_TRANSACTION_COMMIT
};
template<typename T = Ptr<void>>
auto Hook(Ptr<T> p, T f) {
int error = DetourTransactionBegin();
if (error != NO_ERROR) {
return HookErrorCode::ERR_TRANSACTION_BEGIN;
}
error = DetourUpdateThread(GetCurrentThread());
if (error != NO_ERROR) {
return HookErrorCode::ERR_UPDATE_THREAD;
}
error = DetourAttach(
reinterpret_cast<Ptr<PVOID>>(p),
reinterpret_cast<PVOID>(f)
);
if (error != NO_ERROR) {
return HookErrorCode::ERR_ATTACH;
}
error = DetourTransactionCommit();
if (error != NO_ERROR) {
return HookErrorCode::ERR_TRANSACTION_COMMIT;
}
return HookErrorCode::ERR_SUCCESS;
}
void RegisterStaticHook(RVA sym, void* hook, void** org) {
auto base = reinterpret_cast<VA>(GetModuleHandle(NULL));
*org = reinterpret_cast<void*>(base + sym);
auto ret = Hook<void*>(org, hook);
if (ret != HookErrorCode::ERR_SUCCESS) {
std::cout << "[Error] ";
switch (ret) {
case HookErrorCode::ERR_TRANSACTION_BEGIN:
std::cout << "DetourTransactionBegin";
break;
case HookErrorCode::ERR_UPDATE_THREAD:
std::cout << "DetourUpdateThread";
break;
case HookErrorCode::ERR_ATTACH:
std::cout << "DetourAttach";
break;
case HookErrorCode::ERR_DETACH:
std::cout << "DetourDetach";
break;
case HookErrorCode::ERR_TRANSACTION_COMMIT:
std::cout << "DetourTransactionCommit";
break;
default:
break;
}
std::cout << "failed!" << std::endl;
}
}
, затем перехват my_attack
с помощью RegisterStaticHook, как это:
void** org;
bool my_attack(void* player_this, void* animal){
...
}
RegisterStaticHook(0x00678840, my_attack, org);
У меня вопрос, как это сделать с WinAppDbg.