• Inline Hook


    工作方式如下:

    1.1调用GetProcAddress对内存中要拦截的函数进行定位(如Kernel32.dll的ExitProcess),得到它的内存地址。

    1.2把这个函数起始的几个字节保存到我们的内存中。

    1.3用CPU的JUMP汇编指令来覆盖这个函数的起始几个字节,这条JUMP指令用来跳转到我们的替换函数的内存地址。我们替换的函数需要和原函数具有完全相同的声明:参数相同,返回值相同,调用约定相同。

    1.4当线程调用被拦截的函数时,跳转指令实际上会跳转到我们的替代函数,这是,我们可以执行相应的功能代码。

    1.5为了撤销对函数的拦截,我们必须把步骤2中保存的字节恢复回被拦截的函数中。

    1.6我们调用被拦截函数(现在已经不再拦截),让函数执行它的正常处理。

    1.7当原来函数返回时,我们再次执行第2,第3步,这样我们的替代函数将来还会被调用到。

    注意事项:

    l  JUMP指令对CPU(AMD,Intel)有依赖,在X86,X64下,更会有不同的表现。

    l  由于替换汇编代码的过程,不是原子操作的,很有可能在其它线程运行到此函数的入口的时候进行了替换,导致指令异常,程序崩溃。

    l  解决多线程的办法(分析来自Mhook库):

    替换的过程首先上互斥锁(如EnterCriticalSection),这把锁只对替换的过程互斥, 并无法避免其它线程正在调用要替换的函数。

    第二步做的就是挂起除本线程外的其它线程,并同时确保其它线程的执行点(IP)不在 我们将以替换的区域中。(参加Mhook的: SuspendOtherThreads函数)

    一般情况下,API的头部都是  8B FF 55 8B EC 如图所示:

     

    刚好5个字节的硬编码,我们修改成  jmp xxxxxxxx 时也是5个字节进行跳转到我们想要执行的代码地址。修改硬编码hook方式可以在API任意位置进行Hook并不局限于头5个字节,任意位置时需要计算好opcode码。

  • 相关阅读:
    重识linux-常见压缩和解压缩命令
    重识linux-压缩文件的原理
    重识linux-关于selinux
    重识linux-循环执行的例行性工作调度
    重识linux-仅执行一次的工作调动at
    Python资源
    python hehe
    Chrome 消息机制
    自己动手写reg注册表文件
    用JavaScript截图
  • 原文地址:https://www.cnblogs.com/Viwilla/p/5393247.html
Copyright © 2020-2023  润新知