导入地址表钩取技术解析

前置知识

导入表

在一个可执行文件需要用到其余DLL文件中的函数时,就需要用到导入表,用于记录需要引用的函数。例如我们编写的可执行文件需要用到CreateProcess函数,就需要用到kernel32.dll文件并且将其中的CreateProcess函数的信息导入到我们的可执行文件中,然后再调用。

为了管理这些导入函数,就构建了一个导入表进行统一的管理,简单来说,当我们编写的可执行文件中使用到导入函数就会去导入表中去搜索找到指定的导入函数,获取该导入函数的地址并调用。

image-20240424192254287

因此加载器在调用导入函数之前需要先找到导入表的所在处。在可执行文件映射到内存空间时,都是以Dos Header开始的,在该头部存在elfanew的字段,用于记录PE文件头的偏移,在PE文件头存在可选头的结构体,该结构体中存储数据目录项,其中就包括了导入表。因此在内存中我们需要通过Dos Header -> Nt Header -> Option Header -> Import Table的顺序获取导入表。

image-20240424193422922

这里使用《加密与解密》的图来看一下导入表的结构体,如下图。

image-20240424195938393

可以看到导入表涉及的变量非常多,这里重点关注OriginalFirstThunkFistThunk以及Name

  • Name:指向导入库的名称。
  • OriginalFistThunk:指向输入名称表,里面存储了导入函数的信息。
  • FirstThunk:指向输入地址表,可以看到在初始化的时候OriginalFistThunkFirstThunk指向的是同一块区域,即导入函数的信息。

输入名称表的结构体如下图,这里重点关注OrdinalAddressOfData

  • Ordinal:记录函数的序号,即导入函数以序号存储
  • AdressOfData:以函数命的形式记录导入函数

image-20240424201610702

那么INTIAT的区别在于,加载器会在从导入表中获取了导入函数名称后,会搜索该函数的名称并获取该函数的地址并填入到IAT中,因此在经历了加载器后,IAT中存储了实际地址。如下图。

image-20240424202850423

帮助网安学习,全套资料S信免费领取:
① 网安学习成长路径思维导图
② 60+网安经典常用工具包
③ 100+SRC分析报告
④ 150+网安攻防实战技术电子书
⑤ 最权威CISSP 认证考试指南+题库
⑥ 超1800页CTF实战技巧手册
⑦ 最新网安大厂面试题合集(含答案)
⑧ APP客户端安全检测指南(安卓+IOS)

导入地址表钩取技术

输入地址表钩取技术就是通过修改输入地址表的地址值,因此当调用该导入函数时会跳转到被篡改的地址上。

在钩取之前的状态如下图

image-20240424204535373

在钩取之后的状态如下图

image-20240424204853835

因此总结一下输入地址表钩取技术的流程

  • 确定需要钩取的导入函数
  • 获取输入地址表的地址
  • 在输入地址表中搜索需要钩取的导入函数地址并且将导入函数地址修改为自定义的函数
  • 在处理完之后需要在自定义函数中重新调用被钩取的函数

确定需要钩取的导入函数

首先确定可执行文件中存在什么导入函数,可以发现目标的可执行文件中导入了kernel32.dll的系统库,并且导入的CreateProcessW

image-20240424205932029

那么采用输入地址表钩取方法钩取CreateProcessW函数。

获取导入地址表的地址

根据DOS Header -> Nt Header -> Option Header ->Import Table的顺序进行搜索,即可获取导入地址表的地址。

代码如下

...//获取当前进程的基地址hMod = GetModuleHandle(NULL);pBase = (PBYTE)hMod;//进程的基地址是从DOS头开始的pImageDosHeader = (PIMAGE_DOS_HEADER)hMod;//通过e_lfanew变量获取NT头的偏移,然后加上基地址及NT头的位置pImageNtHeaders = (PIMAGE_NT_HEADERS)(pBase + pImageDosHeader->e_lfanew);//数据目录项下标为1的项是导入表pImageImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)(pImageNtHeaders->OptionalHeader.DataDirectory[1].VirtualAddress + pBase)
...

获取导入函数地址并修改

在获取导入地址表的地址后,首先通过遍历导入表的结构体,提取其中的Name字段,判断是否为我们需要钩取的导入库名。在匹配完成后则选择继续遍历IAT中的函数地址,找到需要钩取的函数地址,找到后则修改为自定义函数的地址。

image-20240424212559365

代码如下

    ...//遍历导入表项for (; pImageImportDescriptor->Name; pImageImportDescriptor++){//获取导入库的名称szLibName = (LPCSTR)(pImageImportDescriptor->Name + pBase);//比较导入库的名称,判断是否为kernel32.dllif (!_stricmp(szLibName, szDllName)){//获取IATPIMAGE_THUNK_DATA pImageThunkData = (PIMAGE_THUNK_DATA)(pImageImportDescriptor->FirstThunk + pBase);//获取导入函数地址for (; pImageThunkData->u1.Function; pImageThunkData++){//判断函数地址是否是需要钩取的函数地址,这里需要注意的是64位与32位地址的区别if (pImageThunkData->u1.Function == (ULONGLONG)pfnOrg){//修改IAT的权限为可写VirtualProtect(&pImageThunkData->u1.Function, 4, PAGE_EXECUTE_READWRITE, &dwOldProtect);//将原始的地址修改为自定义函数地址pImageThunkData->u1.Function = (ULONGLONG)pfnNew;//将权限恢复VirtualProtect(&pImageThunkData->u1.Function, 4, dwOldProtect, &dwOldProtect);return TRUE;}}}...

在自定义函数中重新调用被钩取的函数

这里需要注意的是,我们需要构建一个自定函数,该函数的返回类型与参数需要与钩取的函数一模一样,这样我们就可以获取所有参数的信息,然后篡改后重新传递给原始的导入函数,即可完成钩取。

image-20240424213549505

代码如下,这里篡改原始CreateaProcessW函数的第一个参数,使计算器

...LPCWSTR applicationName = L"C:\\Windows\\System32\\calc.exe";return ((LPFN_CreateProcessW)g_pOrgFunc)(applicationName,lpCommandLine,lpProcessAttributes,lpThreadAttributes,bInheritHandles,dwCreationFlags,lpEnvironment,lpCurrentDirectory,lpStartupInfo,lpProcessInformation);
...

完整代码:https://github.com/h0pe-ay/HookTechnology/blob/main/Hook-IAT/iat.cpp

调试

刚开始使用的是xdbg调试,但是用的不太习惯,后面改用WinDbg还可以源码调试,这里记录一下需要用到的操作与指令。

符号表与源码加载

在设置中可以选择源码默认的目录以及符号表默认的目录,符号文件则是利用Visutal Studio编译生成的pdb文件。

其中srv*c:\Symbols*https://msdl.microsoft.com/download/symbols是下载官方的符号表文件,这里可以选择删掉只调试我们设置的文件。不然每次都需要下载一遍影响时间。

源码文件也可以在侧边栏选择Open source file选项打开。

image-20240425103000930

DLL加载调试

由于钩取时需要先使用DLL注入技术将自定义的DLL文件注入进去,因此想要调试钩取过程则需要在DLL附着的时候打下断点。

利用sxe ld:xxx.dll即可在加载xxx.dll的时候打下断点。

利用sxe ud:xxx.dll即在卸载xxx.dll的时候打下断点。

image-20240425103802758

关闭优化调试

防止自定义函数中的变量被优化导致不方便单步调试,在Visual Studio中可以选择关闭优化进行编译。

image-20240425104053895

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

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

相关文章

项目-双人五子棋对战: 登录/注册模块的具体实现(2)

完整代码见: 邹锦辉个人所有代码: 测试仓库 - Gitee.com 模块详细讲解 用户信息定义(数据库) 用户名称: username 用户密码: password 用户天梯分数: score(假定初始值为1000) 用户游戏总场次: totalCount 用户获胜场次: winCount 用户表…

重复文件查找?6款电脑重复文件清理软件很靠谱!

在日常使用电脑过程中,很多人下载文件后常常会忘记它们的存在,导致同一份资料在系统中存在多个副本。虽然你可以手动删除 Windows 系统中的所有重复文件,但这样做很费时间,而且有可能会遗漏很多文件。 而且随着重复文件的不断累积…

IT运维工单系统/智能工单系统选型,需要注意哪些因素?

当今,IT运维服务成为企业降本增效、提升核心竞争力的重要一环。选型IT运维工单系统,提升企业IT运维服务能力,成为企业保持市场竞争力的重要举措。那么,IT运维工单系统选型需要注重哪些因素呢? 如今市面上的工单系统厂…

基于springboot实现餐饮管理系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现餐饮管理系统演示 摘要 互联网发展至今,无论是其理论还是技术都已经成熟,而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播,搭配信息管理工具可以很好地为人们提供服务。针对信息管理混乱,出错率…

贴合客户发展阶段 定义观测服务路径 -- DeepFlow金融银行业可观测性方案发布

金融信创是金融机构重点投入以及技术迭代的方向,经过多年阶段迭代,进入难度更大的核心系统、关键业务系统的更替阶段。近日,云杉网络凭借其在云原生可观测性领域的深厚积累,正式发布了DeepFlow金融银行业可观测性方案及服务,解决行业中普遍存在的分布式交易系统保障难、平台双轨…

使用 Navicat 工具查看 SQLite 数据库中的 PNG 图片

Navicat 是一款功能强大的数据库管理工具,支持多种数据库类型,包括 SQLite。它提供了一个直观的用户界面,可以轻松查看、编辑和管理数据库数据。 SQLite 是一种轻量级的嵌入式数据库,常用于移动应用程序和小型项目。它支持存储各…

构建LangChain应用程序的示例代码:2、使用LangChain库实现的AutoGPT示例:查找马拉松获胜成绩

AutoGPT 示例:查找马拉松获胜成绩 实现 https://github.com/Significant-Gravitas/Auto-GPT,使用LangChain基础组件(大型语言模型(LLMs)、提示模板(PromptTemplates)、向量存储(VectorStores)、嵌入(Embeddings)、工具(Tools))。…

量化投资分析平台 迅投 QMT(四)获取标的期权的代码

量化投资分析平台 迅投 QMT [迅投 QMT](https://www.xuntou.net/?user_code7NYs7O)我目前在使用有了底层标的如何获取期权的交易代码呢?上代码历史帖子 迅投 QMT 我目前在使用 两个月前(2024年4月)迅投和CQF有一个互动的活动,进…

Linux--Socket编程基础

一、Socket简介 套接字( socket )是 Linux 下的一种进程间通信机制( socket IPC ), 使用 socket IPC 可以使得在不同主机上的应用程序之间进行通信(网络通信),当然也可以是同一台…

【Excel】Excel中将日期格式转换为文本格式,并按日期显示。

【问题需求】 在使用excel进行数据导入的过程中, 有的软件要求日期列必须是文本格式。 但是直接将日期列的格式改为文本后,显示一串数字,而不按日期显示。 进而无法导入使用。 【解决方法】 使用【TXET】函数公式进行处理, 在单…

EDA数据跨网交换解决方案,一文了解

EDA数据通常与电子设计自动化相关,这是一种利用计算机辅助设计(CAD)软件来完成超大规模集成电路(VLSI)芯片的功能设计、综合、验证、物理设计等流程的技术。以下是一些会涉及到EDA数据的行业: 集成电路设计…

目前的 Layer2 解决方案有什么优缺点

Layer2解决方案是区块链技术中的一种扩展机制,旨在提高交易速度、降低成本并增加网络的可扩展性,同时保持主链的安全性。目前的Layer2解决方案包括状态通道(State Channels)、侧链(Sidechains)、Rollups&am…

淘宝扭蛋机源码解析:功能实现与技术细节

随着在线购物和娱乐的融合,淘宝扭蛋机作为一种创新的购物娱乐方式,受到了广大用户的喜爱。本文将深入解析淘宝扭蛋机的源码,探讨其功能实现与技术细节,以期为开发者们提供一些有价值的参考。 一、功能实现 1.用户登录与注册 淘宝…

《深入浅出OCR》项目实战:基于CRNN的文字识别

基于CRNN的文本字符验证码识别 1项目介绍链接: 为方便大家快速上手OCR实战,本次实战项目采用开源框架PaddleOCR,大家可以参考官网文档快速了解基本使用,项目数据为2022 DCIC赛题中提供的验证码数据集,大家可以参考其他…

圈子社区系统源码 开源 多端圈子社区论坛系统 社区圈子管理系统

介绍 圈子论坛小程序,是一款为用户提供交流分享、互动沟通的平台。在这个小程序中,用户可以轻松地加入各种不同兴趣爱好的圈子,与志同道合的朋友们交流互动。圈子论坛小程序不仅仅是一个简单的社交工具,更是一个打开新世界大门的…

el-table 固定前n行

el-table 固定前n行 第一种&#xff0c;通过设置前几行粘性布局 <el-table:data"tableData2"borderheight"calc(98% - 40px)"// 设置行样式:row-class-name"TableRowClassName"selection-change"handleSelectionChange" ><…

python编程语言软件:深度解析与实用指南

python编程语言软件&#xff1a;深度解析与实用指南 在数字化时代&#xff0c;Python编程语言软件因其易用性、强大的功能和广泛的应用领域而备受瞩目。本文将从四个方面、五个方面、六个方面和七个方面&#xff0c;深入剖析Python编程语言软件的特点、优势以及应用场景&#…

在 Java 项目中扫描识别图片中的文字(详细教程)

目录 需求&#xff1a; 步骤&#xff1a; 1、maven配置&#xff08;pom.xml&#xff09;&#xff1a; 2、下载依赖文件&#xff1a; 3、代码&#xff1a; post进行测试&#xff1a; 测试图片&#xff1a; 测试结果&#xff1a; 需求&#xff1a; 上传图片文件进行扫描…

CentOS 9安装Kubernetes(k8s)集群

前言 1、版本说明 系统版本&#xff1a;CentOS 9 k8s版本&#xff1a;v1.29.5 docker版本&#xff1a;26.1.3 harbor&#xff1a;v2.9.4 2、提前准备好1台虚拟机&#xff0c;可以参考博客&#xff1a;Vmware 17安装 CentOS9 3、虚拟机提前安装好docker&#xff0c;参考博客&a…