吾爱汇编

 找回密码
 立即注册

QQ登录

绑定QQ避免忘记帐号

查看: 5954|回复: 11

[转载技术] 第三十四章-手脱UPX,修复IAT

[复制链接]
Shark恒 发表于 2015-1-20 17:13 | 显示全部楼层 |阅读模式

                      第三十四章-手脱UPX,修复IAT
我们在上一章中给大家介绍了IT(导入表),IAT(输入函数地址表)的相关概念以及原理。有的人可能会认为,我们只是想修复IAT呀,并不需要知道IAT的具体原理以及它是如何被填充的吧?不是有现成的IAT自动修复工具吗?可以很明确的告诉大家,了解操作系统是如何填充IAT的过程非常有必要的。因为很多壳会检测这些常用的IAT修复工具,致其不能正常运行,在这种情况下,我们就需要自己进行相应的手工修复。
本章我们还是用最简单的CRACKME UPX作为例子,我们将对其进行脱壳以及修复IAT,让其能正常运行。
首先第一步我们来定位OEP,我们用OD加载CRACKME UPX。
image002.jpg
这里我们用ESP定律来定位OEP,现在我们停在了入口点处,单击F7键执行PUSHAD。
image004.jpg
在ESP寄存器值上面单击鼠标右键选择-Followin Dump。
就可以在数据窗口中定位到刚刚PUSHAD指令保存到堆栈中的寄存器环境了,我们选中前4个字节,我们通过单击鼠标右键选择Breakpoint-Hardware,on access-Dword给这4个字节设置硬件访问断点。
image006.jpg
运行起来,马上就断在了JMPOEP指令处。
image008.jpg
我们直接按F7键单步到OEP处。
image010.jpg
好了,现在我们处于OEP处,原程序区段已经解密完毕,我们现在可以进行dump了。
前面已经提到过,有很多dump的工具,OD有一个款插件OllyDump的dump效果也不错。上一章中我们使用LordPE来进行dump的 ,这里我们来使用另外一个工具PE TOOLS来进行dump。
我们用PE-TOOLS定位到CRACKMEUPX所在的进程。
image012.jpg
这里这个crackme.exe就是,因为我忘了把那个重命名的CRACKME UPX放到哪里去了,所以我又重新弄了一个新的,忘了改名字,直接命名为原来的名字crackme.exe了,当前这个crackme.exe进程停在了OEP处。
image014.jpg
单击鼠标右键选择-Dump Full。
image016.jpg
image018.jpg
这里,我们就dump完毕了,接下来我们来修复IAT,关闭PE TOOLS,将PE TOOLS目录下的dumped.exe拷贝一份到CRACKMEUPX所在的目录中。
image020.jpg
我们知道没有修复IAT,是不能运行的,我们双击Dumped.exe看看会发生什么。
image022.jpg
提示无效的win32程序,我们需要修复IAT,我们需要用到一个工具,名字叫做ImportREConstructor,不要关闭OD,将让其断在OEP处,Import REConstructor需要用到它。
image024.jpg
运行Import REConstructor,定位到CRACKME UPX所在的进程。
这里很多初学者可能会有疑问-如何定位IAT的起始位置和结束位置呢?我们知道当前该CRACKME UPX进程停在了OEP处,此时壳已经将导入表破坏了,我们知道IID项的第四个字段为动态库名称字符串的指针,第五个字段为其对应IAT项第一个元素的地址,这些已经被壳破坏了,我们需要通过其他方式来定位。
我们知道API函数的调用通常是通过间接跳转或者间接CALL来实现的。
JMP [XXXXXXX] orCALL [XXXXXX]
上一章我们已经介绍过了,这样是直接调用IAT中保存的API函数地址。我们来看看CRACKME UPX。
image026.jpg
这里我们看到第二行的CALL指令,OD提示调用的是Kernel32.dll中的GetModuleHandleA,是个间接跳转,我们选中这一行,单击鼠标右键选择-Follow。
image028.jpg
image030.jpg
这里我们定位到获取IAT中函数地址的跳转表,这里就是该程序将要调用到的一些API函数,我们可以看到这些跳转指令的都是以机器码FF 25开头的,有些教程里面说直接搜索二进制FF 25就可以快速的定位该跳表。
其实,并不是所有的程序都通过这种间接跳转来调用API函数,所以直接搜索FF 25这种方法有时候会失败,而通过定位某个API函数的调用处,然后Follow到跳表是这种方式才是一直有效的。
这里我们看到JMP [403238]:
image032.jpg
403238是IAT的其中一个元素,里面保存的是GetModuleHandleA这个API函数的入口地址,我们dump出来的程序的IAT部分跟这里是一样的,我们来看看IAT的起始位置和结束位置分别在哪儿。
其实,大家可以通过跳转表中最小的地址和最大的地址算出IAT的起始位置和结束位置,但是比较慢,比较好的做法是,直接将数据窗口往上滚动,我们知道IAT的每个元素中都保存了一个API函数的入口地址,比如这里的7C80B529,在数据窗口中显示的形式为29 B5 80 7C (小端存储),我们将显示列数调整为两列,这样看起来更方便一些。
image034.jpg
这里我们看到的就是整个IAT了,我们直接下拉到IAT的尾部,我们知道属于同一个动态库的API函数地址都是连续存放的,不同的动态库函数地址列表是用零隔开的。
image036.jpg
有一些壳会将这部分全部填零,使得我们的IAT重建工作变得异常困难,这里由于原程序还需要调用这些API函数,所以该壳没有将这部分填零,我们现在来看看其中一个动态库的IAT项,如下:
image038.jpg
这里显示了该DLL中的三个API函数,入口地址都是7C XXXXXX的形式,然后紧接着是一个零。
我们单击工具栏中的M按钮看看7C开头的地址是属于哪个DLL的。
image040.jpg
我们可以看到这几个地址处于kernel32.dll的代码段范围内。
image042.jpg
当然在你们的机器上kernel32.dll可能在别的地址处,但在我的机器上,这几个函数地址是属于kernel32.dll的。
image044.jpg
属于kernel32.dll中的函数地址这里我用粉红色标注出来了,我们再来看看77DXXXXX这类地址是属于哪个DLL的。
image046.jpg
这里我们可以看到77DXXXXX这类地址是属于user32.dll的,我也用粉红色标注出来了。
image048.jpg
我们可以看到user32.dll的这些函数地址项上面是全零的,表示IAT的起始地址为403184,403184中存放的了IAT中的第一个元素。
image050.jpg
这里我们用红线标注出来了,403184是IAT的起始地址。有些强壳可能会将IAT前后都填充上垃圾数据,让我们定位IAT的起始位置和结束位置更加困难。但是我们知道IAT中的数值都是属于某个动态库代码段范围内的,如果我们发现某数值不属于任何一个动态库的代码段的话,就说明该数值是垃圾数据。
现在我们知道了IAT开始于403184,我们现在来看一看IAT的结束位置在哪里。
后面我们会遇到有些壳会将IAT重定向到壳的例程中去,然后再跳转到API函数的入口处,这样的话,上面这样定位IAT的起始和结束位置的做法就行不通了。该如何应对这样情况,我们后面再来介绍。
image052.jpg
这里我们可以看到IAT的最后一个元素的地址形式为76XXXXXX,我们来看看它是属于哪个DLL的。
image054.jpg
这里我们可以看到其是属于COMDLG32.DLL的,后面全是零了,所以40328C是IAT的结束位置。
好了,现在我们知道了IAT的起始位置和结束位置。
begin:403184
end:40328c
ImportREConstructor重建IAT需要三项指标:
1)IAT的起始地址,这里是403184,减去映像基址400000就得到了3184(RVA:相对虚拟地址)。
2)IAT的大小
  IAT的大小 = 40328C- 403184 = 108(十六进制)
3)OEP = 401000(虚拟地址)- 映像基址400000 = 1000(OEP的RVA)。
image056.jpg
我们将这三条数据输入到Import REConstructor中。
image058.jpg
我们单击Get Imports。
image060.jpg
我们看到Import REConstructor找到了IAT中的每项元素,并且valid显示的都是YES,表示这些项都是有效的,那么无效的是什么情况呢,有些壳会将这些值进行重定向,并不是直接调用API函数,就会导致Import REConstructor定位出来的项都是无效的,好了现在这些项都是有效的,我们就可以进行dump了。
在dump之前我们先来看看User32.dll这个项中内容是什么,选中该项,单击左边的+号就可以展开。
image062.jpg
好了,我们可以看到每个API函数名称字符串的指针都显示出来了,该程序调用的第一个API函数GetModuleHandleA这一项在哪里呢?
image064.jpg
大家应该还记得,IAT的中的第一项值为403238,减去映像基址400000就等于3238,位于kernel32.dll中。
image066.jpg
我们单击kernel32.dll这一项左边的+号。
image068.jpg
可以看到3238对应的正好是GetModuleHandleA。好了,现在我们就可以对之前dump出来的程序的IAT进行修复了,我们单击Fix Dump按钮。
image070.jpg
选中之前dump出来的文件。
image072.jpg
我们可以看到修复完毕了,修复过的文件被重命名为了dumped_.exe。我们来看一看。
image074.jpg
我们双击它,看看能不能正常运行。
image076.jpg
我们可以看到还是提示无效的win32程序,嘿嘿,为什么呢?别担心,通常修复了IAT以后,都会出现这种状况。我们现在来打开PE TOOLS。
image078.jpg
我们选择菜单项中的Rebuild PE(重建PE),我们找到刚刚的dumped_.exe,重建之,运行,发现可以正常运行了,嘿嘿。
image080.jpg
大家将这个程序拿到其它机器上运行也是没有问题的。
我们将dumped_.exe加载到OD中。
image082.jpg
这里OD提示入口点位于代码段之外,因为UPX壳将代码段指定到了第三个区段。这个问题可以修复。我们下面来修复它。
image084.jpg
我们单击OK,停在了入口点处,我们在数据窗口中定位到400000地址处。
image086.jpg
将数据窗口的显示模式切换为PE头模式。
image088.jpg
image090.jpg
往下拉:
image092.jpg
可以看到PE头的相对虚拟地址(RVA)为80,即虚拟地址(VA)为400080。
image094.jpg
这里我们看到Base of Code = 9000,表示代码段的相对虚拟地址为9000,我们需要将代码段的相对虚拟地址修改为1000。
image096.jpg
我们选中BaseOfCode这一行,单击鼠标右键选择-Modify integer。
image098.jpg
image100.jpg
修改完毕以后我们将所做的修改保存到文件。
image102.jpg
image104.jpg
image106.jpg
我们再次加载修复过的程序,可以看到OD没有弹出警告窗口了。我们单击工具栏中M按钮看看各个区段的描述信息。
image108.jpg
我们可以看到这里多出了一个区段,名字叫做mackt,这是Import REConstructor给该程序添加的一个新的区段,专门用来存放新的导入表。我们在数据窗口中看一看导入表的情况(PE头显示模式)。
image110.jpg
我们可以看到导入表的相对虚拟地址为B000,即虚拟地址为40B000,刚好就是Import REConstructor添加的那个区段。
我们将数据窗口的显示模式切换为正常模式。
image112.jpg
我们在数据窗口中定位到导入表40B000地址处。
image114.jpg
这里我们可以看到第一个IID,第四个字段为DLL名称字符串的指针,这里是B078(RVA),即40B078(VA)。
image116.jpg
指向的是user32.dll。
第五个字段为该DLL IAT项的起始地址的RVA,这里是3184,即IAT中的第一个元素的地址为403184。
image118.jpg
这里我们可以看到IAT中保存的各个API函数的入口地址。我们定位到可执行文件中对应IAT的偏移处,看看各个API函数名称字符串指针的情况如何。
image120.jpg
image122.jpg
我们可以看到IAT项中的值为B084,即40B084,指向的刚好是KillTimer这个API函数名称字符串。
image124.jpg
这样我们就通过Import REConstructor完成IAT的重建工作,操作系统在程序启动的时候就可以根据IAT中API函数名称字符串通过调用GetProcAddress获取到相应API函数地址,然后重新填充到IAT中。
本章我们就完成了第一个IAT的修复工作,虽然不是很难,但是也算是对我们前面章节知识点的一个汇总吧。大家要好好理解本章的内容。
本章我们没有介绍AntiDump,等我们后面遇到了再介绍。

本系列文章汉化版转载看雪论坛

感谢原作者:RicardoNarvaja(西班牙人)
原作者个人主页:http://www.ricardonarvaja.info/

感谢热心翻译的朋友:
1~3章译者:BGCoder
4~58章译者:安于此生

全集配套程序下载地址:
链接: http://pan.baidu.com/s/1eQzTWfo 密码: vytv



评分

参与人数 11HB +14 THX +1 收起 理由
Jawon + 2
一路走来不容易 + 1
Soul1999 + 1
zxjzzh + 2 [吾爱汇编论坛52HB.COM]-学破解防破解,知进攻懂防守!
消逝的过去 + 2
l278785481 + 1
壮志凌云 + 1
MoeRay + 1
ghostxu + 1 [吾爱汇编论坛52HB.COM]-学破解防破解,知进攻懂防守!
jaunic + 1
hnymsh + 2

查看全部评分

吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
hackysh 发表于 2022-2-20 00:06 | 显示全部楼层
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
ghostxu 发表于 2022-2-22 18:01 | 显示全部楼层

互相讨论,共同进步
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
头像被屏蔽
别管我了行 发表于 2022-3-2 03:49 | 显示全部楼层
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
ghostxu 发表于 2022-3-17 11:01 | 显示全部楼层

精彩文章希望继续努力
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
头像被屏蔽
ldljlzw 发表于 2022-3-20 14:49 | 显示全部楼层
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
壮志凌云 发表于 2022-4-3 13:41 | 显示全部楼层

修复IAT,还有NO怎么弄?
1648964246(1).png
1648964344(1).png
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
曾经沧海 发表于 2022-11-20 19:26 | 显示全部楼层

爱论坛,爱网友!
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
一生逍遥 发表于 2022-12-4 10:46 | 显示全部楼层

感谢楼主分享,用着试试看
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
曾经沧海 发表于 2023-4-4 11:14 | 显示全部楼层

大佬太强了
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

警告:本站严惩灌水回复,尊重自己从尊重他人开始!

1层
2层
3层
4层
5层
6层
7层
8层
9层
10层

免责声明

吾爱汇编(www.52hb.com)所讨论的技术及相关工具仅限用于研究学习,皆在提高软件产品的安全性,严禁用于不良动机。任何个人、团体、组织不得将其用于非法目的,否则,一切后果自行承担。吾爱汇编不承担任何因为技术滥用所产生的连带责任。吾爱汇编内容源于网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除。如有侵权请邮件或微信与我们联系处理。

站长邮箱:SharkHeng@sina.com
站长QQ:1140549900


QQ|RSS|手机版|小黑屋|帮助|吾爱汇编 ( 京公网安备11011502005403号 , 京ICP备20003498号-6 )|网站地图

Powered by Discuz!

吾爱汇编 www.52hb.com

快速回复 返回顶部 返回列表