导入地址表钩取技术解析

2024-06-05 20:36

本文主要是介绍导入地址表钩取技术解析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前置知识

导入表

在一个可执行文件需要用到其余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.chinasem.cn/article/1034105

相关文章

网页解析 lxml 库--实战

lxml库使用流程 lxml 是 Python 的第三方解析库,完全使用 Python 语言编写,它对 XPath表达式提供了良好的支 持,因此能够了高效地解析 HTML/XML 文档。本节讲解如何通过 lxml 库解析 HTML 文档。 pip install lxml lxm| 库提供了一个 etree 模块,该模块专门用来解析 HTML/XML 文档,下面来介绍一下 lxml 库

python: 多模块(.py)中全局变量的导入

文章目录 global关键字可变类型和不可变类型数据的内存地址单模块(单个py文件)的全局变量示例总结 多模块(多个py文件)的全局变量from x import x导入全局变量示例 import x导入全局变量示例 总结 global关键字 global 的作用范围是模块(.py)级别: 当你在一个模块(文件)中使用 global 声明变量时,这个变量只在该模块的全局命名空

【专题】2024飞行汽车技术全景报告合集PDF分享(附原数据表)

原文链接: https://tecdat.cn/?p=37628 6月16日,小鹏汇天旅航者X2在北京大兴国际机场临空经济区完成首飞,这也是小鹏汇天的产品在京津冀地区进行的首次飞行。小鹏汇天方面还表示,公司准备量产,并计划今年四季度开启预售小鹏汇天分体式飞行汽车,探索分体式飞行汽车城际通勤。阅读原文,获取专题报告合集全文,解锁文末271份飞行汽车相关行业研究报告。 据悉,业内人士对飞行汽车行业

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

常用的jdk下载地址

jdk下载地址 安装方式可以看之前的博客: mac安装jdk oracle 版本:https://www.oracle.com/java/technologies/downloads/ Eclipse Temurin版本:https://adoptium.net/zh-CN/temurin/releases/ 阿里版本: github:https://github.com/

金融业开源技术 术语

金融业开源技术  术语 1  范围 本文件界定了金融业开源技术的常用术语。 本文件适用于金融业中涉及开源技术的相关标准及规范性文件制定和信息沟通等活动。

OWASP十大安全漏洞解析

OWASP(开放式Web应用程序安全项目)发布的“十大安全漏洞”列表是Web应用程序安全领域的权威指南,它总结了Web应用程序中最常见、最危险的安全隐患。以下是对OWASP十大安全漏洞的详细解析: 1. 注入漏洞(Injection) 描述:攻击者通过在应用程序的输入数据中插入恶意代码,从而控制应用程序的行为。常见的注入类型包括SQL注入、OS命令注入、LDAP注入等。 影响:可能导致数据泄

webapp地址

F:\LSP\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps

从状态管理到性能优化:全面解析 Android Compose

文章目录 引言一、Android Compose基本概念1.1 什么是Android Compose?1.2 Compose的优势1.3 如何在项目中使用Compose 二、Compose中的状态管理2.1 状态管理的重要性2.2 Compose中的状态和数据流2.3 使用State和MutableState处理状态2.4 通过ViewModel进行状态管理 三、Compose中的列表和滚动

AI(文生语音)-TTS 技术线路探索学习:从拼接式参数化方法到Tacotron端到端输出

AI(文生语音)-TTS 技术线路探索学习:从拼接式参数化方法到Tacotron端到端输出 在数字化时代,文本到语音(Text-to-Speech, TTS)技术已成为人机交互的关键桥梁,无论是为视障人士提供辅助阅读,还是为智能助手注入声音的灵魂,TTS 技术都扮演着至关重要的角色。从最初的拼接式方法到参数化技术,再到现今的深度学习解决方案,TTS 技术经历了一段长足的进步。这篇文章将带您穿越时