单字节HOOK

在产品开发的过程中,常常会遇到API Hook的地方,而inline hook是最常用的一个方式.
因为我们要hook的不一定是带hotpatch特性的文件.所以,它有以下缺点:
1. 需要破坏至少5字节,在64bit的情况下,则可能更长.
2. Hook的过程是非原子,在写入hook指令的过程中,一些高频调用的函数可能恰好被调用.
3.重复hook在撤销时可能导致结果不可预期.

所以,一个单字节的Hook可解决指令长度的问题,一个良好的hook管理类则可以解决第三个问题.

下面是解决问题的思路:
1. 如何单字节.
显然,单字节不可能是直接的跳转指令,但是,有一个角色可以做到改变执行路径的功能: 异常处理.
windows 下有AddVectoredExceptionHandler,SetUnhandledExceptionFilter等,显然,VEH最适合做异常处理的功能,因为它早于SEH被调用.且它允许注册多个.
而单字节的异常,我能想到的两个,int3,或者是halt,前者是同样被用于调试器,后者.则同样符合我们目标,1单字节,2可触发特权指令异常.

进一步的调试分析
如果使用int3
1. od可以直接无障碍的执行
2.windbg需要字节加入event filter
3.VC IDE,无法使用,因为出现异常时eip的值不是异常抵制

如果使用halt
1. od会在首次触发时,提示无法继续,需要按shift+f9继续
2.windbg自动忽略异常,无障碍执行
3.VC IDE,自动忽略异常,无障碍执行

2.如何处理异常
根据异常地址,根据我们记录的map,查找到正确的新地址,改写eip/rip.

// note : exception can be re-enter
LONG CALLBACK CAPIHookMan::VectoredHandler(__in PEXCEPTION_POINTERS pExceptionInfo)
{
// DbgPrint(_T(“code:0x%x,address:%p”),
// pExceptionInfo->ExceptionRecord->ExceptionCode,
// pExceptionInfo->ExceptionRecord->ExceptionAddress);

switch (pExceptionInfo->ExceptionRecord->ExceptionCode)
{
#if HOOK_TYPE==HOOK_TYPE_INT3
case EXCEPTION_BREAKPOINT://it has problem when being debugged by VC IDE
#elif HOOK_TYPE==HOOK_TYPE_HALT
case STATUS_PRIVILEGED_INSTRUCTION:
#else
#error “unknown type”
#endif
{

break;
}
default:
return EXCEPTION_CONTINUE_SEARCH;
}

EnterCriticalSection(&m_cs);
HookPointList::iterator it=m_points.find(pExceptionInfo->ExceptionRecord->ExceptionAddress);
if (it!=m_points.end())
{
HookPoint* point=it->second;
#if defined(_M_IX86)
pExceptionInfo->ContextRecord->Eip=(DWORD)point->pTopNew;
#elif defined(_M_AMD64)
pExceptionInfo->ContextRecord->Rip=(DWORD64)point->pTopNew;
#else
#error “unsupport platform”
#endif
LeaveCriticalSection(&m_cs);
return EXCEPTION_CONTINUE_EXECUTION;
}
LeaveCriticalSection(&m_cs);

return EXCEPTION_CONTINUE_SEARCH;
}

3.如何重复hook
hook记录应该作为一个stack保存.
异常派遣时.栈顶的hook函数被调用.

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s