Hook是什么?

    hook翻译之后是钩子的意思,hook的用途主要是用来拦截消息的,看到这里大家可能会迷茫,What is a hook?所以这时就不得不普及一下操作系统的原理。

举个例子:假如你是一名游戏热衷者,在玩游戏时,你要释放技能那么你就会对键盘鼠标进行操作,表面上你是直接操作游戏,其实中间经过了几个环节。

首先,你操作键盘鼠标,那么计算机底层键盘鼠标的驱动就会收到一个消息。

然后,这个驱动会把消息传个操作系统。

其次,操作系统会判断这个消息是作用在哪个程序上。

最后,操作系统会把这个事件传给相应的程序,那么,你就可以看到你操作游戏的样子了。

做自己的Hook!

好!说了这些,大家想想假如你写了一个hook,在别人的电脑上拦截了这个消息,操作系统就不知道这个消息,你可以把这个消息通过网络发到你的电脑,那个那台电脑的一举一动你都清楚....(当然我教大家这个不是希望你们做坏事,而是同过hook更深入学习计算     机    和保护自己电脑),下面我来同过一个简单的程序来让大家了解hook。

 int main()
{
MessageBox(NULL, L"Hello world", L"this",MB_OK);
system("pause");
return ;
}

这是一段简单的程序,其功能是为了显示一个对话窗口。这个对话窗口操作系统已经帮我们写好了,我们实际上是在调用这段代码。好!大家想一下我们能不能在调用这个函数之前截断这个调用,让程序调用自己的函数。(想想做插件是不是这个原理)答案是肯定的,我们能够截断这个消息并让他调用自己的函数。下面我们来代码实现一下。

 int WINAPI myMSG( HWND hWnd,
LPCTSTR IpText,
LPCTSTR IpCaption,
UINT uType)
{ printf("哈哈你的消息被我截断了");
return ;
}

这是我写的一个函数(注意:函数返回值和参数一定要和MessageBox一样,这样接口才能对上,不然会报错),我们要让程序执行我们的函数,那么我们就要写一个钩子。

 bool Hook()
{
//获取调用代码的首地址
PROC p = GetProcAddress(GetModuleHandle(L"user32.dll"), "MessageBoxW");
if (!p) return ; BYTE b[] = { };
//0xE9无条件跳转(学过汇编的同学应该知道)
b[] = 0xE9;
//计算偏移地址。 偏移地址 = 跳转地址-MessageBox的地址
*(DWORD*)(b + ) = (DWORD)myMSG - (DWORD)p - ;
/*通过上面三行代码,这个数组储存的代码意思是(无条件跳转到我的函数地址位置)*/ //在计算位置的内存中写入数据
WriteProcessMemory(GetCurrentProcess(), p, b, , NULL);
return ;
}

我已经写好了一个钩子,下面我放出完整程序的代码

  #include <stdio.h>
#include <Windows.h> int WINAPI myMSG( HWND hWnd,
LPCTSTR IpText,
LPCTSTR IpCaption,
UINT uType)
{
printf("哈哈你的消息被我截断了");
return ;
} bool Hook()
{
//获取调用代码的首地址
PROC p = GetProcAddress(GetModuleHandle(L"user32.dll"), "MessageBoxW");
if (!p) return ; BYTE b[] = { };
//0xE9无条件跳转(学过汇编的同学应该知道)
b[] = 0xE9;
//计算偏移地址。 偏移地址 = 跳转地址-MessageBox的地址
*(DWORD*)(b + ) = (DWORD)myMSG - (DWORD)p - ;
/*通过上面三行代码,这个数组储存的代码意思是(无条件跳转到我的函数地址位置)*/ //在计算位置的内存中写入数据
WriteProcessMemory(GetCurrentProcess(), p, b, , NULL);
return ;
}
int main()
{
Hook();
MessageBox(NULL, L"Hello world", L"this",MB_OK); system("pause");
return ;
}

首先我们把Hook注释掉运行。运行结果如下。

如何加上hook,你会发现一件令人兴奋的事情,并没有弹出对话框。运行结果如下

通过这个例子相信大家对hook有了一些了解,现在大家肯能会有一个疑问,我能跳转,能不能回去呢,答案是能的。我也给大家提供一个点思路ReadProcessMemory()用这个api来保存原来的段地址和内存中的代码,回去时在利用WriteProcessMemory()再跳转一次,就可以会到原来调用的代码处了,这些是不是很棒,大家可以回家自行试验,也可以巩固一下今天所学的知识。

最新文章

  1. 12.Linux软件安装 (一步一步学习大数据系列之 Linux)
  2. DEV柱状图----傻瓜版
  3. 你还记的那一年你我学习的--&gt;&gt;用表组织数据*(数据表)
  4. Simulating a Fetch robot in Gazebo
  5. [HDU 4417] Super Mario (树状数组)
  6. win7 不能启动 memcached 总是反回failde to start service
  7. mysql存储过程中使用临时表和游标
  8. django cbv
  9. Session为空的一种原因
  10. Spring-Boot:Spring Cloud构建微服务架构
  11. JavaScript 使用闭包防止变量污染
  12. UE4 射线拾取&amp;三维画线
  13. Linux进阶知识和命令
  14. JarvisOJ Misc shell流量分析
  15. flex-grow,flex-shrink,flex-basis及flex
  16. itchat key
  17. media静态文件统一管理 操作内存的流 - StringIO | BytesIO PIL:python图片操作库 前端解析二进制流图片(了解) Admin自动化数据管理界面
  18. WEB框架Django之ORM操作
  19. 江南白衣整理和开发的java常用工具类
  20. CSS加DIV布局

热门文章

  1. 关于ie8兼容性问题的处理
  2. ugui的优化
  3. ES6中的类继承和ES5中的继承模式详解
  4. sublime text 3 PHP 所需插件
  5. 此请求的URL的长度超过配置的maxUrlLength值
  6. 2017年11月27日 C#MDI窗体创建&amp;记事本打印&amp;记事本查找、自动换行
  7. RecyclerView IndexOutOfBoundsException 问题
  8. SZU 7
  9. 如何解决git fatal: refusing to merge unrelated histories
  10. js-TextArea的换行符处理