• 利用异常实现短期hook


    场景1

    调用目标call 需要跳过某些判断或者函数

    场景2 

    目标call 只需要部分指令执行

    大概实现技术

    设置线程上下文设置drX寄存器 实现硬件执行断点

    主动调用目标call

    通过硬件断点获取寄存器或修改eip

    以上实现不改变crc且不通过驱动实现。只对当前执行线程有效,不使用线程句柄

    调用call 的过程中有4个硬件断点随意修改call内部流程,适合在游戏主循环中使用.

    ---------------------------------------------------------------------------

    已经通过hook方法 把所有读写call均在目标主线程调用。

    通过主动调用1050F7A0这个call 但是不执行1050F805 

    1050F805 此时的 ECX则是我需要得到的值

    void __declspec(naked) _stdcall hook_handleEIP()

    {

    _asm

    {

    //E

    popeax //目标地址有push,先平盏

    moveax,ecx //得到数据后修改eax作为返回值 然后ret掉目标函数

    retn    4

    }

    }

    EXCEPTION_DISPOSITION

    __cdecl

    _except_handler(

    struct _EXCEPTION_RECORD *ExceptionRecord,

    void * EstablisherFrame,

    struct _CONTEXT *ContextRecord,

    void * DispatcherContext )

    {

    EXCEPTION_DISPOSITION ERet = ExceptionContinueSearch;

    //判断异常是否为单步异常,硬件断点也是单步异常

    if (ExceptionRecord->ExceptionCode==EXCEPTION_SINGLE_STEP) 

    {

    //判断异常地址,不是目标地址则是第一次的单步

    if ((DWORD)ExceptionRecord->ExceptionAddress != 0x1050F805)

    {

    //B

    SetHardwareBreakpoint(ContextRecord,0x32D3F805,DR_3,CODE,SIZE_1);//设置硬件断点相关标志位

    ERet = ExceptionContinueExecution;//告诉系统异常已处理

    }else if ((DWORD)ExceptionRecord->ExceptionAddress == 0x1050F805)

    {

    //D

    RemoveHardwareBreakpoint(ContextRecord,DR_3);//删除硬件寄存器标志位

    //修改eip到自己的函数上

    ContextRecord->Eip = (DWORD)hook_handleEIP;

    ERet = ExceptionContinueExecution;//告诉系统异常已处理

    }

    }

    return ERet;

    }

    DWORD ExecutionFunction()

    {

    //A

    DWORD handler = (DWORD)_except_handler;//异常处理函数

    _asm

    {

    pushhandler//注册异常处理函数

    pushFS:[0]

    movFS:[0],ESP

    pushfd

    pushfd

    orDWORD PTR[esp],0x100//设置dr7单步标志

    popfd //执行到这里会触发单步异常

    nop

    popfd

    }

    //以上是注册异常处理函数

    //以下是主动调用目标函数

    DWORD dwRet;

    _asm

    {

    pushad

    push0

    moveax,1050F7A0h

    calleax //C

    mov[dwRet],eax

    popad

    }

    //F

    //删除异常接收函数

    _asm

    {

    moveax,[ESP]

    movFS:[0], EAX

    addesp, 8

    }

    return dwRet;

    }

    //以上函数执行过程有标注 A-B-C-D-E-F顺序

    描述完毕。

    设置drX寄存器可以参阅

    https://blog.csdn.net/binhualiu1983/article/details/51646094 

    非常详细.

    需要注意的是目前这个函数有逻辑跳转,如果没正确执行到1050F805就会离开这个函数,然后dr3寄存器未清理,导致被保护检测

    所以执行完call 后主动清理drX寄存器一次就完整了。

  • 相关阅读:
    java.lang.ClassNotFoundExceptioncom.mysql.cj.jdbc.Driver解决方法
    【零基础学Python】Day5 Python基本数据类型之List
    PyCharm 调试过程中控制台 (Console) 窗口内运行命令 - 实时获取中间状态
    实例分割Yolact边缘端部署 (二) 训练自己的模型-> onnx
    揭秘消费者需求:群狼调研助您把握市场先机
    网络爬虫——urllib(2)
    文件I/O
    为什么数组它的顺序读写会比较方便?
    Qt6中使用Qt Charts
    Java文件操作【教你用Java运行微信】
  • 原文地址:https://blog.csdn.net/jmm18363027827/article/details/133776367