吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 3046|回复: 1
收起左侧

[C&C++ 转载] Hook KiUserExceptionDispatcher以及问题解决

[复制链接]
z-one 发表于 2022-3-9 09:22
本帖最后由 z-one 于 2022-3-9 09:29 编辑

异常发生后,KiUserExceptionDispatcher是R3最先被调用的函数,优先于VEH和SEH
Hook KiUserExceptionDispatcher可以让我们的异常处理在R3优先级最高
image-20220309085724461.png
Hook代码

[C] 纯文本查看 复制代码
bool BeginHook(IN PVOID HookAddr, IN PVOID MyFun,IN ULONG HookLen, OUT PVOID* RepairPos)
{
        BYTE HookCode[5] = { 0xE9,0,0,0,0 };
        BYTE ReturnCode[5] = { 0xE9,0,0,0 };
        ULONG PatchSize = Disasm(HookAddr, HookLen);
        *RepairPos = VirtualAlloc(NULL, PatchSize + 5, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
        if (!(*RepairPos)) return FALSE;

        *(PULONG)((ULONG)HookCode + 1) = (ULONG)MyFun -((ULONG)HookAddr + 5);//从HookAddr,jmp到MyFun
        *(PULONG)((ULONG)ReturnCode + 1) = (ULONG)HookAddr - ((ULONG)*RepairPos + 5);//从RepairPos+PatchSize,jmp到HookAddr+PatchSize
        DWORD oldProtect;
        VirtualProtect(HookAddr, 1, PAGE_READWRITE, &oldProtect);
        
        //若Hook处有偏移类型的转移指令,Repair会出错
        RtlCopyMemory(*RepairPos, HookAddr, PatchSize);//把Hook位置的PatchSize字节数据复制到RepairPos
        RtlCopyMemory((PVOID)((ULONG)*RepairPos+PatchSize), ReturnCode, 5);//在RepairPos+PatchSize后面加上返回代码
        RtlCopyMemory(HookAddr, HookCode, 5);//在Hook位置写入Hook代码

        VirtualProtect(HookAddr, 1, oldProtect, &oldProtect);
        return TRUE;
}



代码片段,为调用PatchFun做预备措施,并正确返回
[C] 纯文本查看 复制代码
void PatchFun(EXCEPTION_INFO Info)
{
    printf("-------已经进入KiUserExceptionDispatcher Patch Fun\n");
    printf("-------异常位置:%X\n", Info.pContext->Eip);
    printf("-------异常Code:%X\n", Info.pRecord->ExceptionCode);
    printf("-------\n");
}


__declspec(naked) void Preliminary()
{
        __asm
        {
                mov ecx, [esp + 4];
                mov ebx, [esp];
                push ecx;
                push ebx;
                call PatchFun;
                //__cdecl不对esp加8,给RtlDispatchException用
                //HookLen>5时,修复位置处有偏移类型的转移指令,跳转过去会出错,所以直接调用RtlDispatchException
                mov eax, KiUserExceptionDispatcher;
                add eax, 0x21;
                jmp eax;//jmp位置:call RtlDispatchException
                //mov eax, repairPos;//HookLen=5时,修复位置处无偏移类型的转移指令,跳转过去不会出错
                //jmp eax;
        }
}


需要注意的是若HookLen>7,在Hook位置出现了jz      short loc_4B2F5097,这种短偏移跳转很难修复,所以很难用统一的代码解决,要具体情况具体分析
一开始看网上资料只说了跳转到修复代码处会出错,但没有解释为什么会出错。
通过反汇编引擎很容易发现问题,试验的HookLen=10
image-20220309091356048.png

通过IDA分析KiUserExceptionDispatcher,可以发现就算不修补原来的代码,也不会影响异常派发,所以直接跳回到原函数
image-20220309092532439.png image-20220309092620524.png 最后附上源码 KiUserExceptionDispatcher.7z (339.57 KB, 下载次数: 22)

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

ycs207 发表于 2023-11-11 21:11
很好,有源码
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-24 20:38

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表