当前位置: 首页 > web >正文

PE文件结构(导入表)

导入表


什么是导入表?

导入表就是pe文件需要依赖哪些模块以及依赖这些模块中的哪些函数

回想我们导出表的内容,导出表的位置和大小是保存在扩展pe头最后一个结构体数组当中的

IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]

第一个成员是我们的导出表,第二成员就是我们的导入表了

在这里插入图片描述

通过分析pe文件,得出导入表的位置在0x20400 (RVA)

我们来看一下导入表的结构

typedef struct _IMAGE_IMPORT_DESCRIPTOR {
union {DWORD   Characteristics;            	// 0 for terminating null import descriptorDWORD   OriginalFirstThunk;         	// RVA to original unbound IAT (PIMAGE_THUNK_DATA)
} DUMMYUNIONNAME;
DWORD   TimeDateStamp;                  // 0 if not bound,
// -1 if bound, and real date\time stamp
//     in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND)
// O.W. date/time stamp of DLL bound to (Old BIND)

DWORD   ForwarderChain;                 // -1 if no forwarders
DWORD   Name;							// RVA,指向dll名字
DWORD   FirstThunk;                     // RVA to IAT (if bound this IAT has actual addresses)
} IMAGE_IMPORT_DESCRIPTOR;
typedef IMAGE_IMPORT_DESCRIPTOR UNALIGNED *PIMAGE_IMPORT_DESCRIPTOR;

导入表-确定依赖模块

通过rva到foa的转换后得到第一个导入表的地址:0xD600 (这里的导入表并不是只有一个,一般来说程序使用了多少个模块就有多少个导入表,那么怎么看导入表结束的位置呢)
在这里插入图片描述

我们先看第一个导入表的name属性:0x20876(RVA),转为FOA为:0xDA76
在这里插入图片描述

我们已经查询出来了第一个导入表对应的名称是user32.dll

导入表并不是只有一个,导入表结构体的大小为25个字节,从第一个 0xD600 开始,每25个字节为一个新的导入表,直到下一个导入表的name属性为 0x0000 表示着最后一个导入表的结束


导入表-确定依赖函数

确定导入表中都使用了模块中的哪些方法

关注导入表OriginalFirstThunk和FirstThunk中的属性,OriginalFirstThunk指向的是 INT(导入名称) 表,FirstThunk指向的是 IAT (导入地址)表

IAT结构体

typedef struct _IMAGE_THUNK_DATA64 {union {ULONGLONG ForwarderString;  // PBYTE (无需关注)ULONGLONG Function;         // PDWORD(无需关注)ULONGLONG Ordinal;			// 序号ULONGLONG AddressOfData;    // 指向PIMAGE_IMPORT_BY_NAME} u1;
} IMAGE_THUNK_DATA64;
typedef IMAGE_THUNK_DATA64 * PIMAGE_THUNK_DATA64;

在这里插入图片描述

我们看下导入表结构体中这个属性OriginalFirstThunk为:0x205B8(RVA)

转为FOA后:0xD4B0

可以得到以下IAT信息(RVA)

IMAGE_THUNK_DATA
0x20732
0x20718
0x20B04
0x206FC
0x206DC
0x206BE
0x206A8
0x20688
0x20670

接下来我们来分析IAT结构体中的数据

在这里插入图片描述

// IMAGE_IMPORT_BY_NAME
typedef struct _IMAGE_IMPORT_BY_NAME {WORD    Hint;			// 可能为空,编译器决定如果不为空则为函数在导出表中的索引CHAR   Name[1];			// 函数名称以0结尾
} IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME;
首先我们分析 0x20732(在二进制下)的最高位是否为1,很显然并不为1
再把这个地址(0x20732 )RVA 转为FOA得到 0xD732 (_IMAGE_IMPORT_BY_NAME) 结构体所在的地址

在这里插入图片描述
第一个成员 Hint对应 0x31 ,第二个成员Name,指模块中的方法名以0结尾


导入表-确定函数地址

我们再看最后一个导入表成员FirstThunk属性

FirstThunk和OriginalFirstThunk在程序未执行之前,它们两指向的都是同的结构体数组,但是一但程序运行起来后,FirstThunk指向的是要运行方法的地址

http://www.xdnf.cn/news/4583.html

相关文章:

  • 【AI论文】
  • JavaSE核心知识点01基础语法01-05(字符串)
  • 进程与线程详细介绍
  • 如何使用 QuickAPI 连接 PostgreSQL 数据库并将PostgreSQL数据发布成API?
  • 嵌入式开发学习日志Day15
  • AI恶魔之眼使用说明书
  • Spring Bean 的创建流程
  • 分布式id的两大门派!时钟回拨问题的解决方案!
  • 单调栈原理
  • vtkSmartPointer<vtkPolyData> 常用的函数方法
  • Spring Boot 多数据源事务管理
  • async/await的另一种食用方法
  • vue-quill-editor的失焦事件
  • 分布式架构详解
  • #黑马点评#(一)登录功能
  • 数字化转型-4A架构之应用架构
  • 鸿蒙编译boost
  • 浅谈微前端沙箱机制
  • 报表分析报告怎么写?零基础掌握报表分析三要素!
  • canal mysqltomysql增加同步的库操作
  • 96、数图求解(整数规划建模求解)
  • 分布式-Redis分布式锁
  • 如何用FastMCP快速开发自己的MCP Server?
  • 2024ccpc【上海+陕西】
  • Windows远程桌面实现之十七:基于浏览器的文件和目录传输(一)
  • 解决 win11 连接共享打印机,报错 0x00000709 问题
  • Analytics Service 对生产环境性能的影响
  • Spring-博客系统项目
  • 动态规划之回文串问题
  • 第7章-3 维护索引和表