前言

在上节中介绍了 InlineHook 钩子函数,主要是通过jmp 目标地址(转为机器码E9 偏移量) 来实现的,是修改被Hook函数首地址处的 5个字节的内容。这里再介绍另一种方法,修改被Hook函数首地址处的7字节的内容。我们看下图的汇编指令

之前是jmp 目标地址(5字节),这次是将目标地址放到 eax寄存器中 这里是2条汇编指令(00B417E4-00B417DF = 5字节 + JMP EAX占2字节 = 7字节)。他们有什么不一样呢?

mov eax,78563412
jmp eax
;上面的汇编指令 转为机器码为:
;B8 12345678
;FFE0

这里可以看出 B8为mov指令的机器码,jmp eax 对应的机器码为:FFE0,中间的机器码为目标地址了。这里刚好7个字节开头和结尾的 机器码 是固定的,变化的唯有中间4字节的 目标地址。故此我们可以修改 被Hook函数地址处的 7个字节即可,这样就不必计算偏移量了

示例效果

卸载钩子后


下钩子后

代码实现

InlineHook7.h

#pragma once#include <Windows.h>class CInlineHook7
{
public:CInlineHook7(void);~CInlineHook7(void);bool Hook(LPSTR strModuleName,LPSTR strHookFnName,FARPROC strHookCallFnName);bool UnHook();bool ReHook();
private:FARPROC m_pFnOrign; // 要Hook的函数地址BYTE m_bOld[7]; // 要Hook的函数 前7个字节BYTE m_bNew[7]; // 要Hook的函数 修改后的7个字节
};

InlineHook7.cpp

#include "StdAfx.h"
#include "InlineHook7.h"CInlineHook7::CInlineHook7(void)
{m_pFnOrign = NULL;memset(m_bOld,0,7);memset(m_bNew,0,7);
}CInlineHook7::~CInlineHook7(void)
{UnHook();
}bool CInlineHook7::Hook(LPSTR strModuleName,LPSTR strHookFnName,FARPROC strTargetFnAddr)
{bool ret = false;HMODULE hModule = GetModuleHandleA(strModuleName);if( hModule == NULL )goto end;m_pFnOrign = (FARPROC)GetProcAddress(hModule,strHookFnName);if( m_pFnOrign == NULL )goto end;SIZE_T numByte;// 保存被Hook函数的前7个字节if( ReadProcessMemory(GetCurrentProcess(),m_pFnOrign,m_bOld,7,&numByte) == 0 )goto end;// 构造jmp指令:mov eax,jmp 目标地址,对应的机器码:B8 4字节的目标地址 FFE0m_bNew[0] = 0xB8,m_bNew[5] = 0xFF,m_bNew[6] = 0xE0;// 中间4字节 放目标地址* (DWORD*)(&m_bNew[0]+1) = (DWORD)strTargetFnAddr;// 修改被Hook函数的前7个字节 改变其执行流程if( WriteProcessMemory(GetCurrentProcess(),m_pFnOrign,m_bNew,7,&numByte) == 0 ) goto end;ret = true;
end:return ret;
}bool CInlineHook7::UnHook()
{bool ret = false;// 卸载钩子,实际上即是将更改的7个字节还原SIZE_T numByte;if( m_pFnOrign != NULL && WriteProcessMemory(GetCurrentProcess(),m_pFnOrign,m_bOld,7,&numByte) != 0)ret = true;return ret;
}bool CInlineHook7::ReHook()
{bool ret = false;// 再次装钩子,更改要Hook的函数的前7字节 让其跳转到目标函数SIZE_T numByte;if( m_pFnOrign != NULL && WriteProcessMemory(GetCurrentProcess(),m_pFnOrign,m_bNew,7,&numByte) != 0)ret = true;return ret;
}

目标函数代码

// WINAPI 一定要声明,指明函数调用方式,这里和MessageBox保持一致
int WINAPI MyMessageBox7(HWND   hWnd,LPCSTR lpText, LPCSTR lpCaption,UINT   uType)
{g_inlineHookObj7.UnHook(); // 必须先卸载钩子 再才可以再次调用被Hook的函数,不然会进入死循环::MessageBoxA(hWnd ,"进入MyMessageBox7了","被Hook了,7字节InlineHook",MB_OK);::MessageBoxA(hWnd ,lpText,lpCaption,MB_OK);g_inlineHookObj7.ReHook();return 0;
}

完整项目

完整项目下载请在这里下载,没分也可以在这里github下载最新代码,如果可以的话,帮忙点个星星哟 。

C/C++:Windows编程—Inline Hook内联钩子(下)相关推荐

  1. C/C++:Windows编程—Inline Hook内联钩子(上)

    前言 先介绍下Windows中的Hook技术.Hook是Windows中提供的一种用以替换DOS下"中断"的系统机制,中文译为"挂钩"或"钩子&quo ...

  2. C/C++:Windows编程—IAT Hook实例(程序启动拦截)

    C/C++:Windows编程-IAT Hook实例(程序启动拦截) 前言+思路 本文默认读者有IAT Hook的相关的基础知识了哈,记录笔者在IAT Hook实战中遇到到问题以及解决思路. 笔者想实 ...

  3. 学习windows 应用层 inline hook 原理总结

    inline hook 实际上就是指 通过改变目标函数头部的代码来使改变后的代码跳转到我们自己设置的一个函数里,产生hook. 今天就拿MessageBoxA这个api函数来做实验.功能就是当程序调用 ...

  4. 【编程珠玑】内联函数和宏

    一,内联函数的用法 内联函数从源码层层看,有函数的结构,而在编译后,却不具备函数的性质.编译时,类似宏替换,使用函数体替换调用处的函数名.一般在代码中用inline修饰,但是能否形成内联函数,需要看编 ...

  5. Matlab编程与数据类型 -- 内联函数

    本微信图文详细介绍了Matlab中的内联函数.

  6. inline(内联函数)优缺点比较

    优点: 在内联函数被调用的地方进行代码展开,省去函数调用的时间,从而提高程序运行效率: 相比于宏函数,内联函数在代码展开时,编译器会进行语法安全检查或数据类型转换,使用更加安全: 缺点: 代码膨胀,产 ...

  7. Linux中内联函数,Windows 7上的内联函数的doParallel问题(适用于Linux)

    我在 Windows 7和 Linux(SUSE Server 11(x86_64))上都使用R 3.0.1.以下示例代码在Windows上产生错误,但在Linux上不产生错误.列出的所有工具箱在两台 ...

  8. castle windsor学习-----XML Inline Parameters 内联参数

    当使用XML配置的时候,可能要给组件指定各种各样的依赖 1.简单的参数 参数名称不区分大小写 <componentid="ping"type="Acme.Crm.S ...

  9. C/C++:Windows编程—Hook IE浏览器实现URL拦截及更改(上)

    Hook IE浏览器实现URL拦截及更改(上) 前言+思路 笔者这里有个需求,针对IE浏览器 用户访问URL 做一个判断,是否为 限制访问的url,如果是 在另一个软件上给与警告提示.笔者在拿到这个需 ...

最新文章

  1. 吴恩达deeplearning.ai最后一课上线,下一次得等多少年?
  2. RPM快速打包2017-08-21
  3. MapReduce基础开发之六Map多输入
  4. byte和bit的关系
  5. 各种推荐资料汇总。。。
  6. 怎样判断一个网站是不是前后端分离的?
  7. 解决Keras 与 Tensorflow 版本之间的兼容性问题,导入keras报错:module 'tensorflow.python.keras.backend' has no attribute
  8. 决定成败的人生细节(转)
  9. java比较两个对象_Java比较两个对象
  10. (附源码)springboot高校科研管理系统 毕业设计 222055
  11. 如何理解封装、继承和多态
  12. 常用思维模式大全(上)
  13. 5G即将全面普及,我们到底该换手机卡还是换手机?
  14. 二分专项训练(二分搜索+二分答案的十贰道例题及解析
  15. c++实现远程开关机
  16. 2015年3月CCF软考试题
  17. 信号转换芯片-LT8911EXB MIPI CSI/DSI转EDP
  18. vue--单页面应用和多页面应用
  19. 手摸手教学 - Docker(五) 超级爽!持久化数据库-bind mounts!
  20. 【BZOJ4455】【UOJ185】【ZJOI2016】小星星(树形DP,容斥原理)

热门文章

  1. Hemberg-lab单细胞转录组数据分析(七)-导入10X和SmartSeq2数据Tabula Muris
  2. 为啥我的Python这么慢 (一)
  3. 一场大病引起的诺贝尔2017年生理学奖角逐
  4. 14产品经理要懂的-人性的目的性
  5. android 本地ip获取,【android】 获取本地ip方法
  6. 烽火交换机s5800配置说明_如何通过单臂路由实现VLAN间通信?(配置篇)
  7. java生成j动态页面_zk动态产生多个页面的例子代码
  8. thinkphp5 定时任务
  9. Spring Boot笔记-validation的使用及统一异常处理
  10. Spring Boot笔记-@ComponentScan初步解析