PE文件(十二)导入表

导入表

导入表的引入

当一个PE文件(如.dll/.exe等)需要使用别的模块的函数,也叫做依赖某模块,就需要一个清单来记录使用的模块(一般为.dll文件,为方便理解,以后我们将模块都认为是.dll文件)及使用的函数的相关信息(如使用了哪些DLL、使用了这个DLL里的哪些函数、叫什么名、去哪找等),这个清单就叫做导入表。

定位导入表

一个PE文件的数据目录第二个结构体就是导入表数据目录,根据导入表数据目录的VirtualAddress成员经过RVA转FOA找到导出表

导入表结构

如下是导入表结构:

struct _IMAGE_IMPORT_DESCRIPTOR{                       

    union{                     

        DWORD Characteristics;                                

        DWORD OriginalFirstThunk;

    };                     

    DWORD TimeDateStamp;

    DWORD ForwarderChain;                                     

    DWORD Name;

    DWORD FirstThunk; 

};

一个导入表大小为20字节

DWORD OriginalFirstThunk:该值为指向导入名称表(即INT表)的RVA

DWORD FirstThunk:该值为导出地址表(即IAT表)的RVA

DWORD TimeDateStamp:时间戳,用于判断该.dll文件是否有绑定导入表或IAT表中是否已经绑定绝对地址。当该值为0x00000000时,表示表示这个导入表结构对应的DLL中的函数绝对地址没有绑定到IAT表中。当该值为0xFFFFFFFF时,表示这个导入表结构对应的DLL中函数绝对地址已经绑定到IAT表中

DWORD Name:指向使用到的.dll名字字符串的RVA,该字符串以0结尾。如果Name指向的.dll名称为“user32.dll”,那么这个导入表中记录的就是该PE文件使用user32.dll的相关信息

注意:

1.当一个导入表后跟了一个导入表大小即20个字节长度的0时,表示该PE文件的所有导入表结束。

2.一般来说,程序通过导入表中的信息来装载对应的.dll文件到虚拟内存中(比如通过导入表的所有Name成员,获取系统要装载的.DLL的名字)。但导入表中的某些信息则需要在.DLL装载内存完成后(比如IAT表)才能修复

3.如果导入表的某个结构中OriginalFirstThunk和FirstThunk的值都为0,这意味着该PE文没有使用这个DLL中的任何函数。此时操作系统就不会加载这个导入表结构对应的DLL

4.一个PE文件使用到的.dll文件的数量就是该PE文件的导入表数量。

INT表

定位INT表

INT表定位:通过OriginalFirstThunk找到INT表

INT表结构

结构如下图:

上图是一般情况下INT表的样子,元素有IMAGE_THUNK_DATA也有数值,但实际上这些元素都是属于IMAGE_THUNK_DATA32这一种结构体的不同形式表现。实际上的INT表如下:

图中表的成员为结构体,结构如下:

struct _IMAGE_THUNK_DATA32{                         

    union{                        

        BYTE ForwarderString;                          

        DWORD Function;                         

        DWORD Ordinal;     

        _IMAGE_IMPORT_BY_NAME* AddressOfData;

    };                         

};                  

这个结构体其实就是一个联合体,4字节大小。

元素表现形式不同的原因:一个.DLL中的函数可以以函数名称导出,也可以以序号(NONAME)导出,所以当一个PE文件使用别的.DLL中的函数时要考虑这个函数的名字和序号两种情况。因此INT表中的元素有IMAGE_THUNK_DATA和序号两种形式。

元素形式的判断方法如下:

如果INT表的元素最高位为1:那么除去最高位剩下31位的值,就是函数的导出序号

如果INT表的元素最高位为0:那么这个值为指向IMAGE_IMPORT_BY_NAME结构体的RVA

注意:

1.INT表中的元素个数就是该PE文件使用INT表对应的.dll文件函数的数量

2.当找到INT表后往后依次遍历出现有连续四字节长度的0时,表示该INT表结束

定位导入函数名称表

定位导入函数名称表:通过INT表中 _IMAGE_IMPORT_BY_NAME* AddressOfData元素,即可找到函数名称表的偏移地址

导入函数名称表结构

_IMAGE_IMPORT_BY_NAME结构体:

struct _IMAGE_IMPORT_BY_NAME{                       

    WORD Hint;

    BYTE Name[1];  //函数名称,以0结尾  

};                      

Hint:这个值由编译器决定是否为空,如果不为空,表示函数在导出表中的索引。一般不使用这个值

Name:由于函数名称的字符个数是不确定的,所以此处只给出一个1字节的字符数组用来存储函数名称的第一个字符。通过Name获取该字符串的首地址,再依次往后遍历,直到遇到字符串的结尾字符\0,便是完整的函数名称

IAT表

IAT表的引入

当我们在程序中使用其他模块中的函数时,我们以程序调用MessageBoxA()为例,进行演示。程序运行后我们进入反汇编开始观察。

我们会发现,系统在调用该函数时,call后跟的不是一个绝对地址,而是一个间接地址。

我们在内存中查找该地址

我们发现,这个地址内容是一张表,记录着我们使用的函数的实际地址。我们在这个程序只使用了MessageBoxA()函数,所以上表中只有第一行四个字节记录了数据,也就是MessageBoxA()函数的地址。而这张表就是IAT表,也叫做导入函数地址表

定位IAT表

方法一:通过导入表中的FirstThunk(RVA)成员,找到IAT表。

方法二:通过PE文件数据目录的第13个结构体中的VirtualAddress(RVA)成员,找到IAT表

导入表和IAT表

IAT表在程序运行前后是不一样的,因此导入表和IAT表的具体关系结构有以下两种:

PE文件运行前:

PE文件运行后:

PE文件运行前:IAT表中的内容和INT表的内容是一样的

PE文件运行后:IAT表中的内容就变成了该PE文件使用的对应的.dll中的函数在内存中的绝对地址

IAT表修改过程

1.装载PE文件到内存:当PE文件运行后,系统先装载.exe,再装载各个使用到的.dll到PE文件的虚拟内存中。

2.调用GetProcAddress()函数:内存装载完成后,系统首先遍历导出表中每个结构的INT表,无论遍历到的是函数名还是序号,都会作为其中一个参数传给系统函数GetProcAddress()

3. IAT表修改:GetProcAddress()函数根据函数名或序号返回对应函数在内存中的绝对地址,接着把绝对地址存入到IAT表的对应位置

4.修改call语句地址:

PE文件运行前:call [0x....]后面间接寻址的地址0x....是INT表中某个元素的地址;

PE文件运行后:call [0x....]后面间接寻址的地址0x....改成了IAT表中某个元素的地址;

INT表和IAT表的关系

原因一:PE文件加载后,INT表作为函数名字的备份。

原因二:当PE文件加壳或加密以后,函数地址发生改变。当程序运行后,IAT表中原本的记录的函数的地址就错了,就无法通过IAT表找函数了。此时通过INT表查找函数到函数地址就可以修复IAT表了。具体流程如下:PE文件运行前后INT表中的元素都指向函数名称或者序号。我们通过遍历该程序导入表的INT表,最终在某一个导出表结构中的INT表中找到要查找的函数名称(或序号)。此时通过将LoadLibrary()返回该函数所属的.dll的句柄(即所属DLL的ImageBase)和函数名称传入GetProcAddress()函数,就可以得到该函数地址。此时就可以修改IAT表了

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

electron安装及快速创建

electron安装及快速创建 electron是一个使用 JavaScript、HTML 和 CSS 构建桌面应用程序的框架。 详细内容见官网:https://www.electronjs.org/zh/docs/latest/。 今天来记录下练习中的安装过程和hello world的创建。 创建项目文件夹,并执行npm 初始化命…

将iPad 作为Windows电脑副屏的几种方法(二)

将iPad 作为Windows电脑副屏的几种方法(二) 1. 前言2. EV 扩展屏2.1 概述2.2 下载、安装、连接教程2.3 遇到的问题和解决方法2.3.1 平板连接不上电脑 3. Twomon SE3.1 概述3.2 下载安装教程 4. 多屏中心(GlideX)4.1 概述4.2 下载安…

东莞网站建设前期需要做好哪些工作

在进行东莞网站建设前,需要做好一系列的前期工作。这些工作的实施将为网站建设奠定坚实的基础,确保项目能够按计划顺利进行,并最终达到预期的目标。 首先,需要明确网站的定位和目标。东莞是一个经济发达的城市,因此&am…

Oracle系统表空间的加解密

实验环境 数据库选择的是orclpdb1,当前系统表空间未加密: SQL> show con_nameCON_NAME ------------------------------ ORCLPDB1SQL> select TABLESPACE_NAME, STATUS, ENCRYPTED from dba_tablespaces;TABLESPACE_NAME STATUS …

docker搭建python3的私有源--devpi

一、部署 # docker run -d --name devpi-lib -p 7104:7104 --env DEVPISERVER_HOST0.0.0.0 --env DEVPISERVER_PORT7104 --env DEVPISERVER_ROOT_PASSWORDpassword --env DEVPISERVER_USERlowinli --env DEVPISERVER_PASSWORDpassword --env DEVPISERVER_MIRROR_INDEXpypi --…

SAP PP学习笔记31 - 计划运行的步骤2 - Scheduling(日程计算),BOM Explosion(BOM展开)

上一章讲了计划运行的5大步骤中的前两步,计算净需求和计算批量大小。 SAP PP学习笔记30 - 计划运行的步骤1 - Net requirements calculation 计算净需求(主要讲了安全库存要素),Lot-size calculation 计算批量大小-CSDN博客 本章继续讲计划运行的后面几…

【快速逆向二/无过程/有源码】掌上高考—2024高考志愿填报服务平台

逆向日期:2024.07.21 使用工具:Node.js 加密工具:Crypto-js标准库 文章全程已做去敏处理!!! 【需要做的可联系我】 AES解密处理(直接解密即可)(crypto-js.js 标准算法&…

spring-boot3.x整合Swagger 3 (OpenAPI 3) +knife4j

1.简介 OpenAPI阶段的Swagger也被称为Swagger 3.0。在Swagger 2.0后,Swagger规范正式更名为OpenAPI规范,并且根据OpenAPI规范的版本号进行了更新。因此,Swagger 3.0对应的就是OpenAPI 3.0版本,它是Swagger在OpenAPI阶段推出的一个…

【Linux】玩转操作系统,深入刨析进程状态与调度机制

目录 1. 进程排队2. 进程状态的表述2.1. 进程状态2.2 运行状态2.3. 阻塞状态2.4. 挂起状态 3. Linux下具体的进程状态3.1. 运行状态R3.2. 可中断睡眠状态S3.3. 不可中断睡眠状态D3.4. 停止状态T3.5. 死亡状态X3.6. 僵尸状态Z 4. 孤儿进程5. 优先级6. Linux的调度与切换6.1. 四个…

第二证券:台风的后遗症竟然是台股!

今日早盘,中国台湾的台湾加权指数开盘大跌逾4%,台积电跌超6%。此前,因为飓风的原因,台湾股市暂停生意两天。暂停生意前,台湾加权指数收报22871点,上升614点,涨幅高达2.76%。 剖析人士认为&…

域名解析到ipv6,并用CF隐藏端口

要求:域名解析到 IPv6 地址并隐藏端口 ‍ 效果:用域名 https://myhalo.soulio.top​ 访问http://[2409:8a62:867:4f12:56c7:5508:f7x6:8]:8080​。唯一缺点是延迟有点高。 ​​ ‍ 难度:需要有一定域名解析、cloudflare使用基础 ‍ 实…

[数据集][目标检测]躺坐站识别检测数据集VOC+YOLO格式9488张3类别

数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):9488 标注数量(xml文件个数):9488 标注数量(txt文件个数):9488 标注…

【C/C++】内存管理

内存管理 一.C/C内存分布二.C内存管理方式1.new、delete操作内置类型2.new、delete操作自定义类型3.32位、64位机器的区别 三.operator new与operator delete函数四.new和delete的实现原理1.内置类型2.自定义类型1.new的原理2.delete的原理3.new T[N]的原理4.delete[]的原理 五…

5G赋能新能源,工业5G路由器实现充电桩远程高效管理

随着5G技术的广泛应用,新能源充电桩的5G应用正逐步构建起全新的生态系统。在数字化转型的浪潮中,新能源充电桩行业正迎来数字化改革。工业5G路由器的引入,为充电桩的远程管理提供了强有力的技术支持,新能源充电桩5G路由器网络部署…

MySQL窗口函数详解

MySQL窗口函数详解 MySQL从8.0版本开始引入了窗口函数,这是一个强大的特性,可以大大简化复杂的数据分析任务。本文将详细介绍MySQL窗口函数的概念、语法和常见用法,并结合实际应用场景进行说明。 什么是窗口函数? 窗口函数是一种能够对结…

docker搭建ES 8.14 集群

参考:【docker搭建es8集群kibana】_docker 安装生产级 es 8.14 集群-CSDN博客 1、之前已搭建一台单机版的dockerES集群 参见 Elasticsearch docker 安装_docker 安装es8.14.3-CSDN博客 2、现在需要重新搭建为docker ES集群 准备新搭建3个点 一、准备工作 提前开…

【中项】系统集成项目管理工程师-第4章 信息系统架构-4.3应用架构

前言:系统集成项目管理工程师专业,现分享一些教材知识点。觉得文章还不错的喜欢点赞收藏的同时帮忙点点关注。 软考同样是国家人社部和工信部组织的国家级考试,全称为“全国计算机与软件专业技术资格(水平)考试”&…

计蒜客T3473(丑数) 优先队列,质因数,小题大做一下

文章目录 丑数思考过程代码 丑数 思考过程 其实现在这一题,我还没把代码敲完。但想赶紧把自己的思考过程给记录下来,不然一会儿,一些细节就捕捉不到了。因为才看了一个“广告”,关于抓住瞬间的灵感,虽然我这纯属是小儿…

分类常用的评价指标-二分类/多分类

二分类常用的性能度量指标 精确率、召回率、F1、TPR、FPR、AUC、PR曲线、ROC曲线、混淆矩阵 「精确率」查准率 PrecisionTP/(TPFP) 「召回率」查全率RecallTP/(TPFN) 「真正例率」即为正例被判断为正例的概率TPRTP/(TPFN) 「假正例率」即为反例被判断为正例的概率FPRFP/(TNFP)…

Visual Studio 2022美化

说明: VS版本:Visual Studio Community 2022 背景美化 【扩展】【管理扩展】搜索“ClaudiaIDE”,【下载】,安装完扩展要重启VS 在wallhaven下载壁纸图片作为文本编辑器区域背景图片 【工具】【选项】搜索ClaudiaIDE&#xff…