简单解释下hook:

钩子(Hook),是Windows消息处理机制的一个平台,应用程序可以在上面设置子程以监视指定窗口的某种消息,而且所监视的窗口可以是其他进程所创建的。当消息到达后,在目标窗口处理函数之前处理它。钩子机制允许应用程序截获处理window消息或特定事件。
钩子实际上是一个处理消息的程序段,通过系统调用,把它挂入系统。每当特定的消息发出,在没有到达目的窗口前,钩子程序就先捕获该消息,亦即钩子函数先得到控制权。这时钩子函数即可以加工处理(改变)该消息,也可以不作处理而继续传递该消息,还可以强制结束消息的传递。
 
hook原理:

每一个Hook都有一个与之相关联的指针列表,称之为钩子链表,由系统来维护。这个列表的指针指向指定的,应用程序定义的,被Hook子程调用的回调函数,也就是该钩子的各个处理子程序。当与指定的Hook类型关联的消息发生时,系统就把这个消息传递到Hook子程。一些Hook子程可以只监视消息,或者修改消息,或者停止消息的前进,避免这些消息传递到下一个Hook子程或者目的窗口。最近安装的钩子放在链的开始,而最早安装的钩子放在最后,也就是后加入的先获得控制权。
Windows 并不要求钩子子程的卸载顺序一定得和安装顺序相反。每当有一个钩子被卸载,Windows 便释放其占用的内存,并更新整个Hook链表。如果程序安装了钩子,但是在尚未卸载钩子之前就结束了,那么系统会自动为它做卸载钩子的操作。

这是我第一次接触hook,写得很简单,对MessageBox函数hook一下下。

下面实验的原理:在指定进程中的内存里找到目标函数的地址,然后修改其首地址的前几字节为jmp指令,指向我们自己的自定义函数地址。这样,进程执行这个函数的时候,会先执行我们自己的代码,之后可以选择性执行原函数或不执行。

流程:

1.构造跳转指令。

2.在内存中找到欲hook函数地址,并保存欲hook位置处的前5个字节。

3.将构造的跳转指令写入需hook的位置处。

4.当被hook位置被执行时会转到我们的流程执行。

5.如果要执行原来的流程,那么取消hook,也就是还原被修改的字节。

6.执行原来的流程。

7.继续hook住原来的位置。

下面就要见具体代码实现了。我们来把hook封装一下。

ILHook.h

#ifndef __ILHOOK_H_1_
#define __ILHOOK_H_1_ #include <Windows.h> class CILHook{
public:
CILHook();
~CILHook();
BOOL Hook(LPSTR pszModuleName, LPSTR pszFuncName, PROC pfnHookFunc);
VOID UnHook();
BOOL ReHook(); private:
PROC m_pfnOrig;//函数地址
BYTE m_bOldBytes[];//函数入口代码
BYTE m_bNewBytes[];//Inline代码
}; #endif

ILHook.cpp

#include "ILHook.h"

CILHook::CILHook(){
m_pfnOrig=NULL;
ZeroMemory(m_bOldBytes, );
ZeroMemory(m_bNewBytes, );
}
CILHook::~CILHook(){
UnHook();
} /*
函数名称:Hook
函数功能:对指定模块中的函数进行挂钩
参数说明:
pszModuleName:模块名称
pszFuncName:函数名称
pfnHookFunc:钩子函数
*/
BOOL CILHook::Hook(LPSTR pszModuleName,LPSTR pszFuncName,PROC pfnHookFunc){
BOOL bRet=FALSE;
//获取指定模块中函数的地址
m_pfnOrig=(PROC)GetProcAddress(GetModuleHandle(pszModuleName),pszFuncName); if(m_pfnOrig!=NULL){
//保存该地址处5个字节的内容
DWORD dwNum=;
ReadProcessMemory(GetCurrentProcess(),m_pfnOrig,m_bOldBytes,,&dwNum);
//构造JMP指令
m_bNewBytes[]='\xe9';//jmp Opcode
//pfnHookFunc是HOOK后的目标地址
//m_pfnOrig是原来的地址
//5是指令长度
*(DWORD*)(m_bNewBytes+)=(DWORD)pfnHookFunc-(DWORD)m_pfnOrig-;
//将构造好的地址写入该地址处
WriteProcessMemory(GetCurrentProcess(),m_pfnOrig,m_bNewBytes,,&dwNum); bRet=TRUE;
}
return bRet;
} /*
函数名称:UnHook
函数功能:取消函数的挂钩
*/
VOID CILHook::UnHook(){
if(m_pfnOrig!=){
DWORD dwNum=;
WriteProcessMemory(GetCurrentProcess(),m_pfnOrig,m_bOldBytes,,&dwNum);
}
} /*
函数名称:ReHook
函数功能:重新对函数进行挂钩
*/
BOOL CILHook::ReHook(){
BOOL bRet=FALSE;
if(m_pfnOrig!=){
DWORD dwNum=;
WriteProcessMemory(GetCurrentProcess(),m_pfnOrig,m_bNewBytes,,&dwNum);
bRet=TRUE;
}
return bRet;
}

test.cpp

#include "ILHook.h"

CILHook MsgHook;

int WINAPI MyMessageBoxA(HWND hWnd,LPCSTR lpText,LPCSTR lpCaption,UINT uType){
MsgHook.UnHook();
MessageBox(hWnd,"Hook",lpCaption,uType);
MessageBox(hWnd,lpText,lpCaption,uType);
MsgHook.ReHook(); return ;
} int main(){
MessageBox(NULL,"test","test",MB_OK); MsgHook.Hook("User32.dll","MessageBoxA",(PROC)MyMessageBoxA);
MessageBox(NULL,"test","test",MB_OK);
MsgHook.UnHook(); return ;
}

最后的结果是弹出3个对话框,第一个是正常调用,后两个是跳转到自己的自定义函数里进行两次调用原函数,当然是恢复了hook之后。

这个例子是lnline hook本进程,后面会学习lnline hook非本进程。

lnline Hook初试的更多相关文章

  1. svnserver hook python

    在使用中可能会遇到的错误排除 :1.Error: svn: 解析"D:\www\test"出错,或svn: E020024: Error resolving case of 'D: ...

  2. Android Hook技术

    原文:http://blog.csdn.net/u011068702/article/details/53208825 附:Android Hook 全面入侵监听器 第一步.先爆项目demo照片,代码 ...

  3. Frida HOOK微信实现骰子作弊

    由于微信摇骰子的功能在本地进行随机后在发送,所以存在可以hook掉判断骰子数的方法进行修改作弊. 1.frida实现hook java层函数1)写个用来测试的demo,当我们点击按钮的时候会弹出窗口显 ...

  4. java的关闭钩子(Shutdown Hook)

    Runtime.getRuntime().addShutdownHook(shutdownHook);    这个方法的含义说明:        这个方法的意思就是在jvm中增加一个关闭的钩子,当jv ...

  5. IDT HOOK思路整理

    IDT(中断描述符表)分为IRQ(真正的硬件中断)和软件中断(又叫异常). HOOK的思路为,替换键盘中断处理的函数地址为自己的函数地址.这样在键盘驱动和过滤驱动之前就可以截获键盘输入. 思路确定之后 ...

  6. Android Hook 借助Xposed

    主要就是使用到了Xposed中的两个比较重要的方法,handleLoadPackage获取包加载时候的回调并拿到其对应的classLoader:findAndHookMethod对指定类的方法进行Ho ...

  7. caffe初试(一)happynear的caffe-windows版本的配置及遇到的问题

    之前已经配置过一次caffe环境了: Caffe初试(一)win7_64bit+VS2013+Opencv2.4.10+CUDA6.5配置Caffe环境 但其中也提到,编译时,用到了cuda6.5,但 ...

  8. iOS App 无代码入侵的方法hook

    继续Objective-C runtime的研究 最近公司项目在做用户行为分析 于是App端在某些页面切换,交互操作的时候需要给统计系统发送一条消息 在几十个Controller 的项目里,一个一个地 ...

  9. Hook机制里登场的角色

    稍有接触过 WordPress 主题或插件制作修改的朋友,对 WordPress 的Hook机制应该不陌生,但通常刚接触WordPress Hook 的新手,对其运作原理可能会有点混乱或模糊.本文针对 ...

随机推荐

  1. OpenVPN 部署

    https://blog.frognew.com/2017/09/installing-openvpn.html#21-%E5%AE%89%E8%A3%85%E4%BE%9D%E8%B5%96 为了方 ...

  2. java 简洁的分层实现

    1.分页实现 分页实现是将所有查询结果保存在session对象或集合中,翻页时从session对象或集合中取出一页所需的数据显示.但是这种方法有两个最主要的缺点:一是用户看到的可能是过期数据:二是如果 ...

  3. GNU Radio 入门培训

    1. GNU Radio介绍 1.1 什么是GNU Radio GNU Radio是一个完全开源的软件无线电结构平台,它可以用来设计和仿真,也可以用来连接真实的无线电系统.GNU Radio是一个高度 ...

  4. 【备忘】mysql主从设置

    主(master)192.168.1.10机器设置: [root@vm-vagrant mysql]# vi my.cnf [mysqld]节点下添加以下配置server-id=1log-bin=my ...

  5. bzoj 3867: Nice boat

    题意:给定一个正整数序列,操作是1.区间赋值,2.区间大于x的数与x取gcd,最后输出操作后的序列 用平衡树维护相同数组成的连续段,每次操作至多增加两个连续段,操作2记录一下区间最小值然后暴力修改,每 ...

  6. [转]java中byte转换int时为何与0xff进行与运算

    在剖析该问题前请看如下代码public static String bytes2HexString(byte[] b) {  String ret = "";  for (int ...

  7. ubuntu下面搭建SolrCloud集群

    首先要先把ubuntu环境搭建好,配置好静态IP,我这边配置的是3台机子,solr搭建集群至少是2台. 192.168.0.15  主机 192.168.0.16  从机 192.168.0.17  ...

  8. 二十二 synchronized同步方法

    一 Synchronized锁: 1 synchronized取得的锁都是对象锁,而不是把一段代码或方法加锁. synchronized是给该方法的实例对象加锁.如果多个线程访问的是同一个对象  的s ...

  9. python学习 (三十五) logging

    1  demo import logging # log level: # DEBUG # INFO # Warning # Error # CRITICAL logging.basicConfig( ...

  10. 十七.jQuery源码解析之入口方法Sizzle(1)

    函数Sizzle(selector,context,results,seed)用于查找与选择器表达式selector匹配的元素集合.该函数是选择器引擎的入口. 函数Sizzle执行的6个关键步骤如下: ...