Windows系统编程(七)HotFixHook

InoolineHook需要读写两次内存(先HOOK,再还原),这种Hook方式,性能比较低,具有局限性。今天所讲的HotFixHOOK(热补丁)是InlineHook的升级版

Win32 API特殊性

Win32API的实现代码有这样的特点:起始指令为1个MOV EDI,EDI,上方有多个int3(称之为内存空白区),这些指令实际没有任何意义。

接下来我们通过观察MessageBoxA的反汇编代码来验证这个现象

如图所示,确实存在无意义的指令

HotFix HOOK

我们从上文了解到,Win32 API的实现代码中起始位置处存在一些无意义的指令,因此我们可以通过修改这些无意义的指令来实现HOOK操作。这种方法可以使得进程处于运行状态时临时更改进程内存中的库文件,因此被称为打热补丁,即HotFix HOOK

HOOK原理

如图是MessageBoxA的汇编代码实现处,我们借助这个图方便我们理解HOOK

修改Win32 API实现代码中的第一行指令为jmp,使之可以跳转到上方内存空白处。上方内存空白处修改为我们自己的代码,如执行某API。此时每当程序调用该API时,在执行第一行指令时,都会跳转到上方内存空白处执行我们自己的代码,而不会影响原API实际的函数功能实现

HOOK实现

接下来我们创建dll文件,实现HotFix HOOK

// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"
#include <Windows.h>BOOL Hook(const char * pszModuleName, const char * pszFuncName, PROC pfnHookFunc)//HOOK
{BYTE ShortJmp[2] = { 0xEB,0xF9 };//用于替换函数头两个字节mov edi, edi(8B FF)实现短跳上方五个字节BYTE NewCodes[5] = { 0xE9,0, };//替换短跳后的五个字节:一字节指令,四字节函数地址HMODULE hModule = GetModuleHandleA(pszModuleName);//获取目标HOOK函数所处模块的句柄FARPROC FunAddress = GetProcAddress(hModule, pszFuncName);//获取目标HOOK函数地址DWORD dwOldProtect = 0;//保存原有的内存属性VirtualProtect((LPVOID)((DWORD)FunAddress - 5), 7, PAGE_EXECUTE_READWRITE, &dwOldProtect);//修改五字节空白内存读写属性,注意修改的两个头字节一共七个字节DWORD dwFuncAddr = ((DWORD)pfnHookFunc - (DWORD)FunAddress);//计算要跳转的函数相对地址//注意换算结果:跳转函数地址 - E8指令地址处 - E8指令长度 == 跳转函数地址 - (原函数地址处 -  E8指令长度) -  E8指令长度 == 跳转函数地址 -  原函数地址处*(DWORD *)(NewCodes + 1) = dwFuncAddr;memcpy((LPVOID)((DWORD)FunAddress - 5), NewCodes, 5);memcpy(FunAddress, ShortJmp, 2);//修改内存VirtualProtect((LPVOID)((DWORD)FunAddress - 5), 7, dwOldProtect, &dwOldProtect);//恢复原有的内存属性//此时该程序中所有的原函数都被我们修改了,只要调用该函数,都会被HOOKreturn TRUE;
}BOOL UnHook(const char * pszModuleName, const char * pszFuncName)//卸载HOOK 
{BYTE ShortJmp[2] = { 0x8B,0xFF };//还原原有字节BYTE NewCodes[5] = { 0x90,0x90,0x90,0x90,0x90 };//恢复空白内存的一种方式:NOPHMODULE hModule = GetModuleHandleA(pszModuleName);FARPROC   = GetProcAddress(hModule, pszFuncName);DWORD dwOldProtect = 0;VirtualProtect((LPVOID)((DWORD)FunAddress - 5), 7, PAGE_EXECUTE_READWRITE, &dwOldProtect);memcpy((LPVOID)((DWORD)FunAddress - 5), NewCodes, 5);memcpy(FunAddress, ShortJmp, 2);VirtualProtect((LPVOID)((DWORD)FunAddress - 5), 7, dwOldProtect, &dwOldProtect);//此时原函数恢复原来的代码,卸载了HOOKreturn TRUE;
}typedef int //声明函数指针
(WINAPI
* fnMessageBoxA)(_In_opt_ HWND hWnd,_In_opt_ LPCSTR lpText,_In_opt_ LPCSTR lpCaption,_In_ UINT uType);int
WINAPI
MyMessageBoxA(_In_opt_ HWND hWnd,_In_opt_ LPCSTR lpText,_In_opt_ LPCSTR lpCaption,_In_ UINT uType)
{fnMessageBoxA NewFunc = (fnMessageBoxA)((DWORD)MessageBoxA + 2);//这是我们用于HOOK后执行的函数,其指向MessageBoxA并跳过头两个字节,防止被短跳而反复HOOK进入死循环。此时我们调用这个函数时,可以执行原来的MessageBoxA的功能 int bRet = NewFunc(hWnd, "hook", "hook", uType);//执行我们定义的函数,实际上就是执行MessageBoxA的有效部分return bRet;
}BOOL APIENTRY DllMain( HMODULE hModule,DWORD  ul_reason_for_call,LPVOID lpReserved)
{switch (ul_reason_for_call){case DLL_PROCESS_ATTACH:Hook("user32.dll", "MessageBoxA", (PROC)MyMessageBoxA);break;case DLL_THREAD_ATTACH:break;case DLL_THREAD_DETACH:break;case DLL_PROCESS_DETACH:UnHook("user32.dll", "MessageBoxA");break;}return TRUE;
}

 接下来我们将通过如下的代码,演示HotFix HOOK

#include <iostream>
#include <Windows.h>int main()
{MessageBoxA(NULL, "rkvir", "success", MB_OK);system("pause");MessageBoxA(NULL, "rkvir", "success", MB_OK);return 0;
}

首先运行程序,我们发现正常运行程序时,两次弹窗都是原来的窗口:

接下来我们再次重新运行程序,第一次弹窗是原来的窗口:

此时我们注入上文编写的dll文件,然后再次弹窗,发现弹窗变了,HOOK成功了:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/72540.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python Web应用开发之Flask框架——基础

一、前言 在即将开启的 Flask 学习之旅中,为了能够顺利掌握并运用 Flask 进行 Web 开发,您需要具备一定的基础知识,同时了解相应的运行环境。 需要你具备的知识:Python 编程语言、HTML、CSS、HTTP协议、数据库(如:MySQL、MongoDB) 本文所使用的环境:操作系统Windows…

TCP通讯与基于C#TCP通讯,跨窗收发消息Demo

TCP&#xff08;传输控制协议&#xff09;是一种面向连接的、可靠的、基于字节流的传输层通信协议。它广泛应用于互联网中的数据通信&#xff0c;如网页浏览、文件传输、电子邮件等。以下是TCP通信的基本概念和工作原理&#xff1a; 1. TCP的特点 面向连接&#xff1a;通信前…

【有源码】仿DeepSeek问答网站+SpringBoot+VUE3+对接DeepSeek API

今天带来一款优秀的项目&#xff1a;仿DeepSeek问答网站。 功能和官网差不多&#xff0c;也有历史上下文&#xff0c;流失对话等。 本文介绍了系统功能与部署安装步骤&#xff0c;如果您有任何问题&#xff0c;也请联系学姐&#xff0c;偶现在是经验丰富的程序员&#xff01; …

Ubuntu20.04双系统安装及软件安装(七):Anaconda3

Ubuntu20.04双系统安装及软件安装&#xff08;七&#xff09;&#xff1a;Anaconda3 打开Anaconda官网&#xff0c;在右侧处填写邮箱&#xff08;要真实有效&#xff01;&#xff09;&#xff0c;然后Submit。会出现如图示的Success界面。 进入填写的邮箱&#xff0c;有一封Ana…

洛谷 P2142 高精度减法(详解)c++

题目链接&#xff1a;P2142 高精度减法 - 洛谷 1.题目 2.算法原理 解法:模拟列竖式计算的过程 先用字符串读入&#xff0c;然后拆分每一位&#xff0c;逆序放进数组中利用数组&#xff0c;模拟列竖式减法的过程 在这两步之前要多加一步&#xff0c;在模拟解法的过程&#…

在 MyBatis 中,若数据库字段名与 SQL 保留字冲突解决办法

在 MyBatis 中&#xff0c;若数据库字段名与 SQL 保留字冲突&#xff0c;可通过以下方法解决&#xff1a; 目录 一、使用转义符号包裹字段名二、通过别名映射三、借助 MyBatis-Plus 注解四、全局配置策略&#xff08;辅助方案&#xff09;最佳实践与注意事项 一、使用转义符号…

ThreadLocal解析

1. ThreadLocal的定义与核心作用 ThreadLocal是Java中用于实现线程局部变量的工具类。它为每个线程提供独立的变量副本&#xff0c;使得每个线程访问的是自己的数据&#xff0c;从而避免多线程环境下的资源共享问题&#xff0c;实现线程隔离。 例如&#xff0c;解决SimpleDate…

Kafka零拷贝

Kafka为什么适用零拷贝&#xff0c;其他存储结构不适用&#xff1f; Kafka 采用的是日志存储模型&#xff0c;数据通常是顺序写入、顺序读取&#xff0c;并且它的消费模式是 “读完即走”&#xff08;一次性读取并发送给消费者&#xff09;&#xff0c;这与零拷贝的特性完美匹…

微服务组件详解——sentinel

1.启动sentinel&#xff1a; 下载jar sentinel-dashboard-1.8.0.jar 使用以下命令直接运行 jar 包&#xff08;JDK 版本必须≥ 1.8&#xff09;&#xff1a; java -Dserver.port9999 -jar D:\sentinel-dashboard-1.8.0.jar 控制台访问地址&#xff1a;http://localhost:9999…

AI数据分析:deepseek生成SQL

在当今数据驱动的时代&#xff0c;数据分析已成为企业和个人决策的重要工具。随着人工智能技术的快速发展&#xff0c;AI 驱动的数据分析工具正在改变我们处理和分析数据的方式。本文将着重介绍如何使用 DeepSeek 进行自动补全SQL 查询语句。 我们都知道&#xff0c;SQL 查询语…

动态规划01背包问题系列一>目标和

目录 题目分析及优化&#xff1a;状态表示&#xff1a;状态转移方程&#xff1a;初始化&#xff1a;填表顺序&#xff1a;返回值&#xff1a;代码呈现&#xff1a;优化&#xff1a;代码呈现&#xff1a; 题目分析及优化&#xff1a; 状态表示&#xff1a; 状态转移方程&#xf…

Linux 基础---sudo权限 修改文件所属人、用户所属组

sudo 概念&#xff1a;让普通用户使用管理员权限执行一些操作&#xff08;root&#xff09; 在命令前加上sudo 即可 修改文件所属人、所属组

HMC7043和HMC7044芯片配置使用

一,HMC7043芯片 MC7043独特的特性是对14个通道分别进行独立灵活的相位管理。所有14个通道均支持频率和相位调整。这些输出还可针对50 Ω或100 Ω内部和外部端接选项进行编程。HMC7043器件具有RF SYNC功能,支持确定性同步多个HMC7043器件,即确保所有时钟输出从同一时钟沿开始…

【动手实验】TCP半连接队列、全连接队列实战分析

本文是对 从一次线上问题说起&#xff0c;详解 TCP 半连接队列、全连接队列 这篇文章的实验复现和总结&#xff0c;借此加深对 TCP 半连接队列、全连接队列的理解。 实验环境 两台腾讯云服务器 node2&#xff08;172.19.0.12&#xff09; 和 node3&#xff08;172.19.0.15&am…

Springboot整合WebSocket+Redis以及微信小程序如何调用

一、 Springboot整合WebSocket 1. 引入socket依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId> </dependency>引入依赖后需要刷新maven,Websocket的版本默认跟随S…

影刀RPA开发拓展--SQL常用语句全攻略

前言 SQL&#xff08;结构化查询语言&#xff09;是数据库管理和操作的核心工具&#xff0c;无论是初学者还是经验丰富的数据库管理员&#xff0c;掌握常用的 SQL 语句对于高效管理和查询数据都至关重要。本文将系统性地介绍最常用的 SQL 语句&#xff0c;并为每个语句提供详细…

大模型训练微调技术介绍

大模型训练微调技术是人工智能领域中的一项重要技术&#xff0c;旨在通过少量特定领域的数据对预训练模型进行进一步训练&#xff0c;使其更好地适应具体任务或应用场景。以下是关于大模型训练微调技术的详细介绍&#xff1a; 1. 微调技术的定义与意义 微调&#xff08;Fine-…

生态安全相关

概念&#xff1a;生态安全指一个国家具有支撑国家生存发展的较为完整、不受威胁的生态系统&#xff0c;以及应对内外重大生态问题的能力。 &#xff08;1&#xff09;国外生态安全的研究进展 国际上对生态安全的研究是从“环境”与“安全”之间的关系展开的。开始的阶段&#x…

2024年第十五届蓝桥杯大赛软件赛省赛Python大学A组真题解析《更新中》

文章目录 试题A: 拼正方形(本题总分:5 分)解析答案试题B: 召唤数学精灵(本题总分:5 分)解析答案试题C: 数字诗意解析答案试题D:回文数组试题A: 拼正方形(本题总分:5 分) 【问题描述】 小蓝正在玩拼图游戏,他有7385137888721 个2 2 的方块和10470245 个1 1 的方块,他需…

《张一鸣,创业心路与算法思维》

张一鸣&#xff0c;多年如一日的阅读习惯。 爱读人物传记&#xff0c;称教科书式人类知识最浓缩的书&#xff0c;也爱看心理学&#xff0c;创业以及商业管理类的书。 冯仑&#xff0c;王石&#xff0c;联想&#xff0c;杰克韦尔奇&#xff0c;思科。 《乔布斯传》《埃隆马斯…