inline hook 实际上就是指 通过改变目标函数头部的代码来使改变后的代码跳转到我们自己设置的一个函数里,产生hook。

今天就拿MessageBoxA这个api函数来做实验。功能就是当程序调用MessageBoxA 时,我们打印出MessageBoxA的参数

大概代码结构应该是这样

typedef int (WINAPI*MessageBox_type) (__in_opt HWND hWnd,__in_opt LPCSTR lpText,__in_opt LPCSTR lpCaption,__in UINT uType) ;MessageBox_type RealMessageBox;//我们自己的MessageBox,每调用MessageBox都要跳到myMessageBox来处理
int WINAPImyMessageBox(__in_opt HWND hWnd,__in_opt LPCSTR lpText,__in_opt LPCSTR lpCaption,__in UINT uType)
{//下面打印MessageBox参数printf("hwnd:%8X lpText:%s lpCaption:%s,uType:%8X",hWnd,lpText,lpCaption,uType); return RealMessageBox(hWnd,lpText,lpCaption,uType); //现在开始调用真正的MessageBox
}VOID HookMessageBoxA()
{}int _tmain(int argc, _TCHAR* argv[])
{HookMessageBoxA();  //hook操作::MessageBoxA(NULL,"hook test","tip",MB_OK); //执行api MessageBoxreturn 0;
}

我们先看看汇编是怎样调用MessageBoxA的

首先看到,MessageBoxA里面

mov edi,edi 
mov ebp 
mov ebp,esp 
刚好是5个字节,5个字节可以做一个远jmp

直接汇编改成我们自己的jmp

改后结果如下

单步执行发现hook成功。但程序崩溃。原因主要是由于

我们破坏了真正的MessageBox使们想要调用真正的MessageBox时也会调用失败了,所以我们要调用真正的MessageBox时要加上头部被我们换掉的部分,我们要内联汇编,里面不能含有编译器自动添加的代码,所以在myMessageBox头部要加上 _declspec(naked)

vs2010的debug版本每执行一个函数都要 cmp esi,esp 来验证堆栈的。所以还要加一句push esi 和pop esi

//我们自己的MessageBox,每调用MessageBox都要跳到myMessageBox来处理
_declspec(naked)  void WINAPImyMessageBox(__in_opt HWND hWnd,__in_opt LPCSTR lpText,__in_opt LPCSTR lpCaption,__in UINT uType)
{__asm{PUSH ebpmov ebp,esp/*vs2010 debug 编译后的代码由于要cmp esi esp来比较堆栈。所以这里在调用非__asm函数前push一下esi*/push esi}//下面打印MessageBox参数printf("hwnd:%8X lpText:%s lpCaption:%s,uType:%8X",hWnd,lpText,lpCaption,uType); __asm{/*vs2010 debug 编译后的代码由于要cmp esi esp来比较堆栈。所以这里在调用非__asm函数前push一下esi*/pop esimov ebx,RealMessageBoxadd ebx,5jmp ebx}
}

下面说一下用代码来写MessageBoxA着呢5个字节

首先要懂得 JMP指令转换公式推导  不懂的话 看 http://www.cnblogs.com/zhangdongsheng/archive/2012/12/06/2804234.html

先声明一个JMP结构体。注意前面加 #pragma pack(1)来避免内存对齐的一些规则

#pragma pack(1)
typedef struct _JMPCODE
{BYTE jmp;DWORD addr;
}JMPCODE,*PJMPCODE;

接下来写hook函数

VOID HookMessageBoxA()
{JMPCODE jcode;jcode.jmp = 0xe9;//jmpjcode.addr = (DWORD)myMessageBox - (DWORD)RealMessageBox - 5; RealMessageBox = MessageBoxA;::WriteProcessMemory(GetCurrentProcess(),MessageBoxA,&jcode,sizeof(JMPCODE),NULL);
}

现在测试成功。

完整源代码如下:

// hook_blog_writer.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <windows.h>
#include <stdio.h>typedef int (WINAPI*MessageBox_type) (__in_opt HWND hWnd,__in_opt LPCSTR lpText,__in_opt LPCSTR lpCaption,__in UINT uType) ;MessageBox_type RealMessageBox = MessageBoxA;//我们自己的MessageBox,每调用MessageBox都要跳到myMessageBox来处理
_declspec(naked)  void WINAPImyMessageBox(__in_opt HWND hWnd,__in_opt LPCSTR lpText,__in_opt LPCSTR lpCaption,__in UINT uType)
{__asm{PUSH ebpmov ebp,esp/*vs2010 debug 编译后的代码由于要cmp esi esp来比较堆栈。所以这里在调用非__asm函数前push一下esi*/push esi}//下面打印MessageBox参数printf("hwnd:%8X lpText:%s lpCaption:%s,uType:%8X",hWnd,lpText,lpCaption,uType); __asm{/*vs2010 debug 编译后的代码由于要cmp esi esp来比较堆栈。所以这里在调用非__asm函数前push一下esi*/pop esimov ebx,RealMessageBoxadd ebx,5jmp ebx}
}#pragma pack(1)
typedef struct _JMPCODE
{BYTE jmp;DWORD addr;
}JMPCODE,*PJMPCODE;VOID HookMessageBoxA()
{JMPCODE jcode;jcode.jmp = 0xe9;//jmpjcode.addr = (DWORD)myMessageBox - (DWORD)RealMessageBox - 5; RealMessageBox = MessageBoxA;::WriteProcessMemory(GetCurrentProcess(),MessageBoxA,&jcode,sizeof(JMPCODE),NULL);
}int _tmain(int argc, _TCHAR* argv[])
{HookMessageBoxA();  //hook操作::MessageBoxA(NULL,"hook test","tip",MB_OK); //执行api MessageBoxreturn 0;
}

出处:http://www.cnblogs.com/zhangdongsheng/
作者:张东升 QQ:290387340

学习windows 应用层 inline hook 原理总结相关推荐

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

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

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

    前言 在上节中介绍了 InlineHook 钩子函数,主要是通过jmp 目标地址(转为机器码E9 偏移量) 来实现的,是修改被Hook函数首地址处的 5个字节的内容.这里再介绍另一种方法,修改被Hoo ...

  3. Inline Hook

    @author: dlive IAT Hook时如果要钩取的API不在IAT中(LoadLibrary后调用),则无法使用该技术.而Inline Hook不存在这个限制. 0x01 Inline Ho ...

  4. Inline Hook Syscall 详解

    文章目录 1. hook一般syscall 2. hook stub syscall 2.1 stub_xxx 原理 2.2 方法1:hook `stub_xxx` 2.3 方法2:hook `cal ...

  5. Windows驱动开发学习笔记(六)—— Inline HOOK

    Windows驱动开发学习笔记(六)-- Inline HOOK SSDT HOOK Inline Hook 挂钩 执行流程 脱钩 实验一:3环 Inline Hook 实验二:0环 Inline H ...

  6. Windows下x86和x64平台的Inline Hook介绍

    原文链接:https://blog.csdn.net/PeaZomboss/article/details/129095200?spm=1001.2014.3001.5501 前言 我在之前研究文明6 ...

  7. API hook原理和实例快速入门(inline hook),以dll线程注入方式使用(win7-64bit)

    一个完整的hook,如果hook程序是以dll形式生成的,是分两步:1.完成dll本身的设计和生成,2.完成dll注入程序的设计和生成 本文完成第一步. 第二步在http://blog.csdn.ne ...

  8. Windows内核实验005 Inline Hook

    文章目录 准备工作 寻找Inline Hook的返回地址 编写代码 动态变化的返回地址 JmpTargetAddr Inline Hook基本框架 示例代码 实战HOOK KiTrap01 无需计算偏 ...

  9. inline hook学习

    vs2013编译 //inline hook 实际上就是指 通过改变目标函数头部的代码来使改变后的代码跳转至我们自己设置的一个函数里,产生hook.#include <windows.h> ...

最新文章

  1. 职场的你,如何《赢》?
  2. 宏基因组合种树第285期,胡杨专车
  3. [转自脚本之家] Javascript cookie 详解
  4. 深度学习之windows python faster rcnn 配置及demo运行
  5. 使用replace pioneer批量修改文件名
  6. Qt对话框的事件循环实例分析
  7. std::jthread与std::thread的区别
  8. console对象的方法log、info、warn、error的区别及几个实用的方法
  9. [SDOI2008]Cave 洞穴勘测
  10. java社区活跃度_Java并发编程-活跃度问题
  11. 荣大速印机维修手册_荣大佳文一体机(速印机)故障及排除方法
  12. Ambari安装之安装并配置Ambari-server(三)
  13. AcWing 棋盘挑战 dsf
  14. womic网络错误_WO Mic驱动程序下载
  15. linux根据uid反查用户名
  16. 此程序被组策略阻止,有关详细信息请联系管理员
  17. 关于浏览器加载不出图片的问题
  18. 关于视频后期美白的一些事
  19. android回环地址,Android WebRTC完整入门教程02: 本地回环
  20. python爬虫中遇到“\xb5”、“xa0”等字符时报错编码错误的处理方式

热门文章

  1. 重载练习3_实现重载的println方法
  2. HTTP_请求消息_请求行
  3. SpringBoot 上传多个文件
  4. mybatis 批量将list数据插入到数据库
  5. 使用Docker运行java项目需要注意的glibc依赖库问题
  6. ubuntu知道文件名查找文件路径
  7. Makefile(直接可以使用)
  8. Java开源诊断工具 Arthas 发布v3.1.0
  9. 关于github里readme编辑的方法
  10. 安卓开源项目周报0215