我们再上一章节简要介绍了IAT表,我们知道如果程序调用dll中的函数时,必须通过IAT表来找到函数,我们基本了解了IAT表之后,我们今天来讲解一下导入表,通过本章节的学习,我们可以了解导入表,也能对IAT表有一个更深入的了解。

文章目录

  • 一.导入表是什么?
  • 二.导入表详解
  • 三.打印一个程序的导入表的信息(作业思路)

一.导入表是什么?

我们可以将导入表比作餐厅的菜单,而dll中函数的地址,就可以被比作为菜单上的菜品。
也就是说,导入表记录了dll中的函数名称和地址,exe在调用dll中的函数的时候,就可以通过导入表来找到函数。这里注意区分导入表和IAT表,IAT表是exe在调用dll中的函数时,通过IAT表中记录的地址来找到函数,而导入表记录了dll的名称,还有dll中函数的地址和名称(也有函数的导出序号)。
那么我们来看看导入表的结构:

typedef struct_IMAGE_IMPORRT_DESCRIPTOR{union{DWORD Characteristics;DWORD OriginaFirstThunk;//指向IMAGE_THUNK_DATA(输入名称表)结构数组的RVA}DWORD TimeDateStamp;//时间戳(当可执行文件不与被输入的DLL进行绑定时,此字段为0)DWORD ForwarderChain;//第一个被转向的API索引DWORD Name;//指向被输入的DLL的名称字符串的第一个字符RVADWORD FirstThunk;//指向输入地址表(IAT表)的RVA,IAT是一个IMAGE_THUNK_DATA结构的数组
}IMAGE_IMPORT_DESCRIPTOR;
typedef IMAGE_IMPORT_DESCRIPOTOR UNALIGNED *PIMAGE_IMPORT_DESCRIPTOR;

解析:
该导入表结构中:
OriginaFIrstThunk中存储的是一个地址,指向IMAGE_THUNK_DATA(导入名称表)该表中记录了导入函数的名称,也被叫做INT表,该表的结束标志和很多表一样:最后一张表的数据全为0。
Name中存储的是指向该dll文件名的RVA
FirstThunk中存储的是该文件的IAT(import address table)表的RVA,因为导入表和IAT表都和调用的dll文件中的函数有密切关系,所以他俩总是在一起,该表的结束标志和很多表一样:最后一张表的数据全为0。
找到IAT表有两种方式:一种是通过数据目录的第13个项目的VirtualAddress找到,另一种方式是通过导入表的FirstTrunk找到
我们知道一个程序可能调用了很多dll文件,所以导入表也不只一张,VirtualAddress(数据目录中的第二个元素为导入表) 指向多个一样的导入表结构。

二.导入表详解

我们想要了解导入表,必须通过程序运行前和程序运行中两种状态来了解,也就是程序未被加载前和程序和调用的dll都被加载到独立4GB空间两种状态下:
我们给出图来帮助我们理解:
程序未被加载前:

我们可以很清楚地观察到,在程序未被加载前,INT(导入名称表)和IAT(导入地址表)中存储的地址都指向同一个地方:该处存储了函数名称字符串或函数导出序号,我们在上一章中也在程序二进制文件中观察到存储了MessageBoxA(上一章节存储了MessageBoxA是因为我写的程序调用了MessageBox函数),那么我们如何判断INT(导入名称表)中的元素到底是函数导出名称还是导出序号呢?
这里给出判断INT表中某一项方法:
在INT(导入名称)表中,若该项最高位为1,那么去除最高位,剩下的就是该函数的导出序号
若该项最高位为0,那么这一项就是RVA,指向IMAGE_TRUNK_BY_NAME。

typedef struct _IMAGE_THUNK_DATA32 {                     union {                     PBYTE  ForwarderString;                     PDWORD Function;                        DWORD Ordinal;                       //序号PIMAGE_IMPORT_BY_NAME  AddressOfData;//指向IMAGE_IMPORT_BY_NAME} u1;
} IMAGE_THUNK_DATA32;
typedef IMAGE_THUNK_DATA32 * PIMAGE_THUNK_DATA32;                       typedef struct _IMAGE_IMPORT_BY_NAME {                      WORD    Hint;                       //可能为空,编译器决定 如果不为空 是函数在导出表中的索引BYTE    Name[1];                   //函数名称,以0结尾
} IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME;

IMAGE_IMPORT_BY_NAME 中的 Name 并不只有 1 个字节,而是一直遍历到元素为 ‘\0’ 为止,OriginalFirstThunk 和 FirstThunk 的遍历 具体详见下图(这俩的遍历都一样的,其实都是遍历的 IMAGE_THUNK_DATA)。

程序和调用的dll被加载后:
我们来思考一个问题:既然INT表和IAT表都指向同一个地方,那么我们为什么需要两张表呢?
我们再上一章简单解析了IAT表,我们知道程序在调用dll中的函数时,要通过IAT表来间接寻址,如果只用一张表的话,在程序被加载后,IAT表中的项目被改为函数地址,那么程序不就不知道函数名称了吗?这就是为什么要有INT表和IAT表的原因。

我们可以观察到:在程序和调用的dll被加载后,IAT表中的项目不再指向函数名称,通过上一章节的简析,我们知道它指向了函数被加载后的真正地址,当程序调用函数时,通过IAT表就可以找到函数真正的位置了。
IAT 表在文件加载完成后系统会调用 GetProcAddress() 函数,就是做的我们前面写过的根据导出表函数序号或函数名字找到函数地址的功能。系统会循环 INT 表,根据表内的名字或序号调用 GetProcAddr() 得到地址,依次添加到 IAT 表中。
注意 IMAGE_IMPORT_BY_NAME 中的 Hint 不是导出序号,而是当前这个函数在导出表函数地址表中的索引。但基本没用,所以不一定是准确的,可以全部为0。而Name并不是一字节,而是以’\0’结尾的不定长字符串。

三.打印一个程序的导入表的信息(作业思路)

这里先给出基本思路(这里是打印程序未被加载前的导入表):
1.通过数据目录的第二项的VirtualAddress转换为FOA在文件中找到导入表
2.输出dll名(导入表中Name字段转换为FOA在文件中找到)
3.遍历OriginalFirstTrunk(OriginalFirstTrunk字段转换为FOA在文件中找到),打印导出序号或导出名称(需要转换为FOA在文件中找到)
4.遍历FirstTrunk(导入表中FirstTrunk字段转换为FOA在文件中找到)
5.找到下一张导入表,循环2,3,4,直到某张表的导入表内数据全为零结束

导入表解析,IAT表解析【滴水逆向三期53笔记】相关推荐

  1. IAT表入门简析【滴水逆向三期52笔记】

    在讲IAT表之前,我们来回忆一下之前学习的知识: 如果我们将函数写在程序的源文件中,那么该函数就会被编译器直接编译到程序的二进制文件中,在程序调用该函数的时候,E8后跟的地址是直接写死的,程序直接在e ...

  2. 静态链接库,动态链接库【滴水逆向三期48笔记】

    在开发过程中,我们通常会有很多函数,需要多次使用或在不同的程序中使用该函数,也有可能我们会将我们写好的函数给别人使用,但是我们又不想给他源代码,毕竟代码是我们花了很多功夫写出来的,那么我们如何不发给其 ...

  3. 解析导入表和IAT表

    一.导入表的结构 导入表的结构看起来复杂,其实只是套娃,不要被它吓到了. 导入表的定义如下: typedef struct _IMAGE_IMPORT_DESCRIPTOR {union {DWORD ...

  4. 滴水逆向三期实践16:IAT表和导入表

    IAT表 在我们调用 dll 函数的时候,发现代码中的汇编,是通过间接寻址的.也就是不直接 call 函数地址,而是通过一个中间地址再跳转的. 比如调用MessageBox这类系统函数的时候(这也是个 ...

  5. PE导入表和IAT表的原理及工作关系

    PE导入表和IAT表的原理及工作关系 文章目录 PE导入表和IAT表的原理及工作关系 0.说明 1.PE导入表和IAT表大致工作关系 (1)为什么会有IAT表 (2)为什么会有导入表 2.导入表和IA ...

  6. 滴水逆向三期实践1:PE头字段解析,附PE结构下载

    视频资源详见网盘搜索 或 在线的B站滴水逆向三期 其课件也能在CSDN或百度搜索到,以下部分为课件内容摘要,部分为自己的理解 最后附上详细注释的自写代码 PE(Portable Executable) ...

  7. 滴水逆向win32学习笔记1

    滴水逆向win32学习笔记 一.字符编码 基本介绍 关于utf-16.utf-8和unicode的关系 BOM头 二.宽字符 基本介绍 常用函数 三.Win32 API中的宽字符 什么是win32 A ...

  8. 滴水逆向三期实践15:重定位表修正

    我们知道,重定位表是由于在代码中写入的绝对地址,而 DLL 不能按照设想的 ImageBase 作起始加载位置去了别的地方占坑,那么需要根据重定位表记录的这些绝对地址在内存中的位置(RVA),逐一去到 ...

  9. 滴水逆向三期 win10 ASLR UnmapViewOfSection傀儡进程 加密壳项目

    特意加了一个win10标题, 碰到0xc0000005的朋友就不要再浪费时间了, 我在这个问题上花了整整一天 网上全是xp的代码, 搜到了了几个win10的也是同样的错误没法解决, 唯一一个有用的答案 ...

最新文章

  1. 在Data Collector中使用TensorFlow进行实时机器学习
  2. python 百度词典_用 Python 3 写的命令行百度词典
  3. 如何查他人【思科CCIE证书真伪、有效期】
  4. PVANET: Deep but Lightweight Neural Networks for Real-time Object Detection
  5. C/C++中的##用法
  6. MSSQL返回季度开始月和某月是第几季度
  7. 23-初识正则表达式
  8. VS Code Remote 发布!开启远程开发新时代
  9. 20000W的电灯泡,真的是叼炸天
  10. UEFI学习——事件函数WaitForEvent和CreateEvent/CreateEventEx
  11. BlackBerry7290软件安装——电子书阅读Mobipocket
  12. 冯诺依曼计算机的弱点,冯。诺依曼型计算机的缺点及改进方法.doc
  13. (每日一练c++)CC156 确定字符互异
  14. 11位大咖集结!和最专业的人,探讨“由内及外”的未来趋势 | 生辉 · 生命科学大会-1
  15. CLAHE算法代码详解
  16. 基于Python(Django)+MongoDB实现的(Web)新闻采集和订阅系统【100010319】
  17. SQL查询 — 自连接的用法
  18. 1N系列稳压二极管参数
  19. 那些你可能不知道的 PDF 工具
  20. 真三国无双3 己方士气提升

热门文章

  1. 安卓的SMS 短信的增删改查
  2. android 蓝牙串口连接不上,安卓手机搜索不到蓝牙模块HC-06,是怎么回事?
  3. 尝试用单片机以及GSM模块做出一个简易手机(1)
  4. angularJS求助
  5. Linux文件管理-压缩和解压
  6. 利用Frida绕过Android App(途牛apk)的SSL Pinning
  7. 东软睿道实训心得:走出校门后最稳妥的一步
  8. 75、单元测试-嵌套测试
  9. 【tk制作一个登陆界面】
  10. Visio Pro 2019里面同时添加上下标的简单方法