void VMTHook::Set(ptr_t inst, uint32_t offset) { Release(); vtable_ptr = &GetVMT(inst, offset); vtable_original = *vtable_ptr; int mc = CountMethods(vtable_original); logging::Info("Hooking vtable 0x%08x with %d methods", vtable_original, mc); vtable_hooked = static_cast<method_table_t>(calloc(mc + 3, sizeof(ptr_t))); memcpy(&vtable_hooked[2], vtable_original, sizeof(ptr_t) * mc); vtable_hooked[0] = this; vtable_hooked[1] = (void *) GUARD; }
bool CTask::MakeAbortable(class CPed *ped, int priority, class CEvent *_event) { return ((bool (__thiscall *)(CTask *, int, class CEvent *))GetVMT(this, 6))(this, priority, _event); }
void CTask::StopTimer(class CEvent *_event) { ((void (__thiscall *)(CTask *, class CEvent *))GetVMT(this, 5))(this, _event); }
eTaskType CTask::GetId() { return ((eTaskType (__thiscall *)(CTask *))GetVMT(this, 4))(this); }
bool CTask::IsSimple() { return ((bool (__thiscall *)(CTask *))GetVMT(this, 3))(this); }
CTask *CTask::GetSubTask() { return ((CTask *(__thiscall *)(CTask *))GetVMT(this, 2))(this); }
CTask *CTask::Clone() { return ((CTask *(__thiscall *)(CTask *))GetVMT(this, 1))(this); }
bool IsHooked(ptr_t inst, uint32_t offset) { return GetVMT(inst, offset)[-1] == (method_t) GUARD; }