吾爱汇编

 找回密码
 立即注册

QQ登录

绑定QQ避免忘记帐号

查看: 6807|回复: 24

[转载技术] 第三十七章-论IAT重定向之修复

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

                第三十七章-论IAT重定向之修复
本章我将给大家介绍几种常见的修复IAT重定向的方法。
我们只是介绍修复IAT重定向的基本思路,有些方法可能对有个壳有效,对有的壳无效,这个就需要大家多加练习,举一反三,触类旁通了。
image002.jpg
我们用OD加载UnPackMe_tElock0.98,按照上一章节介绍的方法定位到其OEP,这里就不再赘述了。IAT中有部分元素被重定向到壳创建的区段中去了。
image004.jpg
这些重定向过的IAT项我们需要修复。
我们首先单步到第一个API函数GetVersion的调用处。
image006.jpg
在数据窗口中定位到该IAT项 460ADC,这里460ADC保存的内容是9F06F7,我们打开IMP REC,填充上IAT起始地址的RVA,大小以及OEP的RVA后,看一看无效的项。
image008.jpg
我们可以看到9F06F7这一项是无效的。
image010.jpg
RVA 60ADC对应的IAT项正好是460ADC。
我们回到OD中,上一章我们已经介绍过了如何定位GetVersion这个API函数的入口地址,其实OD有一个自动单步跟踪的功能,我们用这个自动单步跟踪的功能可以方便定位到重定向过的IAT项对应的API函数入口地址,重定向过的IAT项单步步入5,6行就可以定位到其对应的API函数。
image012.jpg
我们在4271D6这条CALL指令的返回地址处设置一个断点,这里我们缺少一步,由于OD的自动跟踪功能是不会主动停止的,我们应该设置自动跟踪停止的条件。
image014.jpg
我们选择主菜单中Debug-Set condition,设置跟踪停止的条件。
image016.jpg
我们可以看到弹出了一个对话框,对话框的标题为Conditionto pause run trace(设置自动跟踪终止的条件)。
如果设置了EIP is in range(EIP的范围)这个选项的话,当EIP位于这个范围的时候,OD就会停止自动跟踪。
例如:
image018.jpg
例如,这里我们将这个范围指定为401000~ 500000,那么OD自动跟踪,当EIP在401000 ~ 500000这个范围的时候就会停止自动跟踪,这里我们只是举个例子,并不是真的要将范围指定为401000 ~ 500000,因为我们需要OD自动跟踪停在API函数的入口处,所以我们打开区段列表窗口看看将这个范围指定为什么比较合适。
image020.jpg
我们看到区段列表窗口中用浅蓝色标注出来的部分,这些是系统DLL的区段,当EIP位于主程序的区段或者壳创建的区段中,我们让OD自动继续跟踪,OD跟进到DLL中的时候,我们需要OD停止跟踪,所以这里我们将该范围设置为5800000~7FFFFFFF,这样就能确保OD跟进到任意一个系统DLL中的时候就会停止跟踪,这里我并没有精确的设置为58C30000 ~ 7FFFFFFF,大家想设置的精确一点也是可以的。
image022.jpg
也就是说OD自动单步跟踪,当EIP位于任意一个系统DLL的区段中的时候就会停止跟踪。
image024.jpg
这里我们给4271DC处CALL指令以及其返回地址处分别设置一个断点。
image026.jpg
我们将之前定位OEP时设置的内存访问断点清除掉,接着给460ADC处的IAT项设置4字节的内存访问断点,运行起来,当该值被读取的时候,OD就会断下来。
image028.jpg
我们现在跟到了4271D6的CALL指令处。
image030.jpg
现在可以让OD自动跟踪了。
image032.jpg
这里我们在反汇编窗口中单击鼠标右键,有两个自动跟踪的选项,第一个是Trace into(自动单步步入),第二个是Trace over(自动单步步过),这里我们选择-Trace into。
image034.jpg
这里满足了停止跟踪的条件,OD停了下来。
image036.jpg
当EIP位于58000000~7FFFFFFF这个范围的时候,OD就会断下来,为了保险起见,我们还是需要看一下OD的下方的提示信息,看看是不是由于其他异常原因导致断下来的。OD下面的提示信息显示是由于EIP位于58000000~7FFFFFFF的范围内,满足了停止自动跟踪的条件,所以断了下来。
image038.jpg
接下来的工作就是检查调用完该API函数以后是不是返回到我们刚刚设置了断点的返回地址处,因为有些壳会调用多个API函数来混淆视听,前面调用的几个API函数都是用来迷惑我们的,最后一个API函数才是其真正要调用的。
这里我们可以看到堆栈窗口显示的返回地址正好是我们刚刚设置了断点的那个返回地址4271DC。
我们也可以在该返回地址上面单击鼠标右键选择Follow in Disassembler定位反汇编窗口中,也可以看到正好是我们设置了断点的返回地址处。
image040.jpg
image042.jpg
好了,现在停在了API函数的入口处,但是OD这里并没有提示API函数的名称,我们需要确定调用的是哪个API函数,我们来分析一下DLL的代码,在反汇编窗口中单击鼠标右键选择-Analysis-Analyse code。
image044.jpg
image046.jpg
这里我们可以OD左下方的解释窗口中看到该API函数的名称为Kernel32.GetVersion,EIP寄存器中也显示了API函数的名称。
image048.jpg
这里我们再来看下一个自动跟踪终止的条件选项EIP is outside the range,通过设置这个选项我们也可以定位到其要调用的API函数:
image050.jpg
(PS:这里原文笔误,作者写错了,作者写成了401000~ 129000,因为是401000 ~ 1272000才对)
这里将EIP is outside the range这个选项的为设置为401000~1272000,即当EIP超出了主程序所在区段的范围就会停止自动跟踪。
大家可以自行尝试。接下来还有一种情况。
image052.jpg
有少数壳会将区段创建在系统DLL的区段之间,这样的话,我们需要用到Condition is TRUE(当条件成立时)这个选项了,这里我们搜索EIP指向的指令为RET,并且栈顶指针指向的是4271DC的指令。
这两个条件同时满足我们可以使用&&,表示这两个条件要同时满足,相当于AND。
如果两个条件满足任意一个的话,我们可以使用||,相当于OR。
这里我们将自动跟踪终止条件设置为[ESP] == 4271DC && byte [EIP] == 0C3
[ESP] == 4271DC即栈顶指针指向了返回地址4271DC。
byte [EIP] == 0C3即EIP指向了API函数的返回指令RET。
接着让OD自动跟踪,我们可以看到断在了API函数的返回指令RET处。
image054.jpg
image056.jpg
由于[ESP] == 4271DC,byte [EIP] == 0C3这两个条件都满足了,所以OD停止了自动跟踪,现在我们位于API函数的返回指令RET处,这里由于我们并不在该API函数的入口地址处,所以OD并不会提示该API函数的名称,因此有些壳会自己模拟执行API函数开头的两,三条指令,然后从API函数的第四,五行开始指令,这样OD也不会提示该API函数的名称,尽管如此,我们还是有办法可以定位该API函数的名称。
我们单击工具栏中的...按钮查看自动跟踪的日志信息。
image058.jpg
我们看到红色箭头标注的这一行也没有显示API函数名称,我们分析一下代码,然后在该行上双击鼠标左键。
image060.jpg
这里我们可以看到OD中EIP寄存器显示了该API函数的名称,当前EIP的值显示为红色,表示EIP寄存器被修改了,如果我们按减号键的话,EIP会变为前一条执行过的指令的地址。
有些壳会去模拟执行API函数前几条指令,然后再去指令API函数后面的代码,这样OD也不会提示该API函数的名称。
我们来看看如何应对这种情况:
我们在API函数返回指令RET的下一行指令空白处单击空格键,CALL 我们怀疑的API函数入口地址,这里我们输入:
CALL 7C8114AB。
image062.jpg
我们可以看到此时OD提示API函数的名称为Kernel32.GetVersion。
image064.jpg
如果我们CALL不是API函数的入口地址的话,OD就不会显示函数名称了。
image066.jpg
image068.jpg
我们单击鼠标右键选择-undo selection(撤销刚刚所做的修改)。
image070.jpg
好了,我们现在知道如何手工定位API函数的名称了,打开IMP REC,我们需要对重定位过的IAT项进行修复,在60ADC这个无效的IAT项上面双击鼠标左键,在弹出的窗口中选中API函数所在的模块以及其函数名称。
image072.jpg
单击确定。
image074.jpg
现在我们单击Show Invaild按钮,可以看到60ADC这一项已经被标记为有效了,我们要的就是这个效果。
image076.jpg
另一种修复的方式就是直接在重定向过的IAT项中填充上正确的API函数地址。
这里我们在460ADC这一项上填入GetVersion函数的地址,我的机器上该函数的入口地址为7C8114AB。
image078.jpg
现在我们来到IMP REC窗口中,单击Clear Imports按钮。然后再单击GetImports按钮,可以看到60ADC(RVA)这一项也被标记为了有效。
image080.jpg
image082.jpg
对于其他的重定向过的IAT项我们也可以按照上述方法来进行修复,接着就可以修复dump文件了。这种方法显得比较枯燥,纯属体力活。
(PS:大家想干这种体力活吗,不管你们想不想,反正我不想,嘿嘿)
IMP REC提示了一个功能可以协助我们完成这个手工修复工作。通过单击Save Tree按钮可以保存我们修复过的IAT项,当我们下次想继续修复其他项的时候可以通过单击Load Tree按钮导入我们之前保存的IAT信息,这样就可以继续之前没有完成的修复工作了。
image084.jpg
接下来的一种修复重定向的IAT项的方法就是借助于IMPREC的插件tELock1,我们将其放到IMPREC目录下的Plugin文件下。
下来我们来看看这个插件怎么用。
image086.jpg
将插件的DLL拷贝到IMP REC中Plugin文件夹中。
image088.jpg
现在我们重启IMP REC,输入OEP,RVA,SIZE等数据,单击Get Imports,接着单击ShowInvaild,在无效的项上面单击鼠标右键选择-Plugin Tracers-tElock1。这样该插件就会帮我们修复这些重定向的IAT项,我们可以看到日志窗口提示除了4项以外,其他重定向的IAT项都被修复了,这个插件不是很爽,帮我们完成大部分的重定向项的修复工作,剩下少数几个重定向过IAT项我们可以自己手工修复。
image090.jpg
这里IMP REC提示4项未修复的,大家可以按照前面介绍的方法进行手工修复,这种插件的修复方式有明显的局限性,只能针对于特定的壳。
IMP REC还自带有常规的Tracers,我们可以试试看其能不能修复这些重定向过的IAT项,大多数情况,通常它也可以替代我们完成手工修复任务。
image092.jpg
这里我们在第一个修复失败的项上面单击鼠标右键,我们可以看到3个等级,这里我们选择-Trace Leve1(Disasm),看看等级1能不能起作用。
image094.jpg
失败了,我们继续尝试Level2,Level3,我们会发现这两项也不起作用,IMP REC死掉了,看来这几个选项只能对比较简单的壳起作用。
接下来的这种修复重定向的方法叫做关键跳法,这种方法在很多脱壳教程中都有用到。
这种方法就是定位壳填充IAT的时机,看看何时填充正确IAT项,何时填充重定向过的IAT项。
举个例子:就拿GetVersion这一项来说吧,我们重启UnPackMe-tElock0.98。
此时我们还没有到达OEP处,460ADC中的值为3D830870,在壳的解密例程执行过程中会将重定向过的值9F06F7填充到460ADC这个内存单元中。
image096.jpg
image098.jpg
为了能够定位何时该IAT项被写入,我们可以对460ADC设置硬件写入断点,但是由于该壳会检测硬件断点,所以这里我们设置内存写入断点,让壳在此处写入重定向过的IAT值的时候断下来。
image100.jpg
运行起来,我们可以看到断在了这里。
image102.jpg
这里并不是我们要定位的点,因为我们按F8键执行这一行会发现重定向过IAT值并没有被写进来,我们继续运行。
我们多运行几次,断在了这里:
image104.jpg
这里也不是写入重定向过的IAT值,我们继续运行。
image106.jpg
我们按F8键执行这行指令,发现也不是保存重定向过的IAT值,继续运行。
image108.jpg
断在了这里,这里将写入一个无效的值,但是并不是我们要定位的重定向过的IAT值9F06F7。
image110.jpg
我们执行REP MOVS指令,该无效的值被写入到该IAT项中,我们继续运行。
image112.jpg
我们断在了这里,我们可以看到当前ECX寄存器的值正好等于重定向过的IAT值9F06F7。
image114.jpg
ECX = 9F06F7,将被保存到EAX = 460ADC指向的IAT中,这里就是我们要定位的地方。
image116.jpg
我们按下F8键,9F06F7就会被保存到460ADC中,这只是第一步,接下来我们需要定位关键跳转。
image118.jpg
我们往下跟几步,达到了46651A处JE指令处,我们看看寄存器窗口中EBX寄存器的值,当前EBX正好指向了GetVersion的函数名称字符串。
image120.jpg
继续往下我们可以看到会调用GetProcAddress获取GetVersion这个API函数的地址。
image122.jpg
我们可以在堆栈窗口中看到参数情况,按F8键执行这个CALL。
image124.jpg
我们可以看到此时EAX保存了GetVersion这个API函数的地址,我们继续往下跟。
image126.jpg
这里有一个条件跳转,这个条件跳转是成立的,我们不跟过去,直接单击鼠标右键选择-Follow。
image128.jpg
这里我们可以看到GetVersion的函数地址并不是被填充到IAT中,而是被写入到EDI指向的内存单元中,当前EDI为:
image130.jpg
保存了该API函数的地址以后,紧接着我们到了JMP指令处。
image132.jpg
这里通过这个JMP我们又将回到这个过程的开始处,这里是一个循环,我们单击鼠标右键选择-Follow。
image134.jpg
这里接下来又要将第二个重定向过的IAT值填充的下一个IAT项中,然后通过GetProcAddress获取对应的API函数地址,并将获取到的API函数地址保存到某处,接着又是第三个重定向过的IAT值,循环往复,直到所有IAT项都被处理完毕为止。
由于壳只是对一部分IAT项进行重定向,所以下面我们来看看壳对IAT项重定向以及不重定向流程的差异。
IAT是如何被重定向的
image136.jpg
image138.jpg
image140.jpg
image142.jpg
image144.jpg
image146.jpg
image148.jpg
这里是一个小循环,继续往下:
image150.jpg
image152.jpg
image154.jpg
image156.jpg
这里是调用GetProcAddress,接着就会到保存GetProcAddress获取到的API函数地址处。
image158.jpg
image160.jpg
以上就是跟踪一个IAT项被重定向的完成流程,其中有很多的条件跳转。现在我们跟到OEP处,定位到一个正确的IAT项,比较一下两者有什么差别。
这里我们选择460BAC这一项。重新启动程序。
image162.jpg
image164.jpg
对460BAC这4个字节设置内存写入断点,运行起来,看看壳何时会将正确的IAT项填充进来。
image166.jpg
断在了这里,正确的IAT值将被写入。
image168.jpg
我们可以看到此时EAX寄存器中可能包含的是一个API函数的入口地址,虽然这里OD没有提示该API函数的名称,但是我们可以Goto过去看一看,我们CTRL + G输入EAX。
image170.jpg
image172.jpg
我们到了这里,我们可以看到寄存器窗口中EAX显示处了该API函数的名称,嘿嘿。
image174.jpg
接下来的任务就是需要将IAT项被重定向的流程修改为正确IAT项的处理流程。
让所有IAT项走正常流程
我们依然从循环的起始位置开始跟。
image176.jpg
image178.jpg
这里跟IAT项重定向的流程是一致的。
image180.jpg
这里只是一个小跳转,我们继续跟。
image182.jpg
这个跳转不成立。
image184.jpg
这里跟之前IAT项被重定位的处理有明显区别,跳过的中间的大片代码。
image186.jpg
我们可以看到这里是一个长跳转,跳转与否取决于是IAT项是否被重定向,也就是说这里是决定是IAT项是否被重定向的关键跳,我们可以将这个条件跳转替换为JMP。
但是这个跳转在程序一开始的时候并不存在,我们重启程序。
image188.jpg
我们可以看到在程序刚开始的时候,这里都是一些垃圾指令,壳会随后的某个时间点写入实际的功能代码。
image190.jpg
我们转到数据窗口,由于硬件断点会被检测,INT3断点这里不能用,所以我们可以使用内存写入断点,我们对460818~460f28这片IAT区域设置内存写入断点。
image192.jpg
这里我们对所有的IAT项都设置上了内存写入断点,当第一个IAT项被写入的时候就会断下来。
image194.jpg
断在了这里,这里的STOS指令会执行多次,直到整个IAT都被填充完毕为止,此时关键跳已经存在了。
image196.jpg
这里我们可以看到关键跳已经生成了,我们将该关键跳转JE替换成JMP,接着清除之前设置的内存断点,接着跟踪到OEP处。
image198.jpg
这里有两种可能,一种就是壳有自校验,运行起来会失败。另一种就是运行很正常,这里我们顺利的跟踪到了OEP处。
image200.jpg
现在到了OEP处,我们再来看看IAT:
image202.jpg
我们可以看到所有的IAT项都是正常的,我们成功修复了IAT,现在我们可以进行dump了。
image204.jpg
image206.jpg
这里我们不勾选ReBuild Import,dump出来。
接着打开IMP REC,填入OEP,RVA,SIZE等数据,单击Get Imports。
image208.jpg
我们可以看到所有的项都是有效的,说明刚刚修改的关键跳起作用了,接着单击Fix dump修复刚刚的dump文件。
image210.jpg
修复过的dump文件被重命名为了dumped_.exe,我们运行一下看看效果。
image212.jpg
嘿嘿,完美运行。
不同壳关键跳的地方也不一样,但是我们细心对比正常IAT项与重定向过的IAT项的处理流程差异,总能找到一点蛛丝马迹,好了,本章就讨论到这里,下一章我们继续讨论别的壳。

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

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

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

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



评分

参与人数 15HB +17 THX +6 收起 理由
Jawon + 2
一路走来不容易 + 1
Soul1999 + 1
冷亦飞 + 1
小猪呼噜噜 + 2 + 1 [吾爱汇编论坛52HB.COM]-学破解防破解,知进攻懂防守!
阿枫 + 1
成丰羽 + 1 [吾爱汇编论坛52HB.COM]-感谢楼主热心分享,小小评分不成敬意!
jaunic + 2
EMT + 1 + 1
kll545012 + 1 [吾爱汇编论坛52HB.COM]-学破解防破解,知进攻懂防守!
消逝的过去 + 2 [吾爱汇编论坛52HB.COM]-软件反汇编逆向分析,软件安全必不可少!
ghostxu + 1 [吾爱汇编论坛52HB.COM]-学破解防破解,知进攻懂防守!
hnymsh + 2
lies + 1
wswwj + 1 + 1 [快捷评语] - 吃水不忘打井人,给个评分懂感恩!

查看全部评分

吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
easy 发表于 2015-7-23 01:37 | 显示全部楼层

需要这个教程,图文的难看懂....有类是视频吗,想砍一下
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
ycq1996 发表于 2017-10-7 09:08 | 显示全部楼层

还是视频教程看的明白,不知可有视频教程?
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
wswwj 发表于 2017-10-7 09:40 | 显示全部楼层
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
ghostxu 发表于 2022-1-17 01:00 | 显示全部楼层

大神,请收下我的膝盖
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
EMT 发表于 2022-1-17 16:09 | 显示全部楼层
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
xujinwen 发表于 2022-1-17 17:08 | 显示全部楼层

谢谢大佬!
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
越宝 发表于 2022-1-18 19:48 | 显示全部楼层

谢谢大佬!
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
king51999 发表于 2022-1-19 08:25 | 显示全部楼层

感谢分享~~
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!52HB.COM
越宝 发表于 2022-1-20 11:32 | 显示全部楼层

谢谢大佬分享
吾爱汇编论坛-学破解,防破解!知进攻,懂防守!逆向分析,软件安全!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

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