Author:方圆科技
The ways of hook have many methods , They have strengths and weaknesses . Hook of IAT need watch functions like LIABRARY,GETPROCESS . Real realize is trouble. Patch memory and jump to oneself code , That need realize original command on oneself code.....
Now I talk a new thinking , Exception is used to realize hook. You know, When a program happen exception, Exception pass on like this path: 1.debuger 2. Vectorization exception, mean VEH 3.SEH...
If don't use debugger, VEH is first receive exception. Like that We can inset int3 on want to space of hook code, Then through VEH to dispose hook, Realize hook final. Axiom is simple.
Code:
// Hook.h: interface for the CHook class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_HOOK_H__C0F41F39_4EB7_4129_BFB7_156CB203826F__INCLUDED_)
#define AFX_HOOK_H__C0F41F39_4EB7_4129_BFB7_156CB203826F__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <list>
using namespace std;
typedef void (*HOOKHANDLEFUN)(EXCEPTION_POINTERS *pExceptionInfo,void *pExtendData);
struct t_HookInfo
{
DWORD dwAddr;
HOOKHANDLEFUN pFn;
BYTE byOldCode;
};
class CHook
{
private:
static CHook *m_Instance; //单件模式
protected:
CHook(); //保证只生成一个实例
public:
static CHook* GetInstance();
t_HookInfo *m_pCurrentBP;
BOOL m_bSingleFlag;
EXCEPTION_POINTERS *m_pException;
void SetTF();
static LONG WINAPI VectoredHandler(PEXCEPTION_POINTERS ExceptionInfo);
list<t_HookInfo*> m_listHook;
BOOL AddHook(DWORD dwHookAddr, HOOKHANDLEFUN pFn);
BOOL RemoveHook(DWORD dwHookAddr);
BOOL SetBP(t_HookInfo*);
BOOL UnSetBP(t_HookInfo*);
virtual ~CHook();
};
#endif // !defined(AFX_HOOK_H__C0F41F39_4EB7_4129_BFB7_156CB203826F__INCLUDED_)
Code:
// Hook.cpp: implementation of the CHook class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "HookDll.h"
#include "Hook.h"
#define TEST
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#ifdef TEST
#define TESTMSG(str) AfxMessageBox(str)
#else
#define TESTMSG(str)
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
#define BREAKPOINTLEN 2
typedef PVOID (WINAPI *ADDVECTOREDEXCEPTIONHANDLER)(ULONG,PVOID);
CHook* CHook::m_Instance;
CHook::CHook()
{
//Empty chain table
m_listHook.empty();
//Install top exception
HINSTANCE hMod = LoadLibrary("kernel32.dll");
ADDVECTOREDEXCEPTIONHANDLER pfn = (ADDVECTOREDEXCEPTIONHANDLER)
GetProcAddress(hMod,"AddVectoredExceptionHandler");
PVOID ret = pfn(1,VectoredHandler);
m_bSingleFlag = FALSE;
m_pCurrentBP = NULL;
}
//Function name: GetInstance
//Funtion paramter: Non
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "HookDll.h"
#include "Hook.h"
#define TEST
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#ifdef TEST
#define TESTMSG(str) AfxMessageBox(str)
#else
#define TESTMSG(str)
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
#define BREAKPOINTLEN 2
typedef PVOID (WINAPI *ADDVECTOREDEXCEPTIONHANDLER)(ULONG,PVOID);
CHook* CHook::m_Instance;
CHook::CHook()
{
//Empty chain table
m_listHook.empty();
//Install top exception
HINSTANCE hMod = LoadLibrary("kernel32.dll");
ADDVECTOREDEXCEPTIONHANDLER pfn = (ADDVECTOREDEXCEPTIONHANDLER)
GetProcAddress(hMod,"AddVectoredExceptionHandler");
PVOID ret = pfn(1,VectoredHandler);
m_bSingleFlag = FALSE;
m_pCurrentBP = NULL;
}
//Function name: GetInstance
//Funtion paramter: Non
//Function feature: return a class instance
//Return Value: CHook*
CHook* CHook::GetInstance()
{
if (!m_Instance)
{
m_Instance = new CHook;
}
return m_Instance;
}
CHook::~CHook()
{
list<t_HookInfo*>::iterator it;
for (it = m_listHook.begin(); it!=m_listHook.end(); it++)
{
UnSetBP((*it));
delete (*it);
}
m_listHook.empty();
}
//Function name: AddHook
//Funtion paramter: 1.Need hook address 2.Dispose pointer of hook function
//Function feature: Add a HOOKINFO to chain table and install a hook
//Return Value: succeed return TRUE, Otherwise FALSE
//Notice: The function isn't check validity of paramter address, By caller check
BOOL CHook::AddHook(DWORD dwHookAddr, HOOKHANDLEFUN pFn)
{
t_HookInfo *pHookInfo = new t_HookInfo;
if (!pHookInfo)
{
return FALSE;
}
pHookInfo->dwAddr = dwHookAddr;
pHookInfo->pFn = pFn;
m_listHook.push_back(pHookInfo);
return SetBP(pHookInfo);
}
//Function name: RemoveHook
//Funtion paramter: 1. address of REMOVEHOOK
//Function feature: Delete a hook
//Return Value: succeed return TRUE, Otherwise FALSE
//Notice: The function isn't check validity of paramter address, By caller check
BOOL CHook::RemoveHook(DWORD dwHookAddr)
{
list<t_HookInfo*>::iterator it;
for (it = m_listHook.begin(); it!=m_listHook.end(); it++)
{
if ((*it)->dwAddr == dwHookAddr)
{
UnSetBP(*it);
delete (*it);
m_listHook.remove(*it);
return TRUE;
}
}
return FALSE;
}
//Function name: SetBP
//Funtion paramter:1. Information of t_HookInfo hook
//Return Value: CHook*
CHook* CHook::GetInstance()
{
if (!m_Instance)
{
m_Instance = new CHook;
}
return m_Instance;
}
CHook::~CHook()
{
list<t_HookInfo*>::iterator it;
for (it = m_listHook.begin(); it!=m_listHook.end(); it++)
{
UnSetBP((*it));
delete (*it);
}
m_listHook.empty();
}
//Function name: AddHook
//Funtion paramter: 1.Need hook address 2.Dispose pointer of hook function
//Function feature: Add a HOOKINFO to chain table and install a hook
//Return Value: succeed return TRUE, Otherwise FALSE
//Notice: The function isn't check validity of paramter address, By caller check
BOOL CHook::AddHook(DWORD dwHookAddr, HOOKHANDLEFUN pFn)
{
t_HookInfo *pHookInfo = new t_HookInfo;
if (!pHookInfo)
{
return FALSE;
}
pHookInfo->dwAddr = dwHookAddr;
pHookInfo->pFn = pFn;
m_listHook.push_back(pHookInfo);
return SetBP(pHookInfo);
}
//Function name: RemoveHook
//Funtion paramter: 1. address of REMOVEHOOK
//Function feature: Delete a hook
//Return Value: succeed return TRUE, Otherwise FALSE
//Notice: The function isn't check validity of paramter address, By caller check
BOOL CHook::RemoveHook(DWORD dwHookAddr)
{
list<t_HookInfo*>::iterator it;
for (it = m_listHook.begin(); it!=m_listHook.end(); it++)
{
if ((*it)->dwAddr == dwHookAddr)
{
UnSetBP(*it);
delete (*it);
m_listHook.remove(*it);
return TRUE;
}
}
return FALSE;
}
//Function name: SetBP
//Funtion paramter:1. Information of t_HookInfo hook
//Function feature: Write a INT3
//Return Value: succeed return TRUE, Otherwise FALSE
//Notice: The function isn't check validity of paramter address, By caller check
BOOL CHook::SetBP(t_HookInfo *pHookInfo)
{
DWORD dwOldProtect,dwNewProtect = PAGE_EXECUTE_READWRITE;
if (!pHookInfo)
{
return FALSE;
}
VirtualProtect((void*)pHookInfo->dwAddr,BREAKPOINTLEN,dwNewProtect,&dwOldProtect);
pHookInfo->byOldCode = *(BYTE*)(pHookInfo->dwAddr);
*(BYTE*)(pHookInfo->dwAddr) = 0xcc;
VirtualProtect((void*)pHookInfo->dwAddr,BREAKPOINTLEN,dwOldProtect,&dwNewProtect);
return TRUE;
}
//Function name: SetBP
//Funtion paramter:1.Information of t_HookInfo hook
//Function feature: Delete break
//Return Value: succeed return TRUE, Otherwise FALSE
//Notice: The function isn't check validity of paramter address, By caller check
BOOL CHook::UnSetBP(t_HookInfo *pHookInfo)
{
DWORD dwOldProtect,dwNewProtect = PAGE_EXECUTE_READWRITE;
if (!pHookInfo)
{
return FALSE;
}
VirtualProtect((void*)pHookInfo->dwAddr,BREAKPOINTLEN,dwNewProtect,&dwOldProtect);
*(BYTE*)(pHookInfo->dwAddr) = pHookInfo->byOldCode;
VirtualProtect((void*)pHookInfo->dwAddr,BREAKPOINTLEN,dwOldProtect,&dwNewProtect);
return TRUE;
}
//Function name: VectoredHandler
//Funtion paramter: Exception information structure pointer
//Function feature: Dispose exception
//Return Value: Oneself exception return EXCEPTION_CONTINUE_EXECUTION,Otherwise return EXCEPTION_CONTINUE_SEARCH
LONG WINAPI CHook::VectoredHandler(PEXCEPTION_POINTERS ExceptionInfo)
{
CHook *pHook = CHook::GetInstance();
//检测是否INT3断点
if (ExceptionInfo->ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT)
{
CString str;
str.Format("%-8x",ExceptionInfo->ExceptionRecord->ExceptionAddress);
// TESTMSG(str);
list<t_HookInfo*>::iterator it;
//Check whether oneself break
for (it = pHook->m_listHook.begin(); it!=pHook->m_listHook.end(); it++)
{
if ((*it)->dwAddr ==(DWORD) ExceptionInfo->ExceptionRecord->ExceptionAddress)
{
//Log current break, Set step flag, Delete break,
pHook->m_pException = ExceptionInfo;
pHook->SetTF();
pHook->UnSetBP(*it);
pHook->m_pCurrentBP = *it;
//Call related function
(*it)->pFn(ExceptionInfo,NULL);
return EXCEPTION_CONTINUE_EXECUTION;
}
}
return EXCEPTION_CONTINUE_SEARCH;
}
//Dispose step break
//Return Value: succeed return TRUE, Otherwise FALSE
//Notice: The function isn't check validity of paramter address, By caller check
BOOL CHook::SetBP(t_HookInfo *pHookInfo)
{
DWORD dwOldProtect,dwNewProtect = PAGE_EXECUTE_READWRITE;
if (!pHookInfo)
{
return FALSE;
}
VirtualProtect((void*)pHookInfo->dwAddr,BREAKPOINTLEN,dwNewProtect,&dwOldProtect);
pHookInfo->byOldCode = *(BYTE*)(pHookInfo->dwAddr);
*(BYTE*)(pHookInfo->dwAddr) = 0xcc;
VirtualProtect((void*)pHookInfo->dwAddr,BREAKPOINTLEN,dwOldProtect,&dwNewProtect);
return TRUE;
}
//Function name: SetBP
//Funtion paramter:1.Information of t_HookInfo hook
//Function feature: Delete break
//Return Value: succeed return TRUE, Otherwise FALSE
//Notice: The function isn't check validity of paramter address, By caller check
BOOL CHook::UnSetBP(t_HookInfo *pHookInfo)
{
DWORD dwOldProtect,dwNewProtect = PAGE_EXECUTE_READWRITE;
if (!pHookInfo)
{
return FALSE;
}
VirtualProtect((void*)pHookInfo->dwAddr,BREAKPOINTLEN,dwNewProtect,&dwOldProtect);
*(BYTE*)(pHookInfo->dwAddr) = pHookInfo->byOldCode;
VirtualProtect((void*)pHookInfo->dwAddr,BREAKPOINTLEN,dwOldProtect,&dwNewProtect);
return TRUE;
}
//Function name: VectoredHandler
//Funtion paramter: Exception information structure pointer
//Function feature: Dispose exception
//Return Value: Oneself exception return EXCEPTION_CONTINUE_EXECUTION,Otherwise return EXCEPTION_CONTINUE_SEARCH
LONG WINAPI CHook::VectoredHandler(PEXCEPTION_POINTERS ExceptionInfo)
{
CHook *pHook = CHook::GetInstance();
//检测是否INT3断点
if (ExceptionInfo->ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT)
{
CString str;
str.Format("%-8x",ExceptionInfo->ExceptionRecord->ExceptionAddress);
// TESTMSG(str);
list<t_HookInfo*>::iterator it;
//Check whether oneself break
for (it = pHook->m_listHook.begin(); it!=pHook->m_listHook.end(); it++)
{
if ((*it)->dwAddr ==(DWORD) ExceptionInfo->ExceptionRecord->ExceptionAddress)
{
//Log current break, Set step flag, Delete break,
pHook->m_pException = ExceptionInfo;
pHook->SetTF();
pHook->UnSetBP(*it);
pHook->m_pCurrentBP = *it;
//Call related function
(*it)->pFn(ExceptionInfo,NULL);
return EXCEPTION_CONTINUE_EXECUTION;
}
}
return EXCEPTION_CONTINUE_SEARCH;
}
//Dispose step break
else if ( ExceptionInfo->ExceptionRecord->ExceptionCode == STATUS_SINGLE_STEP )
{
//Judge wether step break onself
if (pHook->m_bSingleFlag && pHook->m_pCurrentBP)
{
//Restore break, flag
pHook->SetBP(pHook->m_pCurrentBP);
pHook->m_bSingleFlag = FALSE;
pHook->m_pCurrentBP = NULL;
return EXCEPTION_CONTINUE_EXECUTION;
}
else
{
return EXCEPTION_CONTINUE_SEARCH;
}
}
else
{
return EXCEPTION_CONTINUE_SEARCH;
}
}
//Function name: SetTF
//Funtion paramter:Non
//Function feature: Set step break
//Return Value: Non
void CHook::SetTF()
{
if (m_pException)
{
m_pException->ContextRecord->EFlags |= 0x100;
m_bSingleFlag = TRUE;
}
}
{
//Judge wether step break onself
if (pHook->m_bSingleFlag && pHook->m_pCurrentBP)
{
//Restore break, flag
pHook->SetBP(pHook->m_pCurrentBP);
pHook->m_bSingleFlag = FALSE;
pHook->m_pCurrentBP = NULL;
return EXCEPTION_CONTINUE_EXECUTION;
}
else
{
return EXCEPTION_CONTINUE_SEARCH;
}
}
else
{
return EXCEPTION_CONTINUE_SEARCH;
}
}
//Function name: SetTF
//Funtion paramter:Non
//Function feature: Set step break
//Return Value: Non
void CHook::SetTF()
{
if (m_pException)
{
m_pException->ContextRecord->EFlags |= 0x100;
m_bSingleFlag = TRUE;
}
}
No comments:
Post a Comment