【加密与解密(第四版)】第十三章笔记

news2024/11/17 4:15:31

第十三章 HOOK技术

13.1 Hook概述

IAT HOOK(改地址)

BOOL IAT_InstallHook()

{

BOOL bResult = FALSE ;

HMODULE hCurExe = GetModuleHandle(NULL);

PULONG_PTR pt ;

ULONG_PTR OrginalAddr;

bResult = InstallModuleIATHook(hCurExe,"user32.dll","MessageBoxA",(PVOID)My_MessageBoxA,&pt,&OrginalAddr);

if (bResult)

{

printf("[*]Hook安装完毕! pThunk=0x%p  OriginalAddr = 0x%p\n",pt,OrginalAddr);

g_PointerToIATThunk = pt ;

OldMessageBox = (PFN_MessageBoxA)OrginalAddr ;

}

return bResult;



}



//************************************

// FullName:    InstallModuleIATHook

// Description: 为指定模块安装IAT Hook

// Access:      public

// Returns:     BOOL

// Parameter:   HMODULE hModToHook , 待Hook的模块基址

// Parameter:   char * szModuleName , 目标函数所在模块的名字

// Parameter:   char * szFuncName , 目标函数的名字

// Parameter:   PVOID DetourFunc , Detour函数地址

// Parameter:   PULONG * pThunkPointer , 用以接收指向修改的位置的指针

// Parameter:   ULONG * pOriginalFuncAddr , 用以接收原始函数地址

//************************************

BOOL InstallModuleIATHook(

    HMODULE hModToHook,// 要钩取的模块的句柄

    char *szModuleName,// 要钩取的模块的名称

    char *szFuncName,// 要钩取的函数的名称

    PVOID DetourFunc,// 替换原始函数的钩子函数的地址

    PULONG_PTR *pThunkPointer,// 用于存储指向导入地址的指针的指针

    ULONG_PTR *pOriginalFuncAddr// 用于存储原始函数地址的指针

    )

{

    PIMAGE_IMPORT_DESCRIPTOR  pImportDescriptor; // 指向导入描述符表的指针

    PIMAGE_THUNK_DATA         pThunkData; // 指向导入函数表的指针

    ULONG ulSize; // 导入描述符表的大小

    HMODULE hModule=0; // 加载模块的句柄

    ULONG_PTR TargetFunAddr; // 目标函数的地址

    PULONG_PTR lpAddr; // 导入地址的指针

    char *szModName; // 当前模块的名称

    BOOL result = FALSE ; // 返回值,默认为失败

    BOOL bRetn = FALSE; // 操作结果,默认为失败



    hModule = LoadLibrary(szModuleName); // 加载要钩取的模块

    TargetFunAddr = (ULONG_PTR)GetProcAddress(hModule,szFuncName); // 获取要钩取的函数的地址

    printf("[*]Address of %s:0x%p\n",szFuncName,TargetFunAddr); // 输出目标函数的地址

    printf("[*]Module To Hook at Base:0x%p\n",hModToHook); // 输出要钩取的模块的基地址

    pImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)ImageDirectoryEntryToData(hModToHook, TRUE,IMAGE_DIRECTORY_ENTRY_IMPORT, &ulSize); // 获取导入描述符表的地址

    printf("[*]Find ImportTable,Address:0x%p\n",pImportDescriptor); // 输出导入描述符表的地址

    while (pImportDescriptor->FirstThunk) // 遍历导入描述符表,直到遇到空描述符

    {

        szModName = (char*)((PBYTE)hModToHook+pImportDescriptor->Name) ; // 获取当前模块的名称

        printf("[*]Cur Module Name:%s\n",szModName); // 输出当前模块的名称

        if (stricmp(szModName,szModuleName) != 0) // 若当前模块名称与要钩取的模块名称不匹配

        {

            printf("[*]Module Name does not match, search next...\n"); // 输出模块名称不匹配的信息

            pImportDescriptor++; // 继续下一个导入描述符表

            continue; // 继续下一次循环

        }

        // 程序的导入表处理完毕后OriginalFirstThunk可能是无效的,不能再根据名称来查找,而是遍历FirstThunk直接根据地址判断

        pThunkData = (PIMAGE_THUNK_DATA)((BYTE *)hModToHook + pImportDescriptor->FirstThunk); // 获取导入函数表的地址

        while(pThunkData->u1.Function) // 遍历导入函数表,直到遇到空条目

        {

            lpAddr = (ULONG_PTR*)pThunkData; // 获取导入地址的指针

            // 找到了地址

            if((*lpAddr) == TargetFunAddr) // 如果导入地址与目标函数地址相等

            {

                printf("[*]Find target address!\n"); // 输出找到目标地址的信息

                // 通常情况下导入表所在内存页都是只读的,因此需要先修改内存页的属性为可写

                DWORD dwOldProtect; // 旧的保护属性

                MEMORY_BASIC_INFORMATION  mbi; // 内存页信息结构体

                VirtualQuery(lpAddr,&mbi,sizeof(mbi)); // 获取内存页的信息

                bRetn = VirtualProtect(mbi.BaseAddress,mbi.RegionSize,PAGE_EXECUTE_READWRITE,&dwOldProtect); // 修改内存页的保护属性为可写

                if (bRetn) // 如果修改成功

                {

                    // 内存页属性修改成功,继续下一步操作,先保存原始数据

                    if (pThunkPointer != NULL) // 如果指针不为空

                    {

                        *pThunkPointer = lpAddr ; // 将导入地址的指针赋值给pThunkPointer

                    }

                    if (pOriginalFuncAddr != NULL) // 如果指针不为空

                    {

                        *pOriginalFuncAddr = *lpAddr ; // 将导入地址的值赋值给pOriginalFuncAddr

                    }

                    // 修改地址

                    *lpAddr = (ULONG_PTR)DetourFunc; // 将导入地址的值修改为钩子函数的地址

                    result = TRUE ; // 操作成功

                    // 恢复内存页的属性

                    VirtualProtect(mbi.BaseAddress,mbi.RegionSize,dwOldProtect,0); // 恢复内存页的保护属性

                    printf("[*]Hook ok.\n"); // 输出钩子成功的信息

                }

               

                break; // 跳出循环

            }

            //---------

            pThunkData++; // 继续下一个导入函数表条目

        }

        pImportDescriptor++; // 继续下一个导入描述符表

    }

   

    FreeLibrary(hModule); // 释放加载的模块

    return result; // 返回操作结果

}

InLine Hook(改内容)

13.2  HOOK的分类

名目繁多的 Hook,总结起来其实只有两种:Address Hook和Inline Hook。

Address Hook:IAT、EAT、user32.dll的回调函数表、IDT(中断描述符表)、SSDT(系统服务描述符表)、C++类的虚函数表、COM接口的功能函数表、处理例程地址、特殊寄存器中的地址、特定的函数指针

Inline Hook:

基于异处理的HOOK

13.3 HOOK位置的挑选

影响最小的 Hook:应用程序中的call Hook,可精确到特定位置对特定 API的调用。

影响最大的Hook:在系统内核中,大部分Hook的位置都会影响整个系统的调用过程,越往下就越明显。

在内核中,KiFastCallEnlry和KeServiceDescriptorTable(含 Shadow)是两个绝佳的Hook位置。

13.4 HOOK的典型过程

Address Hook 的实施过程:定义Detour()函数、定义函数指针、查表(遍历匹配)替换原函数地址、关闭写保护、写入Detour()函数的地址

Inline Hook 的实施过程:确定 Hook方式及需要在Trampoline 中执行的指令、准备TrampolineFun函数、准备jmp指令并写入、CALLL HOOK

二次HOOK

13.5  Detour函数的典型用法

检查参数、检查结果、拦截调用或下发

13.6  HOOK中的注意事项

多线程安全、保存和恢复现场、注意返回值、避免重入

13.7  HOOK在X64平台上的新问题

指针的定义与操作、内存地址对齐、PE格式、调用约定的变化、跳转指令的问题、PatchGuard问题

13.8  HOOK技术的应用

实现增强的二次开发或补丁、信息截获、安全防护

13.9  HOOK的检测、恢复与对抗

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

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

相关文章

若依启动run-modules-system.bat报错问题解决方案

在启动run-modules-system.bat时遇到了一些问题,在网上搜索无果后,排查解决完毕 1.启动nacos时,报错如下 Error creating bean with name grpcClusterServer: Invocation of init method failed; nested exception is java.io.IOException: Failed to bind to address 0.0.0.0…

CSS精灵图

详细内容见B站黑马程序员网课: 【前端Web开发HTML5CSS3移动web视频教程,前端web入门首选黑马程序员】https://www.bilibili.com/video/BV1kM4y127Li?p99&vd_source06e5549bf018e111f4275c259292d0da

智慧林业云巡平台 客户端和移动端(支持语音和视频)自动定位巡护,后端离线路线监测

目前现状 无法客观、方便地掌握护林员的到位情况,因而无法有效地保证巡护人员按计划要求,按时按周期对所负责的林区开展巡护,使巡护工作的质量得不到保证。遇到火情、乱砍滥伐等灾情时无法及时上报处理,现场状况、位置等信息描述…

代码随想录——左叶子之和(Leetcode404)

题目链接 BFS 队列 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val val; }* TreeNode(int val, TreeNode left, TreeNode right)…

小程序使用vant组件库

一:下载组件库 在小程序内npm下载的包 vant组件库官网:快速上手 - Vant Weapp (youzan.github.io) 1)首先有有package.json文件,没有的话则先初始化 即使通过package.json去下载包,也需要有,可以观察下载的包. 2)下载包 3)构建npm包 下载包之后存储在node_modules内,但是我们…

ChatGPT原创指令大全(持续更新)

随着ChatGPT在互联网上的使用越来越多,但很多人在使用ChatGPT的过程中会觉得得到的答案并不是很精准。究其原因其实是你给它的命令不够准确、不够到位。实际现在网上已经很多关于ChatGPT的网站,可以快速生成带有快捷键的ChatGPT指令。但是对于不熟悉Chat…

Leetcode3161. 物块放置查询(Go语言的红黑树 + 线段树)

题目截图 题目分析 每次1操作将会分裂成两块区间长度,以最近右端点记录左侧区间的长度即可 因此涉及到单点更新和区间查询 然后左右侧最近端点则使用redBlackTree,也就是python中的sortedlist ac code type seg []int// 把 i 处的值改成 val func (t …

44、Flink 的 Interval Join 详解

Interval Join Interval join 组合元素的条件为:两个流(暂时称为 A 和 B)中 key 相同且 B 中元素的 timestamp 处于 A 中元素 timestamp 的一定范围内,即 b.timestamp ∈ [a.timestamp lowerBound; a.timestamp upperBound] 或…

HTML静态网页成品作业(HTML+CSS)——动漫熊出没介绍网页(3个页面)

🎉不定期分享源码,关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 🏷️本套采用HTMLCSS,未使用Javacsript代码,共有3个页面。 二、作品演示 三、代…

美股重大变化,结算周期将从T+2变成T+1

KlipC报道:当地时间5月28日,美国证券交易结算时间将从“T2”改为“T1”。美股迎来历史性时刻。 目前,美股实行的是T0交易制度,T2结算交割制度。即投资者买入一只股票,当天可以卖出,但是交易的结算并不是立…

【国信华源:以专业服务,协助水利厅抵御强暴雨】

5月18日-19日,广西出现入汛以来最强暴雨天气过程,钦州、防城港、北海、南宁等地出现特大暴雨,多地打破降雨量极值。国信华源技术团队积极行动驻守一线,为打好山洪灾害防御的提前战、主动战提供了技术支撑。 5月17日18时&#xff0…

简单的利用有限脉冲响应(FIR)滤波器对心电信号进行降噪(Python)

代码很简单。 import numpy as np import matplotlib.pyplot as plt#------------------------Bandstop Filter Function------------------------ def bandstop(M,low,high,Fs):#50Hz removalk1 int( (low/Fs)*M) # index 22k2 int( (high/Fs)*M) # index 27#DC removalk0 …

移动应用程序设计详解:基本概念和原理

移动应用程序设计是什么? 一般来说,应用程序设计师的核心职责是让用户有体验应用的欲望,而开发者负责让它正常工作。移动应用程序设计包括用户界面 (UI) 和用户体验 (UX)。设计者负责应用程序的整体风格,包括配色方案、字体选择、…

NV-LIO:一种基于法向量的激光雷达-惯性系统(LIO)

论文:NV-LIO: LiDAR-Inertial Odometry using Normal Vectors Towards Robust SLAM in Multifloor Environments 作者:Dongha Chung, Jinwhan Kim NV-LIO:一种基于法向量的激光雷达-惯性系统(LIO)NV-LIO利用从激光雷…

活动策划大师课:应对意外,如何巧妙化解风险?

活动策划,听起来光鲜亮丽,实则暗潮涌动。 作为活动后的幕后英雄,我们得随时准备迎接各种突发状况,你至少需要做好以下四点来应对和处理意外情况和风险: 一、应急管理团队:构建你的应急梦之队 首先&#…

第二证券炒股知识:股票破发后怎么办?

当一只新股的价格跌破其发行价时,往往会受到商场出资者的关注。关于股票破发后怎么办,第二证券下面就为我们具体介绍一下。 股票破发是指股票的商场价格低于其发行价格或最近一次增发价格,股票破发往往是由于多种要素共同作用的结果&#xf…

JS中的数组很重要,怎样定义(声明)

为什么呢?在java中有集合,数组的作用就弱了,其高光时刻基本都被集合代替了。在JS中没有集合,数组就有点忙不过来了。你说它重要不重要?! 在JS中,怎样定义一个数组呢? 数组的声明方…

【C++】vector常见的使用方式

前言:在上一篇中我们讲到了string类的模拟实现,今天我们将进一步的去学习vector的一些常用的使用方法。 💖 博主CSDN主页:卫卫卫的个人主页 💞 👉 专栏分类:高质量C学习 👈 💯代码仓…

IPC$横向移动

一. IPC$介绍和连接方式 1. IPC$介绍 IPC( Internet Process Connection)共享,是为了实现进程间通信而开放的命名管道。IPC可以通过验证用户名和密码获得相应的权限,通常在远程管理计算机和查看计算机的共享资源时使用。通过ipc$,可以与目标机器建立连接。利用这个…

css3 笔记02

目录 01 过渡 02 rotate旋转 03 translate函数 04 真正的3D 05 动画 06 阴影 07 自定义字体库 08 自定义动画库 01 过渡 过渡属性的使用: transition-property:要过渡的css属性名 多个属性用逗号隔开 过渡所有属性就写all transition-duration: 过渡的持续时间 s秒 …