首页
社区
课程
招聘
[原创]HOOK学习笔记与心得
发表于: 2014-10-27 18:27 35239

[原创]HOOK学习笔记与心得

2014-10-27 18:27
35239

前言
自己从高中那时对黑客比较感兴趣,那时候去过很多论坛学所谓的“黑客技术”。同时也经常在一些QQ群,论坛里混,但见效甚微。
因为我很喜欢玩游戏,上大学后,同学们都发疯似的玩一款游戏—三国杀,现在玩的人已经很少了,被某公司抄袭后垄断了。由于当时学业繁重,然后自己又爱面子,所以在想如何学业不落下的同时游戏等级也能比别人高,上网找到了一款三国杀的刷分软件。兴高采烈得打开准备刷分,用了一天之后就不能用了,30元一个月的收费标准,穷学生哪能舍得啊?于是想找人破解,但转念一想,谁会帮你破解呢?还是自己来吧~自己动手,丰衣足食。上网+图书馆疯狂找资料,花了一个周末,把这个软件KO了,当时是高兴死了。那种成就感和兴奋感恐怕也只有亲身试过的人才知道。很快就刷到了150级了,比整天玩游戏的同学等级还要高,在满足了我虚荣心的同时也带我走向了逆向之门,或许这就是一种缘分吧。
好了,背景就不多说了。今天和大家一起学习一下C++中的HOOK API技术。相信大家都知道这是逆向PJ中的一个特别重要也是实用的技术。(*^__^*)
一、        Hook介绍
钩子(Hook),是Windows消息处理机制的一个平台,应用程序可以在上面设置子程以监视指定窗口的某种消息,而且所监视的窗口可以是其他进程所创建的。当消息到达后,在目标窗口处理函数之前处理它。钩子机制允许应用程序截获处理window消息或特定事件。
我们知道Windows系统API函数都是被封装到DLL中,在某个应用程序要调用一个API函数的时候,如果这个函数所在的DLL没有被加载到本进程中则加载它,然后保存当前环境(各个寄存器和函数调用完后的返回地址等)。接着程序会跳转到这个API函数的入口地址去执行此处的指令。由此看来,我们想在调用真正的API之前先调用我们的函数,那么可以修改这个API函数的入口处的代码,使他先跳转到我们的函数地址,然后在我们的函数最后再调用原来的API函数。
简单来说HOOK API 可以理解成对程序将要执行系统函数的一个拦截, 拦截后执行自己写的代码以达到完成某种特定的目的,再恢复程序继续执行,很多PJ中的Patch 机器码,盗号木马等都是用这个方法。
二、        Hook API实战
OK,既然我们需要实现一个这样的一个HOOK。当然需要两样东西,一是目标程序,一是我们的代码。
1.        程序:
新建一个dll工程文件目录如图:

我们自己新建一个Add.def文件,然后添加到工程中即可,如图我是添加到Source Files里。
跟exe有个main或者WinMain入口函数一样,DLL也有它自己的一个入口函数,就是DllMain。
我们打开dllmain.cpp  代码如下:

// dllmain.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"

int WINAPI add(int a, int b)
{
	return a + b;
}

BOOL APIENTRY DllMain(HANDLE hModule,
	DWORD  ul_reason_for_call,
	LPVOID lpReserved
	)
{
	return TRUE;
}
LIBRARY  Add
DESCRIPTION "ADD LA"
EXPORTS
add  @1;

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 3
支持
分享
最新回复 (21)
雪    币: 56
活跃值: (34)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
沙发~多谢分享!
2014-10-27 20:04
0
雪    币: 71
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
很基础,很通俗
2014-10-27 22:52
0
雪    币: 266
活跃值: (44)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
4
顶~~~~~
2014-10-28 22:09
0
雪    币: 202
活跃值: (61)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
入门级资料,不过值得支持了。
2014-10-28 22:30
0
雪    币: 163
活跃值: (45)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
Mark!
2014-10-28 23:35
0
雪    币: 21
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
再来个x64位下的hook呢
2014-11-5 13:10
0
雪    币: 3242
活跃值: (279)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
好文章~~
2014-11-5 19:52
0
雪    币: 10
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
写的挺好的 楼主加油!顺便问一下VS2012 不装Visual Assist X有自动提示么
2014-11-5 20:09
0
雪    币: 1933
活跃值: (113)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
瞬间感觉自己好弱啊,一个周末搞定了,我现在还没入门!!
2015-1-12 14:39
0
雪    币: 188
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
不错,支持个
2015-1-12 22:15
0
雪    币: 3496
活跃值: (749)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
不错 支持
2015-3-16 06:05
0
雪    币: 60
活跃值: (449)
能力值: ( LV5,RANK:65 )
在线值:
发帖
回帖
粉丝
13
标记一下
2015-3-17 10:47
0
雪    币: 910
活跃值: (3565)
能力值: ( LV7,RANK:140 )
在线值:
发帖
回帖
粉丝
14
hookon和hookoff不需要使用WriteProcessMemory,因为dll已经注入了目标进程,fadd的地址相当于本地地址,可以直接当作本地内存进行操作,比如*fadd=xxx 这样的,或者memcpy函数。
另外Inject里面也不需要内联汇编,一样的道理。
当然了并不是说你写的不对或者写的不好,而是交流一下其他的手法,操作本地内存可以更灵活
2015-3-17 14:31
0
雪    币: 141
活跃值: (54)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
15
学习了 谢谢
2015-10-9 15:04
0
雪    币: 9917
活跃值: (475)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
完全看不懂不知道要如何才能正确的学习hook方面的知识
2016-1-28 09:55
0
雪    币: 12527
活跃值: (5278)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17

楼主的复件也是牛了,还以为是源码
原来就是图
2017-12-23 17:17
0
雪    币: 350
活跃值: (87)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
18
楼主,你这HOOK程序,问题很严重啊!虽然能运行,但是你没看出有一个严重的问题么?你可以试试多线程频繁HOOK以及卸载HOOK的情况,你就会发现一个非常严重的后果!
2017-12-23 19:39
0
雪    币: 350
活跃值: (87)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
19
看你们学习HOOK的时候栽倒在我曾经栽倒的地方,真是不是滋味啊!
2017-12-23 19:42
0
雪    币: 350
活跃值: (87)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
20
yeyeshun hookon和hookoff不需要使用WriteProcessMemory,因为dll已经注入了目标进程,fadd的地址相当于本地地址,可以直接当作本地内存进行操作,比如*fadd=xxx 这样的,或 ...
这个倒是其次,你没有发现,它没有处理多线程竞争么?按照它这调用方法,在多线程同时HOOK的时候就会出现一个线程在调用函数的时候,另外一个线程有可能正在进行HOOK,这是很危险的,WriteProcessMemory并不是线程同步的,还有,它没有对线程调用HOOK的函数进行调用次数统计,这个统计的作用是保证DLL模块在退出时所有的HOOK调用已经完成,当HOOK进行调用时,这个统计就加一,HOOK调用完成时,统计减一,如果模块需要退出,就检查HOOK调用统计,如果统计不为0,就让模块进入等待,直到调用统计为0为止!如果HOOK调用未完成,而模块又退出了,那么等待HOOK目标的后果就只有崩溃了
2017-12-23 19:51
0
雪    币: 350
活跃值: (87)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
21
yeyeshun hookon和hookoff不需要使用WriteProcessMemory,因为dll已经注入了目标进程,fadd的地址相当于本地地址,可以直接当作本地内存进行操作,比如*fadd=xxx 这样的,或 ...
楼主,你的这个函数int  WINAPI  Myadd(int  a,  int  b)
{
        //截获了对add()的调用,我们给a,b都加上一定的数
        a  =  a  +  987;
        b  =  b  +  654;
 
        HookOff();//关掉Myadd()钩子防止死循环 
 
        int  ret;
        ret  =  add(a,  b);
 
        HookOn();//开启Myadd()钩子 
 
        return  ret;
}虽然可以防止钩子死循环  ,你这样调用却产生了一个多线程竞争的问题,要解决这个问题,你就不能这样关闭HOOK
2017-12-23 19:57
0
雪    币: 910
活跃值: (3565)
能力值: ( LV7,RANK:140 )
在线值:
发帖
回帖
粉丝
22
czcqq 楼主,你的这个函数int WINAPI Myadd(int a, int b) { //截获了对add()的调用,我们给a,b都加上一定的数 a = a + 987; ...
我思考了一下,发现我并不是楼主。。。
这些东西如果要写到完美的话还是很复杂的,我只是指出其中可以改进的一点而已。真正要使用的话,我选择minHook
2017-12-25 10:18
0
游客
登录 | 注册 方可回帖
返回
//