深入了解IAT原理
---------------------------编辑时突然死机自动保存也没有用真的痛苦回头补上------------------
输入表中的这些间接跳转是无法正常运行的,因为在正常情况,操作系统必须知道指向各个API函数名称字符串的指针,然后通过GetProcAddress定位到各个API函数正确的入口地址并填充到IAT中,这样这些间接跳转才能起作用。可我们脱壳之后没有这些指针了自然也就无法运行了。
搞明白了问题下一步就着手重建输入表,下面我们来看看未加壳程序的IAT。
我们来定位该CrackMe PE结构中一些重要字段。首先在数据窗口中定位400000地址处。

单击鼠标右键选择-Special-PE header切换到PE头的显示模式。

往下拉。我们可以看到PE头的偏移为100。即PE头位于400100地址处。

继续往下拉,我们可以看到IT(导入表)的指针,这里大家不要将其跟IAT搞混淆了。
IT = 导入表
IAT = 输入函数地址表
我们知道当程序启动之前操作系统会将各个API函数的地址填充到IAT中,那么IT(导入表)又是怎么一回事呢?首先我们定位到导入表,该导入表偏移值为3000(即虚拟地址为403000),长度为670(十六进制),
即403670为导入表的结尾。我们一起来看一看。

我们将数据窗口的显示模式切换为正常状态,这就是导入表了,我们来介绍一下导入表的结构吧。

我们选中的这20个字节是导入表的描述符结构。官方的叫法为IMAGE_IMPORT_DESCRIPTOR。每组为20个字节,IMAGE_IMPORT_DESCRIPTOR包含了一个的字符串指针,
该指针指向了某个的动态链接库名称字符串。
这里我们将IMAGE_IMPORT_DESCRIPTOR简称为IID。这里选中的部分为导入表中的第一个IID,共五个DWORD,其中5个DWORD字段的含义如下:
OriginalFirstThunk
TimeDateStamp 时间戳
ForwarderChain 链表的前一个结构
Name1 指向DLL名称的指针
FirstThunk 指向的链表定义了针对Name1这个动态链接库引入的所有导入函数
前三个字段不是很重要,对于我们Cracker来说,我们只对第4,5字段感兴趣。
我们来看个例子:
正如大家所看到的,第4个字段为指向DLL名称字符串的指针,我们来看看403290处是哪个DLL的名称。
这里我们可以看到是USER32.DLL,第5个字段指向了USER32.DLL对应IAT项的起始地址,即403184。(不过我觉得位置不太对啊这也不是第四个DWORD啊而且403184在哪啊看不到啊)

既然我们已经知道了对应IAT的起始地址,那就跳到403184看看

这样我们就到达了IAT,导入表的结束地址为403670(根据起始地址和长度计算得到)。导入表中的每个IID项指明了DLL的名称以及其对应IAT项的起始地址。紧凑的排列在一起,供操作系统使用。
大量实验表明,IAT并不一定位于在导入表中。IAT可以位于程序中任何具有写权限的地方,只要当可执行程序运行起来时,操作系统可以定位到这些IID项,然后根据IAT中标明的API函数名称获取到函数地址即可。
下面我们来总结一下操作系统填充IAT的具体步骤:
1:定位导入表
2:解析第一个IID项,根据IID中的第4个字段定位DLL的名称
3:根据IID项的第5个字段DLL对应的IAT项的起始地址
4:根据IAT中的指针定位到相应API函数名称字符串
5:通过GetProcAddress获取API函数的地址并填充到IAT中
6:当定位到的IAT项为零的时候表示该DLL的API函数地址获取完毕了,接着继续解析第二个IID,重复上面的步骤。
下面我们来手工的体验一下这个步骤:
1)定位导入表

2)定位到导入表的起始地址

3)根据第一个IID项中的第四个字段得到DLL名称字符串的指针,这里指向的是USER32.DLL

根据第五个字段的内容定位到IAT项的起始地址,这里是403184,我们定位到该地址处。


这里我们可以看到已经被填充了正确的API函数的入口地址,跟我们dump出来的结果一样,我们再来看看相应的可执行文件偏移处的内容是什么。

这里我们可以看到第一个API函数的名称位于4032CC地址处,我们定位到该地址处。

第一个API函数是KillTimer,我们在OD中看到的KillTimer的入口地址是操作系统调用GetProcAddress获取到的。

这里我们可以看到KillTimer的入口地址为75EC79DB。该地址将被填充到IAT相应单元中去覆盖原来的值,我们看到已经被覆盖了。

这里是IAT中的第一元素。
我们再来看下一个元素,向后偏移4就是,是2f 7d ec 75这里,来看一看该API函数名称字符串的指针是多少。
定位到可执行文件的相应偏移处:

32D8即4032D8,来看看该API函数的名称是什么,这里由于该指针不为零,说明该API函数还是位于USER32.DLL中的。

这里我们可以看到第二个API函数是GetSystemMetrics,通过该函数名称可以通过GetProcAddress获取到其函数地址然后填充到IAT中。接下来按照以上步骤依次获取USER32.DLL中的其他的函数地址,直到遇到的IAT项为零为止。我们来看一看可执行文件中结束项位于哪里。
我们可以看到当IAT中元素为零的时候表明USER32.DLL就搜索完毕了,我们接着来看下一个IID。

这里我们根据第4,5字段分别可以知道第二个DLL的名称,以及对应IAT项的起始地址。
DLL的名称字符串位于40329B地址处。

我们可以看到第二个DLL为KERNEL32.DLL,该DLL对应的IAT项起始地址为40321C。
这里我们可以看到前一个DWORD是零,表示USER32.DLL的API函数的结尾。40321C表示KERNEL32.DLL的API函数地址项的开始。
根据这些指针我们就可以定位到kernel32.dll中的各个API函数名称字符串,进而获取到其函数入口地址,接着填充到对应的IAT项中覆盖原来的内容。
本章这里就结束了,我给大家描述了IAT被填充的整个过程,了解这个过程对大家来说是很有必要的,这部分内容是重建IAT必备的基础知识,大家只有理解了其基本原理,然后配上适当的工具,就可以方便进行IAT的修复工作了。
好了,下一章我们将介绍具体如何修复IAT。
仅允许非商业转载,转载请注明出处
深入了解IAT原理的更多相关文章
- IAT Hook 原理分析与代码编写
Ring 3层的 IAT HOOK 和 EAT HOOK 其原理是通过替换IAT表中函数的原始地址从而实现Hook的,与普通的 InlineHook 不太一样 IAT Hook 需要充分理解PE文件的 ...
- 浅谈IAT加密原理及过程
上一次做完代码段加密后,又接触到了新的加密方式:IAT加密 IAT加密是通过隐藏程序的导入表信息,以达到增加分析程序的难度.因为没有导入表,就无法单纯的从静态状态下分析调用了什么函数,动态调试时,也无 ...
- 手动修复IAT
现在我们已经了解了IAT的的工作原理,现在我们来一起学习手动修复IAT,一方面是深入了解运行过程一方面是为了避免遇到有些阻碍自动修复IAT的壳时不知所措. 首先我们用ESP定律找到加了UPX壳后的OE ...
- JSON Web Token(JWT)原理和用法介绍
JSON Web Token(JWT)是目前最流行的跨域身份验证解决方案.今天给大家介绍一下JWT的原理和用法. 官网地址:https://jwt.io/ 一.跨域身份验证 Internet服务无法与 ...
- JWT认证原理及使用
一.JWT原理: 参考文章:https://www.jianshu.com/p/180a870a308a 1.传统的登录方式: 浏览器输入用户名密码,服务端校验通过,根据用户信息生成一个token,将 ...
- Visual Leak Detector原理剖析
认识VLD VLD(Visual Leak Detector)是一款用于Visual C++的开源内存泄漏检测工具,我们只需要在被检测内存泄漏的工程代码里#include “vld.h”就可以开启内存 ...
- Dll注入:修改PE文件 IAT注入
PE原理就不阐述了, 这个注入是PE感染的一种,通过添加一个新节注入,会改变PE文件的大小,将原有的导入表复制到新节中,并添加自己的导入表描述符,最后将数据目录项中指向的导入表的入口指向新节. 步骤: ...
- pandas DataFrame的查询方法(loc,iloc,at,iat,ix的用法和区别)
pandas DataFrame的增删查改总结系列文章: pandas DaFrame的创建方法 pandas DataFrame的查询方法 pandas DataFrame行或列的删除方法 pand ...
- IAT Hook
@author: dlive 0X01 IAT Hook的优缺点 优点:工作原理与实现都比较简单 缺点:如果想钩取的API不在目标进程的IAT中,那么就无法使用该技术进行钩取操作.即如果要钩取的API ...
随机推荐
- Chrome控制台使用详解
Chrome的开发者工具已经强大到没朋友的地步了,特别是其功能丰富界面友好的console,使用得当可以有如下功效: 更高「逼格」更快「开发调试」更强「进阶级的Frontender」 Bug无处遁形「 ...
- 暂停和播放CSS3动画的两种实现方法
1,直接修改animationPlayState <!DOCTYPE html> <html> <head lang="en"> <met ...
- angular.extend、angular.$watch、angular.bootstrap
1.angular.extend:依次将第二个参数及后续的参数的第一层属性(不管是简单属性还是对象)拷贝给第一个参数的第一层属性,即如果是对象,则是引用的是同一个对象,并返回第一个参数对象. 直接上代 ...
- 关于js中的表单事件
表单结构如下所示: <form > <input type="text" name="txt" id="txt" valu ...
- JavaWeb 后端 <三> 之 Response Request 学习笔记
一.响应对象 Response(重点:HTTP协议响应部分) 查看
- git分支的使用
本文章假定你已经接触了一些git的基本概念和基本的操作知识 这里先贴出关于分支的一些常用命令 git branch /*查看所有分支*/git branch <branch-name> / ...
- 二维坐标点排序(JavaScript)
今天给大家分享下最近web项目中出现的一个技术难点问题--坐标排序: 如下图所示,要求在前端页面上按顺序将下面5个模块的坐标依次保存至数据库 现在已知信息如下: 1.每个模块分别为一个div 2.每个 ...
- 如何清除img图片下面有一片空白
最近在做项目突然发现用了img后有个空白区,如下图: 真的很影响美观,那么是什么原因造成的呢? 右键查看元素查看上下文的margin和padding也没有找到这个空白的来源. 只好上网看看别人是怎么说 ...
- background背景透明内容不透明
.demo{ padding: 25px; background-color:#000000;/* IE6和部分IE7内核的浏览器(如QQ浏览器)下颜色被覆盖 */ background-color: ...
- 登录界面Demo
今天记载一个Demo,这个是我练习项目中用到,供新手看看,界面图: