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

我选对程序无影响的地址401305这块地址

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

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

解释一下

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的入口地址

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

Hook 初学习的更多相关文章

  1. clisp, scheme 和 clojure 初学习

    clisp, scheme和clojure 初学习 1 clojure "clojure绝对会成为你的编程工具箱里的终极武器" "其他语言可能只是工具,但 Clojure ...

  2. Android so注入(inject)和Hook技术学习(三)——Got表hook之导出表hook

    前文介绍了导入表hook,现在来说下导出表的hook.导出表的hook的流程如下.1.获取动态库基值 void* get_module_base(pid_t pid, const char* modu ...

  3. c# window服务-初学习

    window服务-初学习 一.工具: VS2015+NET Framework4.5. 二.操作: 1.新建windows服务的项目: 2.修改windows服务相关内容: 3.预览windows服务 ...

  4. Python初学习:简单的练习题

    Python初学习 一些见到那的练习题: 初级难度 设计一重量转换器,输入以g为单位的数字后,返回换算结果以Kg为单位的结果 中级难度 设计一个求直角三角形斜边长的函数,(以两个直角边为参数,求最长边 ...

  5. Swift初学习

    距离swift发布10天了,也简单看了一下swift的语法,个人感觉相对于object-c很是简单明了.Swift的出现并不能说明iOS开发简单了很多,有可能会变得复杂,你需要学习两门编程语言,因为在 ...

  6. Jquery 插件初学习

    参考文章:插件开发精品教程,让你的jQuery提升一个台阶 刚刚学了一下jquery的插件插件开发,写个demo记录.练习一下.毕竟,输出才是最好的学习. 这个也不过是最基础的一个插件写法,只是,自己 ...

  7. requests库写接口测试框架初学习

    学习网址:    https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-dscpm/ff75b907-415d-4220-89 ...

  8. 2018.2.21 Python 初学习

    折腾了一天,一直在用CMD学习Python写Hello World.偶然间发现可以用Pycharm.也算是给后面想学习的人提个醒,方便省事许多. format()使用方法. age = 20name ...

  9. Android so注入(inject)和Hook技术学习(二)——Got表hook之导入表hook

    全局符号表(GOT表)hook实际是通过解析SO文件,将待hook函数在got表的地址替换为自己函数的入口地址,这样目标进程每次调用待hook函数时,实际上是执行了我们自己的函数. GOT表其实包含了 ...

随机推荐

  1. SpringBoot分布式篇Ⅷ --- 整合SpringCloud

    SpringCloud是一个分布式的整体解决方案.Spring Cloud为开发者提供了在分布式系统(配置管理,服务发现,熔断,路由,微代理,控制总线,一次性token,全局锁,leader选举.分布 ...

  2. springIOC源码接口分析(六):ResourceLoader

    参考博客: https://www.cnblogs.com/jixp/articles/10702486.html 一 定义方法 Spring提供了ResourceLoader接口用于实现不同的Res ...

  3. MySQL5.7 中的query_cache_size

    摘自:http://jackyrong.iteye.com/blog/2173523 1 原理    MySQL查询缓存保存查询返回的完整结果.当查询命中该缓存,会立刻返回结果,跳过了解析,优化和执行 ...

  4. 《ASP.NET Core 高性能系列》静态文件中间件

    一.概述 静态文件(如 HTML.CSS.图片和 JavaScript等文件)是 Web程序直接提供给客户端的直接加载的文件. 较比于程序动态交互的代码而言,其实原理都一样(走Http协议), ASP ...

  5. c++中静态成员函数

    静态成员函数 静态成函数和静态成员数据相同,他们都属于某一个类的静态成员而不是某一个对象的成员. 静态数据成员的使用方法和注意事项 1.静态数据成员在定义或说明时前面加上关键字static 2.初始化 ...

  6. 一、Shell概述

    什么是Shell 解释Shell脚本名词之前,我们先来说下什么是Shell? Shell是一个命令解释器,它在操作系统的最底层,负责直接与用户对话,把用户的输入解释给操作系统,并处理各种各样的操作系统 ...

  7. 死磕mysql(2)

    想测试自己的查询语句,导入批量的数据,一开始很慢以为是自己的语句有问题,后来是这个autocommit,效率相差好多好多............ delimiter // create procedu ...

  8. Codeforces Gym101234G Dreamoon and NightMarket(优先队列,子集和第k大)

    题意: 求子集和第k大,n,k<=1e6 思路: 优先队列经典题目,注意优先队列是默认按从大到小排的 代码: #include<iostream> #include<cstdi ...

  9. 牛客练习赛25 A 因数个数和(数论分块)

    题意: q次询问,每次给一个x,问1到x的因数个数的和. 1<=q<=10 ,1<= x<=10^9 1s 思路: 对1~n中的每个数i,i作为i,2i,3i,...的约数,一 ...

  10. mongodb 常用操作命令

    1.关闭mongodbuse admindb.shutdownServer() 2.报错 not master and slaveok=falsers.slaveOk(); 3.查看集群副本的状态rs ...