首页
社区
课程
招聘
[原创]关于VEH无痕hook的一些小把戏
发表于: 2023-1-16 06:23 15335

[原创]关于VEH无痕hook的一些小把戏

2023-1-16 06:23
15335

众所周知VEH hook是为了躲避CRC检测而诞生的一项技术,古老但实用,故在此总结一下关于VEH hook的几种方法

先来简单介绍一下如何添加VEH处理函数,微软开放给了我们一个API:

第一个参数为true则代表插入VEH链表头,第二个参数则是要添加的VEH处理函数

那么来讲讲常见的hook方式

这是最为常见的VEH hook方式,利用硬件断点抛出异常,在异常处理函数里判断发生异常的地址是否和hook的地址一致,如果一致,则修改EIP(RIP)跳转

缺点:容易被检测(当然也可以Hook KiUserExceptionDispatcher来清空Dr寄存器规避检测),且用户最多只能够设置4个硬件断点(Dr0~Dr3)

这里就涉及到一个问题了,咱们想要这个Hook点不止一次被触发,所以该怎么做呢?
这里给出两种方法:

a.利用单步异常

b.利用析构函数(PolyHook做法)
这是个十分巧妙的做法,利用了C++中析构函数的特性,其原理就是构造一个恢复保护的析构函数,并在你的hook函数内初始化一个类,当程序执行完后(包括返回原函数),对象销毁,析构函数执行恢复保护
这里附上大概例子,详细做法各位可以移步 PolyHook 这是个十分优秀的Hook引擎

最后是触发方法,只需:

缺点:容易被查页属性,好处就是没有动DR寄存器(emmmmmm)

将Hook点首字节修改为0xCC,网上有例子,这里不再赘述

这应该说是所有常见VEH hook方法中最为隐蔽的了,将页面修改为只读这种不可执行属性,一但执行便会触发C0000005,只需像上面一样接管他就行

但由于影响的是一整个页面,也就是说这一整个页都会产生异常,所以说一个页面不能存在多个Hook点~但是有菊花说的好,办法总比困难多,这里说一下我的思路(用来Hook模块内函数,比较无脑且垃圾,大佬勿喷)

首先遍历整个进程的模块,找出要Hook的那个函数所在的模块,获取模块的地址以及大小,然后直接新建一块同样大小的内存,然后把整个模块拷贝到这块内存内,将这块内存中的“要Hook的函数”直接Inline Hook,然后通过异常将EIP(RIP)重定向到这块内存中“要Hook的函数”(ImageBase + HookAddress_Offset),直接不走原来的函数

这种方法的缺陷呢就是太太太太慢了,而且做法非常繁琐,所以说只适合Hook某些API,如果大佬们有什么更好的方法可以不吝赐教的话,不胜感激

 
 
SuspendThread(hHookThread);
 
CONTEXT thread_context = { CONTEXT_DEBUG_REGISTERS };
thread_context.Dr0 = HookAddr;
thread_context.Dr7 = 0x405;
 
//设置线程环境 抛出异常
 
DWORD oldprotect;
VirtualProtect((LPVOID)HookAddr, 5, PAGE_EXECUTE_READWRITE, &oldprotect);
SetThreadContext(hHookThread, &thread_context);
 
ResumeThread(hHookThread);
SuspendThread(hHookThread);
 
CONTEXT thread_context = { CONTEXT_DEBUG_REGISTERS };
thread_context.Dr0 = HookAddr;
thread_context.Dr7 = 0x405;
 
//设置线程环境 抛出异常
 
DWORD oldprotect;
VirtualProtect((LPVOID)HookAddr, 5, PAGE_EXECUTE_READWRITE, &oldprotect);
SetThreadContext(hHookThread, &thread_context);
 
ResumeThread(hHookThread);
LONG NTAPI  ExceptionFilter(PEXCEPTION_POINTERS ExceptionInfo)
{
 
    //判断当前异常码是否为硬件断点异常
    if (ExceptionInfo->ExceptionRecord->ExceptionCode== EXCEPTION_SINGLE_STEP)
    {
 
        //判断hook地址
        if (ExceptionInfo->ExceptionRecord->ExceptionAddress == HookAddr)
        {   
            /*在这里做你想做的事或者直接跳转到你的Hook函数中
            ........................
                            */
            ExceptionInfo->ContextRecord->Eip=(DWORD)&OriginalFunc;   
 
            return EXCEPTION_CONTINUE_EXECUTION;
 
        }
    }
    return EXCEPTION_CONTINUE_SEARCH;//继续向下搜索
}
LONG NTAPI  ExceptionFilter(PEXCEPTION_POINTERS ExceptionInfo)
{
 
    //判断当前异常码是否为硬件断点异常
    if (ExceptionInfo->ExceptionRecord->ExceptionCode== EXCEPTION_SINGLE_STEP)
    {
 
        //判断hook地址
        if (ExceptionInfo->ExceptionRecord->ExceptionAddress == HookAddr)
        {   
            /*在这里做你想做的事或者直接跳转到你的Hook函数中
            ........................
                            */
            ExceptionInfo->ContextRecord->Eip=(DWORD)&OriginalFunc;   
 
            return EXCEPTION_CONTINUE_EXECUTION;
 

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 4
支持
分享
最新回复 (3)
雪    币: 12
活跃值: (418)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
这种Query一下代码段就g,或者enum有没有第二份gamebase 也G...
crc走到最后还是要正面对抗
2023-3-11 11:26
0
雪    币: 66
活跃值: (152)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
可否留下联系方式 我想定制这个page hook
2023-6-24 16:59
1
雪    币: 2948
活跃值: (30846)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
感谢分享
2023-6-24 21:19
1
游客
登录 | 注册 方可回帖
返回
//