zoukankan      html  css  js  c++  java
  • Hook 初学习

    Hook
    概念

    百度上的概念

    每个Hook都有一个相关的指针列表,后加入的Hook再链表的开始,先加入的在链表的尾部

    后加入先获得控制权

    Hook 原理

    原本的流程

    graph LR id1(MessageBoxA)--<br>原本的进程-->id2(MessageBoxB); id2(MessageBoxB)-->id1(MessageBoxA)

    hook后的流程

    graph LR id1(MessageBoxA)--<br>step1:Hook-->id2(My_MessageBox); id2--<br>2step:return-->id1; id1--<br>step3-->id4(MessageBoxB) id4--<br>step4-->id2 id2--<br>step5-->id1

    就是在执行MessageBoxA的API时,先jmp到我的My_MessageBox,执行完之后再return回到MessageBoxA继续执行

    利用这个技术,我们可以监控API,比如应用程序会调用loadLibrary,那我们把它Hook了,把Dll路径改成我们的,那加载的就是我们的dll了,当然 Hook的API很多,因为只要是Windows的API都能HOOK

    Hook的思路
    1. 获取MessageBoxA函数的地址
    2. 修改函数的内存保护属性(便于写入jmp的二进制)
    3. 找到MessageBoxA前的5个字节的位置,写入jmp

    具体代码和地址的计算

    Hook实例

    手动尝试hook一个程序

    源码

    编译环境:win10 1909+gcc

    #include <windows.h>
    
    int main (){
      int a,b;
      a=3;
      b=2;
      int c=a+b;
      char tmp[8];
      memset(tmp,0,8);
      itoa(5,tmp,10);
      MessageBox(NULL,tmp,"Hook",0);
      return 0;
    }
    

    正常情况会弹出一个弹窗,标题栏写着Hook,下面写着5

    我们尝试用hook把5改成0

    Step1:

    ida打开a.exe,找到主函数部分,可以看到代码的大概位置

    .text:00401410 ; __unwind {
    .text:00401410                 lea     ecx, [esp+4]
    .text:00401414                 and     esp, 0FFFFFFF0h
    .text:00401417                 push    dword ptr [ecx-4]
    .text:0040141A                 push    ebp
    .text:0040141B                 mov     ebp, esp
    .text:0040141D                 push    ecx
    .text:0040141E                 sub     esp, 34h
    .text:00401421                 call    ___main
    .text:00401426                 mov     [ebp+var_C], 3
    .text:0040142D                 mov     [ebp+var_10], 2
    .text:00401434                 mov     edx, [ebp+var_C]
    .text:00401437                 mov     eax, [ebp+var_10]
    .text:0040143A                 add     eax, edx
    .text:0040143C                 mov     [ebp+var_14], eax
    .text:0040143F                 mov     dword ptr [esp+8], 8 ; size_t
    .text:00401447                 mov     dword ptr [esp+4], 0 ; int
    .text:0040144F                 lea     eax, [ebp+Text]
    .text:00401452                 mov     [esp], eax      ; void *
    .text:00401455                 call    _memset
    .text:0040145A                 mov     dword ptr [esp+8], 0Ah ; int
    .text:00401462                 lea     eax, [ebp+Text]
    .text:00401465                 mov     [esp+4], eax    ; char *
    .text:00401469                 mov     eax, [ebp+var_14]
    .text:0040146C                 mov     [esp], eax      ; int
    .text:0040146F                 call    _itoa
    .text:00401474                 mov     dword ptr [esp+0Ch], 0 ; uType
    .text:0040147C                 mov     dword ptr [esp+8], offset Caption ; "Hook"
    .text:00401484                 lea     eax, [ebp+Text]
    .text:00401487                 mov     [esp+4], eax    ; lpText
    .text:0040148B                 mov     dword ptr [esp], 0 ; hWnd
    .text:00401492                 call    _MessageBoxA@16
    .text:00401497                 sub     esp, 10h
    .text:0040149A                 mov     eax, 0
    .text:0040149F                 mov     ecx, [ebp+var_4]
    .text:004014A2                 leave
    .text:004014A3                 lea     esp, [ecx-4]
    .text:004014A6                 retn
    .text:004014A6 ; } // starts at 401410
    .text:004014A6 _main           endp
    

    正常来说,我们可以用patch来改,这里尝试hook的方式

    在赋值3,2完成之后,写入jmp指令,随便jmp到一块不影响程序,且在程序中的地址上(不一定要紧跟在jmp后面,只要在调用MessageBox函数之前随便的五个字节,要是没有刚好5个字节的指令,可以凑到至少5个,多的就nop掉),jmp指令破坏掉的指令要在jmp到的我的hook中修复,这样才能不影响程序原本的运行

    Step2:

    od定位到相应位置,双击指令,开始修改(也可以在ida中patch修改)eb

    3KopsP.png

    我选对程序无影响的地址401305这块地址3KIfPJ.png

    我选择在add eax, edx后插入jmp 00401305,因为这条汇编是5个字节,会覆盖掉两条汇编指令,变成了

    3KIxxI.png

    所以在我的hook,也就是00401305处我要补上

    3KoQdU.png

    解释一下

    mov eax,0x0                        ;jmp 来之前eax中的值是5,给覆盖成0
    mov dword ptr ss:[ebp-0x14],eax    ;这是照着原来的写法,把jmp时覆盖的指令补上
    mov dword ptr ss:[esp+0x8],0x8     ;同上
    jmp a.00401447                     ;这是跳回原来的地方继续执行
    

    step3

    保存:右键-->复制到课自行文件-->全部修改

    如果发现报错,可执行文件中无法确定数据。首先不管报错,直接保存文件,看看是否可运行,不行考虑换个离源代码位置近的地方去添加跳转代码,再不行就考虑增加区块

    Hook实例2

    具体参考

    hook api 反OD调试的一种思路

    HOOK API入门之Hook自己程序的MessageBoxW

    截获 Windows socket API

    vc++ 编译dll

    原理

    windows 系统函数都是以dll封装起来的,程序应用到系统函数的时候,要先将dll加载到进程空间。我们只要在我们要hook程序调用dll之前,jmp到我们自己构造的dll中,就可以达到效果

    几个要点:

    1. 怎么让被hook的程序加载我们的dll

      采用上面文章讲到的方法,调用windows现成的鼠标钩子,响应到所有鼠标点击事件,然后载入我的dll。鼠标钩子只是用来载入我的dll到被hook的程序,做事的还是我的dll

    2. 怎么加载完成后修复原来被我们的部分

      这个方法有很多,可以在我的dll中去修复,先记录下原来的数据,在执行完我们dll的主要内容后再把数据恢复,跳转回去的时候就不会再执行jmp到我们dll了。也可以像上一个实例一样,直接在我定义的dll执行,在调会主函数,再执行进入下个dll

    3. 怎么在加载正常dll前获取地址

      可以调用GetProcAddress函数,来获取dll的入口地址

    操作……还没操作,之后再补

  • 相关阅读:
    ASP.NET Core 中文文档 第四章 MVC(3.2)Razor 语法参考
    ASP.NET Core 中文文档 第四章 MVC(3.1)视图概述
    ASP.NET Core 中文文档 第四章 MVC(2.3)格式化响应数据
    ASP.NET Core 中文文档 第四章 MVC(2.2)模型验证
    ASP.NET Core 中文文档 第四章 MVC(2.1)模型绑定
    ASP.NET Core 中文文档 第四章 MVC(01)ASP.NET Core MVC 概览
    mysql 解除正在死锁的状态
    基于原生JS的jsonp方法的实现
    HTML 如何显示英文单、双引号
    win2008 r2 服务器php+mysql+sqlserver2008运行环境配置(从安装、优化、安全等)
  • 原文地址:https://www.cnblogs.com/militray-axe/p/12344427.html
Copyright © 2011-2022 走看看