IAT表
0X0
0 DLL介绍
DLL翻译器为动态链接库,原来不存在DLL的概念只有,库的概念,编译器会把从库中获取的二进制代码插入到应用程序中。在现在windows操作系统使用了数量庞大的库函数(进程,内存,窗口,消息)采用这种包含库的方式,会造成内存严重的浪费。因此,windows OS 设计者根据需要引入了DLL这一概念
(1) 不要把库包含到程序中,单独组成DLL文件,需要时调用即可
(2) 内存映射技术使加载后的DLL代码,资源在多个进程中实现共享
(3) 更新库时只要替换相关的DLL文件即可
0X01 IMAGE_IMPORT_DESCRIPTOR
IMAGE_IMPORT_DESCRIPTOR 结构体记录着PE文件要导入哪些库文件
IMAGE_IMPORT_DESCRIPTOR 结构体如下
typedef struct _IMAGE_IMPORT_DESCRIPTOR {
union {
DWORD Characteristics; // 0 for terminating null import descriptor
DWORD OriginalFirstThunk; // RVA to original unbound INT (PIMAGE_THUNK_DATA) 存着INT表地址
} 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; //导入库的名字
DWORD FirstThunk; // RVA to IAT (if bound this IAT has actual addresses) 存着IAT表地址
} IMAGE_IMPORT_DESCRIPTOR;
typedef IMAGE_IMPORT_DESCRIPTOR UNALIGNED *PIMAGE_IMPORT_DESCRIPTOR;
执行一个普通程序往往需要导入多个库,导入多个库就存在多少IMAGE_IMPORT_DESCRIPTOR结构体,这些结构体形成了数组,且结构体数组最后以NULL结构体结束。
| 项目 | 含义 |
|---|---|
| OriginalFirstThunk | INT的地址(RVA) |
| Name | 库的名字 |
| FirstThunk | IAT的地址(RVA) |
IAT 和 INT 存着很多IMAGE_THUNK_DATA,IMAGE_THUNK_DATA结构体汇总只有一个联合体,一般用四字节的AddressOfData来获取
typedef struct _IMAGE_THUNK_DATA32 {
union {
DWORD ForwarderString; // PBYTE
DWORD Function; // PDWORD
DWORD Ordinal;
DWORD AddressOfData; //RVA 指向_IMAGE_IMPORT_BY_NAME
} u1;
} IMAGE_THUNK_DATA32;
typedef IMAGE_THUNK_DATA32 * PIMAGE_THUNK_DATA32;
typedef struct _IMAGE_IMPORT_BY_NAME {
WORD Hint; //可能为0,编译器决定,如果不为0,是函数在导出表中的索引
BYTE Name[1]; //函数名称,以0结尾,由于不知道到底多长,所以干脆只给出第一个字符,找到0结束
} IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME;
INT 导入姓名表 IAT为导入地址表,程序在初始化时需要把获取库中的函数地址存入IAT表中进行IAT的初始化,在开始时INT和IAT指的是同一个结构体IMAGE_IMPORT_BY_NAME(我在XP环境中测试的时候记事本程序时在文件中,INT表存的是IMAGE_IMPORT_BY_NAME 结构体,IAT表存的是写死的函数地址)
描述IMAGE_IMPORT_DESCRIPTOR 的示意图

下面了解一下PE装载器把导入函数输入至IAT的顺序
- 读取IID的Name成员,获取库名称字符串("kernel32.dll")
- 装载相应库 ->LoadLibrary("kernel32.dll")
- 读取IID的OriginalFirstThunk成员,获取INT地址
- 逐一读取INT中数组的值,该值是IMAGE_IMPORT_BY_NAME的地址,然后获取IMAGE_IMPORT_BY_NAME结构体中的Hint 或者Name项 使用GetProcAddress()获取相应的起始地址
- 读取IID的FirstThunk(IAT)成员,获取IAT地址
- 将上面获取的函数地址输入相应的IAT数组值
- 重复4-6这几个步骤直到INT结束
0X02 在xp系统下用notepad.exe进行演示
0x021 从PE可选头查找导出表的位置
IMAGE_IMPORT_DESCROPTOR 结构的起始地址存在于 可选头的DataDirectory 数组第二个位置IMAGE_OPTIONAL_HEADER32.DataDirectory[1].VirtualAddress的值
- 首先通过PEwiew查看 notepad.exe的PE可选头 看出 IMPORT表 RVA 7604 => RAW 6A04
- 我们查到了导入表的首地址我们用HXd查看一下
我们可以看到数组的最后是以NULL结尾的
- 我先列一下第一个导入表对应的各个地址,全是F的话就是还未装载,在进入内存是将会装载
| 地址(RVA) | 含义 | 地址(RAW) |
|---|---|---|
| 7990 | OriginalFirstThunk | 6D90 |
| FFFFFFFF | TimeDateStamp | 0 |
| FFFFFFFF | ForwarderChain | 0 |
| 7AAC | Name | 6EAC |
| 12C4 | FirstThunk | 06C4 |
- 先看一下这个库的名字 是 comdlg32.dll
- 查看导入姓名表 中的 IMAGE_THUNK_DATA32 结构
RVA 7A7A => RAW 6E7A 为 IMAGE_IMPORT_BY_NAME 结构体的首地址
- 查看IMAGE_IMPORT_BY_NAME 结构体
可以看出000F为函数的编号 ,后面则是导入的函数名字 PageSetupDlgW
- 查看IAT表中的 IMAGE_THUNK_DATA32 结构
IAT表中的IMAGE_THUNK_DATA32 结构存的就不是姓名表的地址了,而是一个写死了的,该函数的内存地址,为了兼容其他系统,程序在执行时会通过IAT和库的导出表来动态获取该函数的地址。并把地址存入IAT表的对应位置,然后进行下一个函数名称查找,直到把所有函数查找完。
- 我们通过OllyIce查看在内存中IAT表的样子
看着该函数地址与在hxd文件一样,那是因为在xp系统下,换个系统这两个值就可能会不一致。
IAT表的更多相关文章
- PE格式第四讲,数据目录表之导入表,以及IAT表
PE格式第四讲,数据目录表之导入表,以及IAT表 一丶IAT(地址表) 首先我们思考一个问题,程序加载的时候会调用API,比如我们以前写的标准PE 那么他到底是怎么去调用的? 他会Call 下边的Jm ...
- 手工脱壳之FSG压缩壳-IAT表修复
目录 一.工具及壳介绍 二.脱壳 2.1.单步跟踪脱壳 2.2.IAT修复 三.程序脱壳后运行截图 四.个人总结 五.附件 一.工具及壳介绍 使用工具:Ollydbg.PEID.ImportREC.L ...
- IAT表和导入表
1.关于IAT(import address table)表 当exe程序中调用dll中的函数时,反汇编可以看到,call后面并不是跟的实际函数的地址,而是给了一个地址:
- [PE结构]导入表与IAT表
导入表的结构导入表的结构 typedef struct _IMAGE_IMPORT_DESCRIPTOR { union { DWORD Characteristics; // 0 for termi ...
- 第四讲,数据目录表之导入表,以及IAT表
一丶IAT(地址表) 首先我们思考一个问题,程序加载的时候会调用API,比如我们以前写的标准PE 那么他到底是怎么去调用的? 它会Call 下边的Jmp位置 而Jmp位置则是对一个全局变量取内容. 看 ...
- PE知识复习之PE的绑定导入表
PE知识复习之PE的绑定导入表 一丶简介 根据前几讲,我们已经熟悉了导入表结构.但是如果大家尝试过打印导入表的结构. INT IAT的时候. 会出现问题. PE在加载前 INT IAT表都指向一个名称 ...
- PE知识复习之PE的导入表
PE知识复习之PE的导入表 一丶简介 上一讲讲解了导出表. 也就是一个PE文件给别人使用的时候.导出的函数 函数的地址 函数名称 序号 等等. 一个进程是一组PE文件构成的. PE文件需要依赖那些 ...
- ring3下的IAT HOOK
标 题: [原创]ring3下的IAT HOOK作 者: hostzhen时 间: 2013-03-28,11:30:53链 接: http://bbs.pediy.com/showthread.ph ...
- 零基础逆向工程23_PE结构07_重定位表_IAT表(待补充)
重定位表 待补充 IAT表 待补充
随机推荐
- Jenkins-gogs安装及使用
很多同学可能第一次了解什么是ci-cd,什么是Jenkins,首先会介绍下cicd的概念及应用场景,之后再详细介绍下Jenkins的概念.安装及使用. 什么是CI-CD? 首先明确CI-CD是一种技术 ...
- 王艳 201771010127《面向对象程序设计(java)》第六周学习总结
实验六 继承定义与使用 一:理论部分: 第五章:继承类. 1.继承:已有类来构建新类的一种机制.档定义了一个新类继承另一个类时,这个新类就继承了这个类的方法和域,同时在新类中添加新的方法和域以适应新的 ...
- Hyperledger Fabric——balance transfer(五)执行交易
链码安装和实例化之后就可以调用chaincode执行交易,下面分析简单的账户转账操作是如何完成的. 源码分析 1.首先看app.js的路由函数 app.post('/channels/:channel ...
- 【Java】Scanner类nextInt后使用nextLine无法读取输入
首先,我们先介绍一下,在学习Java语言,对于字符串的输入,由于Scanner.next()函数无法输入空格及回车,此时,我们就必须要用Scanner.nextLine()解决这类问题, 在使用过程中 ...
- 五、数据类型(1):整数&&带小数点的数
1.整数 int printf("%d",...); scanf("%d",&...); 2.带小数点的数 double printf("%f ...
- 一言难尽,Jpa这个功能差点让我丢了工作
故事背景 前阵子,有位朋友在微信上问我数据被删了能不能恢复,我问了下原因,居然是因为一个配置项惹的祸. 故事细节 在 Spring Boot 中使用 jpa 来操作数据库,jpa 就不做详细的介绍了, ...
- Android中的多进程、多线程
前面几篇总结了进程.线程相关的知识.这里总结下关于Android中的多进程.多线程及其使用. 这里总结的Android中的多进程.多线程也是一个基础,可扩展的很多. Android中多进程 常见的几种 ...
- html5学习之路_003
html布局 使用<div>元素布局 使用<table>元素布局 <div>元素布局 <!DOCTYPE html> <html> < ...
- 五、Java - 集合
一.集合 Java 中的集合类存放于 java.util 包中,是一个存放对象的容器. 集合存放的是对对象的引用,对象本身还是存在于 JVM 堆内存中. 存放的是对象,即引用数据类型,对于基本数据类型 ...
- 记一次使用windbg排查内存泄漏的过程
一.背景 近期有一个项目在运行当中出现一些问题,程序顺利启动,但是观察一阵子后发现内存使用总量在很缓慢地升高, 虽然偶尔还会往下降一些,但是总体还是不断上升:内存运行6个小时候从33M上升到80M: ...






