PE文件(十二)导入表

news2024/9/25 1:15:07

导入表

导入表的引入

当一个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表了

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

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

相关文章

重磅发布:OpenAI宣布推出AI驱动的搜索引擎SearchGPT,将与Google和Perplexity展开竞争|TodayAI

OpenAI宣布推出其备受期待的AI驱动搜索引擎SearchGPT。该搜索引擎能够实时访问互联网信息,并将作为原型在有限范围内发布,计划最终将其功能整合到ChatGPT中。 SearchGPT的功能特点 SearchGPT是一个具有实时互联网信息访问能力的AI驱动搜索引擎。它的界面…

GoFly快速开发框架基于Go语言和Vue3开发后台管理附件管理插件包

说明 为了给客户提供更好的交互体验,框架把附件管理独立打包成插件包,这样附件管理接可以做个不通需求的附件管理插件包来满足不同甲方客户需求。 目前附件插件包有2个:一个基础包、一个高级包 附件插件包功能 1.基础包 统一管理业务系统…

Python酷库之旅-第三方库Pandas(046)

目录 一、用法精讲 161、pandas.Series.cumsum方法 161-1、语法 161-2、参数 161-3、功能 161-4、返回值 161-5、说明 161-6、用法 161-6-1、数据准备 161-6-2、代码示例 161-6-3、结果输出 162、pandas.Series.describe方法 162-1、语法 162-2、参数 162-3、功…

深入解析:inode、软硬链接与动静态库的奥秘

目录 一.inode1.inode的介绍2.文件系统与inode3.“目录”再理解 二.软硬链接1.硬链接2.软连接 三.动静态库1.静态库2.动态库3.动态库的加载过程 一.inode 1.inode的介绍 在Linux操作系统中,‘inode(索引节点)是文件系统的核心组件之一,用于管理文件和目…

从零开学C++:模板初阶

引言:在C语言当中,如果我们想要实现一个能计算整数和浮点数的计算器时,我们都需要根据不同的返回类型和参数类型创建许多个形式极其相似的函数,非常的麻烦,而在C中,我们将会引入模版的知识概念,…

模型优化—输入特征归一化处理

一、normalization 归一化(规范化)是对输入数据进行处理,使其满足某种规范。 前提:线性变换,不会改变原始数据的数值顺序。 假设原值分布在第一象限的某区间,并且x轴间距较广(离散&#xff0…

QT动态添加布局以及删除布局

具体代码示例如下 : QHBoxLayout* hLayout new QHBoxLayout;hLayout->addWidget(new QLabel("444"));hLayout->addWidget(new QLineEdit("444"));hLayout->addWidget(new QPushButton("444"));layout->addLayout(hLayou…

Axure Web端元件库:从Quick UI到500+组件的飞跃

在快速变化的数字世界中,产品设计不仅仅是功能的堆砌,更是用户体验的精心雕琢。原型设计作为产品开发过程中的关键环节,其重要性不言而喻。Axure,作为业界领先的原型设计工具,凭借其强大的交互设计和丰富的功能&#x…

Masked Autoencoders for Point CloudSelf-supervised Learning

关于SSL中的MAE方法。 摘要 文章介绍了一种新的技术,叫做MAE,在帮助计算机自己学习理解语言和图片方面做得非常好。受到这个技术的启发,它用在了点云上。点云是一堆代表三维空间中某些点的数据,这种数据有时候会有点难处理&…

机器学习笔记-02-基础线性算法认识(问题-解答自查版)

前言 以下问题以Q&A形式记录,基本上都是笔者在初学一轮后,掌握不牢或者频繁忘记的点 Q&A的形式有助于学习过程中时刻关注自己的输入与输出关系,也适合做查漏补缺和复盘。 本文可以让读者用作自查,答案在后面&#xff0…

尚庭公寓开发(二)

任何二进制和子网掩码进行一个与运算 得到是子网ip的话就是属于子网ip的范围 任何数字和一做与运算都是他本身 和0做运算都是0 所以要得到子网ip的话他的前面必须是 192.168.200 最后是0-255之间的范围 0不能取 0是子网本身 255也不能用 因为他是广播地址 真正可以使用 的范…

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

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

Python升级打怪—Django入门

目录 一、Django简介 二、安装Django 三、创建Dajngo项目 (一) 创建项目 (二) 项目结构介绍 (三) 运行项目 (四) 结果 一、Django简介 Django是一个高级Python web框架,鼓励快速开发和干净、实用的设计。由经验丰富的开发人员构建,它解决了web开…

机器学习 | 分类算法原理——感知机

Hi,大家好,我是半亩花海。接着上次的内积继续更新《白话机器学习的数学》这本书的学习笔记,在此分享感知机这一回归算法基础。本章的回归算法基础基于《基于图像大小进行分类》项目,欢迎大家交流学习! 目录 一、感知机…

阿里云-物联网平台-IoT设备MQTT通信

阿里云-物联网平台-IoT设备MQTT通信 登录阿里云物联网平台创建产品添加设备查看设备客户端登录 登录阿里云 阿里云 注册账号,实名认证这些按提示操作即可不在赘述。 物联网平台 选择产品》物联网》物联网平台 进入管理控制台界面 开通服务 选择开通公共实例测试环…

oracle中存储过程的写法

存储过程常规语法: 实际业务例子: CREATE OR REPLACE TRIGGER "TRI_B00_02_ONLY_GUID" BEFORE/AFTER INSERT OR UPDATE OR DELETE ON B00_02 FOR EACH ROW declare t_guid varchar2(300) : ; --GUID t_cnt int : 0; BEGIN t_guid : :NEW…

Oracle核心进程详解并kill验证

Oracle核心进程详解并kill验证 文章目录 Oracle核心进程详解并kill验证一、说明二、核心进程详解2.1.PMON-进程监控进程2.2.SMON-系统监控进程2.3.DBWn-数据库块写入进程2.4. LGWR-日志写入器进程2.5. CKPT-检查点进程 三、Kill验证3.1.kill ckpt进程3.2.kill pmon进程3.3.kill…

Spring MVC笔记

Java 版本: JDK17 Eclipse: eclipse-jee-2023-12-R-win32-x86_64.zip Tomcat 10 JDK17采用springframework 6 *必须考虑兼容性问题&#xff0c;所以JDK 和spring framework不要乱搭配 初步创建Maven Project 安装包 修改poem.xml <dependency><groupId>org.sprin…

Spark实时(五):InputSource数据源案例演示

文章目录 InputSource数据源案例演示 一、​​​​​​​File Source 1、读取text文件 2、读取csv文件 3、读取json文件 二、Socket Source 三、Rate Source InputSource数据源案例演示 在Spark2.0版本之后&#xff0c;DataFrame和Dataset可以表示静态有边界的数据&am…

客户服务知识库最佳实践 7 个步骤

介绍 每个公司的声誉都依赖于其客户。 如果全世界都向你敞开了大门&#xff0c;但你最终在与客户打交道方面做得很糟糕&#xff0c;那么消息就会传出去&#xff0c;无论你的捕鼠器有多好&#xff0c;你都会失去销售。 正如营销依赖于与潜在客户的关系一样&#xff0c;公司的…