小甲鱼PE详解之输入表(导入表)详解2(PE详解08)
来源:互联网 发布:淘宝运营论坛 编辑:程序博客网 时间:2024/05/17 05:01
在此之前,我们已经对这个输入表进行了一些实践和理解,这有助于大家对这个概念更进一步的加深认识。小甲鱼觉得,越是复杂的问题我们应该越是去动手操作它,认识它,这样才容易熟悉它!
在上一节课我们像小鹿一样的乱撞,终于撞到了输入表里边包含的函数名称,嘿嘿,不过地址,我们还是没能找着……这节课我们将深入来剖析输入表的结构,通过结合实例分析来帮助大家理解输入表的工作原理。
输入表结构
回顾一下,在 PE文件头的 IMAGE_OPTIONAL_HEADER 结构中的 DataDirectory(数据目录表) 的第二个成员就是指向输入表的。而输入表是以一个 IMAGE_IMPORT_DESCRIPTOR(简称IID) 的数组开始。每个被 PE文件链接进来的 DLL文件都分别对应一个 IID数组结构。在这个 IID数组中,并没有指出有多少个项(就是没有明确指明有多少个链接文件),但它最后是以一个全为NULL(0) 的 IID 作为结束的标志。
IMAGE_IMPORT_DESCRIPTOR 结构定义如下:
IMAGE_IMPORT_DESCRIPTOR STRUCT
成员介绍:
OriginalFirstThunk
它指向first thunk,IMAGE_THUNK_DATA,该 thunk 拥有 Hint 和 Function name 的地址。
TimeDateStamp
该字段可以忽略。如果那里有绑定的话它包含时间/数据戳(time/data stamp)。如果它是0,就没有绑定在被导入的DLL中发生。在最近,它被设置为0xFFFFFFFF以表示绑定发生。
ForwarderChain
一般情况下我们也可以忽略该字段。在老版的绑定中,它引用API的第一个forwarder chain(传递器链表)。它可被设置为0xFFFFFFFF以代表没有forwarder。
Name
它表示DLL 名称的相对虚地址(译注:相对一个用null作为结束符的ASCII字符串的一个RVA,该字符串是该导入DLL文件的名称,如:KERNEL32.DLL)。
FirstThunk
它包含由IMAGE_THUNK_DATA定义的 first thunk数组的虚地址,通过loader用函数虚地址初始化thunk。在Orignal First Thunk缺席下,它指向first thunk:Hints和The Function names的thunks。
这个OriginalFirstThunk 和 FirstThunk明显是亲家,两家伙首先名字就差不多哈。那他们有什么不可告人的秘密呢?来,我们看下面一张图(画的很辛苦,大家仔细看哈):
我们看到:OriginalFirstThunk 和 FirstThunk 他们都是两个类型为IMAGE_THUNK_DATA 的数组,它是一个指针大小的联合(union)类型。每一个IMAGE_THUNK_DATA 结构定义一个导入函数信息(即指向结构为IMAGE_IMPORT_BY_NAME 的家伙,这家伙稍后再议),然后数组最后以一个内容为0 的 IMAGE_THUNK_DATA 结构作为结束标志。
我们得到 IMAGE_THUNK_DATA 结构的定义如下:
IMAGE_THUNK_DATA STRUC
我们可以看出由于是union结构,所以IMAGE_THUNK_DATA 事实上是一个双字大小。该结构在不同时候赋予不同的意义(伟大神奇不得鸟……)。其实union这种数据结构很容易理解:说白了就是当时穷,能省就省,再说白了,就是几兄弟姐妹轮流穿一条裤子去相亲!理解了吧?哈哈~
那我们怎么来区分何时是何意义呢?
规定如下:
当 IMAGE_THUNK_DATA 值的最高位为 1时,表示函数以序号方式输入,这时候低 31位被看作一个函数序号。
当 IMAGE_THUNK_DATA 值的最高位为 0时,表示函数以字符串类型的函数名方式输入,这时双字的值是一个 RVA,指向一个 IMAGE_IMPORT_BY_NAME 结构。(演示请看小甲鱼解密系列视频讲座)
好,那接着我们讨论下指向的这个 IMAGE_IMPORT_BY_NAME 结构。IMAGE_IMPORT_BY_NAME 结构仅仅只有一个字型数据的大小,存有一个输入函数的相关信息结构。其结构如下:
IMAGE_IMPORT_BY_NAME STRUCT
结构中的 Hint 字段也表示函数的序号,不过这个字段是可选的,有些编译器总是将它设置为 0,Name 字段定义了导入函数的名称字符串,这是一个以 0 为结尾的字符串。
整个过程看起来有点绕有点烦,别急,后边我们有演示哈。
输入地址表(IAT)
为什么由两个并行的指针数组同时指向 IMAGE_IMPORT_BY_NAME 结构呢?第一个数组(由 OriginalFirstThunk 所指向)是单独的一项,而且不能被改写,我们前边称为 INT。第二个数组(由 FirstThunk 所指向)事实上是由 PE 装载器重写的。
好了,那么 PE 装载器的核心操作时如何的呢?这里就给大家揭秘啦~
PE 装载器首先搜索 OriginalFirstThunk ,找到之后加载程序迭代搜索数组中的每个指针,找到每个 IMAGE_IMPORT_BY_NAME 结构所指向的输入函数的地址,然后加载器用函数真正入口地址来替代由 FirstThunk 数组中的一个入口,因此我们称为输入地址表(IAT)。所以,当我们的 PE 文件装载内存后准备执行时,刚刚的图就会转化为下图:
此时,输入表中其他部分就不重要了,程序依靠 IAT 提供的函数地址就可正常运行。
输入表实例分析:(具体过程将在视频中演示,这里不啰嗦啦~)
工具:PEinfo.exe, UltraEdit, LordPE
解剖对象:hello.exe
在上一节课我们像小鹿一样的乱撞,终于撞到了输入表里边包含的函数名称,嘿嘿,不过地址,我们还是没能找着……这节课我们将深入来剖析输入表的结构,通过结合实例分析来帮助大家理解输入表的工作原理。
输入表结构
回顾一下,在 PE文件头的 IMAGE_OPTIONAL_HEADER 结构中的 DataDirectory(数据目录表) 的第二个成员就是指向输入表的。而输入表是以一个 IMAGE_IMPORT_DESCRIPTOR(简称IID) 的数组开始。每个被 PE文件链接进来的 DLL文件都分别对应一个 IID数组结构。在这个 IID数组中,并没有指出有多少个项(就是没有明确指明有多少个链接文件),但它最后是以一个全为NULL(0) 的 IID 作为结束的标志。
IMAGE_IMPORT_DESCRIPTOR 结构定义如下:
IMAGE_IMPORT_DESCRIPTOR STRUCT
union
TimeDateStamp DWORD ?
ForwarderChain DWORD ?
Name DWORD ?
FirstThunk DWORD ?
IMAGE_IMPORT_DESCRIPTOR ENDS Characteristics DWORD ?
OriginalFirstThunk DWORD ?
ends OriginalFirstThunk DWORD ?
TimeDateStamp DWORD ?
ForwarderChain DWORD ?
Name DWORD ?
FirstThunk DWORD ?
成员介绍:
OriginalFirstThunk
它指向first thunk,IMAGE_THUNK_DATA,该 thunk 拥有 Hint 和 Function name 的地址。
TimeDateStamp
该字段可以忽略。如果那里有绑定的话它包含时间/数据戳(time/data stamp)。如果它是0,就没有绑定在被导入的DLL中发生。在最近,它被设置为0xFFFFFFFF以表示绑定发生。
ForwarderChain
一般情况下我们也可以忽略该字段。在老版的绑定中,它引用API的第一个forwarder chain(传递器链表)。它可被设置为0xFFFFFFFF以代表没有forwarder。
Name
它表示DLL 名称的相对虚地址(译注:相对一个用null作为结束符的ASCII字符串的一个RVA,该字符串是该导入DLL文件的名称,如:KERNEL32.DLL)。
FirstThunk
它包含由IMAGE_THUNK_DATA定义的 first thunk数组的虚地址,通过loader用函数虚地址初始化thunk。在Orignal First Thunk缺席下,它指向first thunk:Hints和The Function names的thunks。
这个OriginalFirstThunk 和 FirstThunk明显是亲家,两家伙首先名字就差不多哈。那他们有什么不可告人的秘密呢?来,我们看下面一张图(画的很辛苦,大家仔细看哈):
我们看到:OriginalFirstThunk 和 FirstThunk 他们都是两个类型为IMAGE_THUNK_DATA 的数组,它是一个指针大小的联合(union)类型。每一个IMAGE_THUNK_DATA 结构定义一个导入函数信息(即指向结构为IMAGE_IMPORT_BY_NAME 的家伙,这家伙稍后再议),然后数组最后以一个内容为0 的 IMAGE_THUNK_DATA 结构作为结束标志。
我们得到 IMAGE_THUNK_DATA 结构的定义如下:
IMAGE_THUNK_DATA STRUC
union u1IMAGE_THUNK_DATA ENDSForwarderString DWORD ? ; 指向一个转向者字符串的RVAends
Function DWORD ? ; 被输入的函数的内存地址
Ordinal DWORD ? ; 被输入的API 的序数值
AddressOfData DWORD ? ; 指向 IMAGE_IMPORT_BY_NAME
我们可以看出由于是union结构,所以IMAGE_THUNK_DATA 事实上是一个双字大小。该结构在不同时候赋予不同的意义(伟大神奇不得鸟……)。其实union这种数据结构很容易理解:说白了就是当时穷,能省就省,再说白了,就是几兄弟姐妹轮流穿一条裤子去相亲!理解了吧?哈哈~
那我们怎么来区分何时是何意义呢?
规定如下:
当 IMAGE_THUNK_DATA 值的最高位为 1时,表示函数以序号方式输入,这时候低 31位被看作一个函数序号。
当 IMAGE_THUNK_DATA 值的最高位为 0时,表示函数以字符串类型的函数名方式输入,这时双字的值是一个 RVA,指向一个 IMAGE_IMPORT_BY_NAME 结构。(演示请看小甲鱼解密系列视频讲座)
好,那接着我们讨论下指向的这个 IMAGE_IMPORT_BY_NAME 结构。IMAGE_IMPORT_BY_NAME 结构仅仅只有一个字型数据的大小,存有一个输入函数的相关信息结构。其结构如下:
IMAGE_IMPORT_BY_NAME STRUCT
Hint WORD ?IMAGE_IMPORT_BY_NAME ENDS
Name BYTE ?
结构中的 Hint 字段也表示函数的序号,不过这个字段是可选的,有些编译器总是将它设置为 0,Name 字段定义了导入函数的名称字符串,这是一个以 0 为结尾的字符串。
整个过程看起来有点绕有点烦,别急,后边我们有演示哈。
输入地址表(IAT)
为什么由两个并行的指针数组同时指向 IMAGE_IMPORT_BY_NAME 结构呢?第一个数组(由 OriginalFirstThunk 所指向)是单独的一项,而且不能被改写,我们前边称为 INT。第二个数组(由 FirstThunk 所指向)事实上是由 PE 装载器重写的。
好了,那么 PE 装载器的核心操作时如何的呢?这里就给大家揭秘啦~
PE 装载器首先搜索 OriginalFirstThunk ,找到之后加载程序迭代搜索数组中的每个指针,找到每个 IMAGE_IMPORT_BY_NAME 结构所指向的输入函数的地址,然后加载器用函数真正入口地址来替代由 FirstThunk 数组中的一个入口,因此我们称为输入地址表(IAT)。所以,当我们的 PE 文件装载内存后准备执行时,刚刚的图就会转化为下图:
此时,输入表中其他部分就不重要了,程序依靠 IAT 提供的函数地址就可正常运行。
输入表实例分析:(具体过程将在视频中演示,这里不啰嗦啦~)
工具:PEinfo.exe, UltraEdit, LordPE
解剖对象:hello.exe
0
上一篇:小甲鱼PE详解之输入表(导入表)详解(PE详解07)
下一篇:qwt 6.1.0集成进Qt creator 2.8.1步骤
相关热门文章
- 多磁盘自动分区自动挂载脚本...
- c++ virtual析构函数详解...
- BLE-NRF51822教程14-adc和电池...
- input输入设备驱动
- QEMU源码分析系列(三) ...
- Serv-u的ODBC数据库做法(完整...
- 10种启动故障解决方法(转)...
- Auto CAD 2007中文版 迅雷免费...
- MATLAB中plot的用法
- 出现“high definition audio...
- linux dhcp peizhi roc
- 关于Unix文件的软链接
- 求教这个命令什么意思,我是新...
- sed -e "/grep/d" 是什么意思...
- 谁能够帮我解决LINUX 2.6 10...
给主人留下些什么吧!~~
评论热议
0 0
- 小甲鱼PE详解之输入表(导入表)详解2(PE详解08)
- 小甲鱼PE详解之输入表(导入表)详解2(PE详解08)
- 小甲鱼PE详解之输入表(导入表)详解2(PE详解08)
- 小甲鱼PE详解之输入表(导入表)详解2(PE详解08)
- 小甲鱼PE详解之输入表(导入表)详解2(PE详解08)
- 小甲鱼PE详解之输入表(导入表)详解2(PE详解08)
- 小甲鱼PE详解之输入表(导入表)详解2(PE详解08)
- 小甲鱼PE详解之输入表(导入表)详解2(PE详解08)
- 小甲鱼PE详解之输入表(导入表)详解2(PE详解08)
- 小甲鱼PE详解之输入表(导入表)详解2(PE详解08)
- 小甲鱼PE详解之输入表(导入表)详解2(PE详解08)
- 小甲鱼PE详解之输入表(导入表)详解2(PE详解08)
- 小甲鱼PE详解之输入表(导入表)详解2(PE详解08)
- 小甲鱼PE详解之输入表(导入表)详解2(PE详解08)
- 小甲鱼PE详解之输入表(导入表)详解2(PE详解08)
- 小甲鱼PE详解之输入表(导入表)详解(PE详解07)
- 小甲鱼PE详解之输入表(导入表)详解(PE详解07)
- 小甲鱼PE详解之输入表(导入表)详解(PE详解07)
- 小甲鱼PE详解之区块表(节表)和区块(节)续(PE详解05)
- 小甲鱼PE详解之区块描述、对齐值以及RVA详解(PE详解06)
- JAVA基础【3.9】《Java核心技术1》Java的基本程序设计结构-大数值
- ThinkPad E550 加装固态安装Windows 7系统
- 小甲鱼PE详解之输入表(导入表)详解(PE详解07)
- 小甲鱼PE详解之输入表(导入表)详解2(PE详解08)
- Java运算符
- Android ActionBar隐藏修改图标和标题
- qwt 6.1.0集成进Qt creator 2.8.1步骤
- tq2440编译ARM版本的Qt4出错问题解决
- load_elf_binary阅读(1)
- 设计模式之装饰者模式
- load_elf_binary阅读(2)
- 日本“冷知识”你都知道吗?
原创粉丝点击
热门IT博客
热门问题
老师的惩罚
人脸识别
我在镇武司摸鱼那些年
重生之率土为王
我在大康的咸鱼生活
盘龙之生命进化
天生仙种
凡人之先天五行
春回大明朝
姑娘不必设防,我是瞎子
韩青禹
韩青个人资料
韩青老婆个人资料
韩静
女友韩静
韩非
韩非名言
韩非怎么死的
韩非h明珠夫人
宋相思韩非深
卫庄怎么不救韩非
韩风
黑暗系女头韩风
韩风源自助餐
韩风源自助餐价格
韩风婚纱摄影
韩飞
都市医武狂少韩飞
爱情是从告白开始的 韩飞
韩餐
韩餐图片
做韩餐
韩餐网
韩餐店名
韩餐美食
韩餐海带汤
韩餐炒菜
韩餐培训班
韩餐怎么做
韩餐都有什么
韩饭
韩馥
我的父亲叫韩馥 向嘉庚
韩鹏
韩龙
韫
某韫
韫色过浓
韫怎么读
权宠某韫
爱新觉罗韫颖