152 lines
2.4 KiB
C++
152 lines
2.4 KiB
C++
#include "hook.h"
|
|
#include "MinHook.h"
|
|
|
|
Hook* Hook::s_pFirst = NULL;
|
|
Hook* Hook::s_pLast = NULL;
|
|
|
|
void Hook::Init()
|
|
{
|
|
MH_Initialize();
|
|
}
|
|
|
|
void Hook::Exit()
|
|
{
|
|
UnHookAll();
|
|
MH_Uninitialize();
|
|
}
|
|
|
|
void Hook::UnHookAll()
|
|
{
|
|
Hook* pItem = s_pFirst;
|
|
if (pItem)
|
|
{
|
|
Hook* pNext;
|
|
do {
|
|
pNext = pItem->m_pNext;
|
|
|
|
pItem->DoUnHook();
|
|
} while (pItem = pNext);
|
|
}
|
|
|
|
s_pFirst = NULL;
|
|
s_pLast = NULL;
|
|
}
|
|
|
|
void Hook::DoHook()
|
|
{
|
|
m_pPrev = s_pLast;
|
|
|
|
if (!s_pFirst) s_pFirst = this;
|
|
if (s_pLast) s_pLast->m_pNext = this;
|
|
|
|
s_pLast = this;
|
|
//Delete!
|
|
delete this;
|
|
}
|
|
|
|
void Hook::DoUnHook()
|
|
{
|
|
if (m_pPrev) m_pPrev->m_pNext = m_pNext;
|
|
if (m_pNext) m_pNext->m_pPrev = m_pPrev;
|
|
}
|
|
|
|
class FHook : public Hook
|
|
{
|
|
public:
|
|
FHook(LPVOID pFunction, LPVOID pHook)
|
|
: m_pFunction(pFunction), m_pHook(pHook)
|
|
{
|
|
}
|
|
|
|
virtual void DoHook()
|
|
{
|
|
MH_CreateHook(m_pFunction, m_pHook, &m_pTrampoline);
|
|
MH_EnableHook(m_pFunction);
|
|
|
|
Hook::DoHook();
|
|
}
|
|
|
|
virtual void DoUnHook()
|
|
{
|
|
MH_DisableHook(m_pFunction);
|
|
MH_RemoveHook(m_pFunction);
|
|
|
|
Hook::DoUnHook();
|
|
}
|
|
|
|
LPVOID HookFunction()
|
|
{
|
|
DoHook();
|
|
return m_pTrampoline;
|
|
}
|
|
private:
|
|
LPVOID m_pFunction;
|
|
LPVOID m_pHook;
|
|
LPVOID m_pTrampoline;
|
|
};
|
|
|
|
LPVOID Hook::HookFunction(LPVOID pFunction, LPVOID pDetour, Hook** ppHook)
|
|
{
|
|
FHook* pHook = new FHook(pFunction, pDetour);
|
|
LPVOID pTrampoline = pHook->HookFunction();
|
|
if (ppHook) *ppHook = pHook;
|
|
return pTrampoline;
|
|
}
|
|
|
|
class VMTHook : public Hook
|
|
{
|
|
public:
|
|
VMTHook(LPVOID pInterface, UINT uIndex, LPVOID pHook)
|
|
{
|
|
m_pVMT = *(LPVOID**)pInterface;
|
|
m_uIndex = uIndex;
|
|
m_pHook = pHook;
|
|
}
|
|
|
|
void EnableProtection(bool bEnable)
|
|
{
|
|
LPVOID* pPtr = &m_pVMT[m_uIndex];
|
|
DWORD dwOldProtect;
|
|
VirtualProtect((LPVOID)pPtr, 4096, bEnable
|
|
? PAGE_READONLY : PAGE_READWRITE, &dwOldProtect);
|
|
}
|
|
|
|
virtual void DoHook()
|
|
{
|
|
m_pOriginal = m_pVMT[m_uIndex];
|
|
EnableProtection(false);
|
|
m_pVMT[m_uIndex] = m_pHook;
|
|
EnableProtection(true);
|
|
|
|
Hook::DoHook();
|
|
}
|
|
|
|
virtual void DoUnHook()
|
|
{
|
|
EnableProtection(false);
|
|
m_pVMT[m_uIndex] = m_pOriginal;
|
|
EnableProtection(true);
|
|
|
|
Hook::DoUnHook();
|
|
}
|
|
|
|
LPVOID HookVFunction()
|
|
{
|
|
DoHook();
|
|
return m_pOriginal;
|
|
}
|
|
private:
|
|
LPVOID* m_pVMT;
|
|
UINT m_uIndex;
|
|
LPVOID m_pHook;
|
|
LPVOID m_pOriginal;
|
|
};
|
|
|
|
LPVOID Hook::HookVFunction(LPVOID pInterface, UINT uIndex,
|
|
LPVOID pDetour, Hook** ppHook)
|
|
{
|
|
VMTHook* pHook = new VMTHook(pInterface, uIndex, pDetour);
|
|
LPVOID pOriginal = pHook->HookVFunction();
|
|
if (ppHook) *ppHook = pHook;
|
|
return pOriginal;
|
|
}
|