第四十三章-ACProtect V1.09(编写脚本修复IAT) 上一章节,我们介绍了如何定位stolen bytes,本章我们的任务是修复IAT,再次用OD加载UnPackMe_ACProtect1.09,我们可以通过并执行HBP.TXT脚本到达假的OEP处。 现在我们在壳的入口处,现在我们来利用上一章节编写的脚本定位到OEP处,首先,需要需要给KiUserExceptionDispatcher入口处以及其下方的ZwContinue调用处分别设置断点。 现在我们到了假的OEP处,大家可以修改一下这个脚本让其自动给KiUserExceptionDispatcher入口以及ZwContinue调用处设置断点,并且让其支持输入需要设置硬件断点的地址,但这里我们暂时没有必须修改,这个脚本目前来说已经够用了。 下面我们来随便定位一个API函数的调用处,单击鼠标右键选择Search for - All intermodular calls选项搜索。 我们可以看到很多API函数的调用,其中有些IAT项是正常的,显示出了函数名称,但是大部分的IAT项都是经过重定位的,并没有显示函数名称,我们随便选中一个重定向的IAT项,双击鼠标左键。 这里我们可以看到CALL的是460E80内存单元中对应的IAT项,我们在数据窗口中定位到该项。 这里我们可以看到很多经过重定向的项,这些项直接就位于壳的区段中,我们来看看区段列表窗口。 大家应该还记得该壳的入口点也是位于这个区段的,壳的入口点为46B000,也就是说该壳并没有重新创建一个区段用来处理重定向的API函数。 接下来任务就需要定位修复IAT项的关键跳转(magical jump)了。 下面我们就来通过460ADC这一项来定位关键跳。 首先我们将定位OEP的脚本备份一下。 我们将备份过的脚本重命名为OEP.txt,接下来我们通过修改HBP.txt脚本来定位修复IAT的关键跳转。 这里我们将脚本修改为对460ADC这个重定向的IAT项设置硬件写入断点,也就是说断点类型修改为W。 现在我们清除之前设置的硬件断点,重新启动OD。 执行上面的脚本,不一会儿弹出了是否继续执行脚本的消息框。 我们可以看到这里对460ADC写入的时候触发了硬件写入断点,我们知道硬件断点是断在下一条指令处,我们来看看前一条指令是什么。 这里我们可以看到是这条指令将对460ADC地址进行写入,我们来看看EAX的值是多少。 这里EAX的值为46B492。 这里我们在反汇编窗口中定位到46B492这个地址,看看该壳做什么处理。 这里我们看到这个重定向的处理非常简单,首先将常量5BF11A9压入堆栈,接着将该值与793E0502进行异或,接着就RET返回。 异或得到的结果就是API函数的入口地址,我们一起来计算一下。 5BF11A9 XOR 793E0502 = 7C8114AB 计算出来的这个地址就是API函数的入口地址,我们返回到OD中看看。 我们将堆栈窗口往上拉一点就能看到正确的API函数地址了,下面我们就来看看是不是所有的重定向的IAT项都是这样处理的,先停止脚本。 我们对部分重定向的IAT项设置内存写入断点,看看会发生什么。 我们运行起来,当下一个重定向的IAT项被写入的时候断了下来。 我们定位到重定向的部分,执行异或操作以后可以看到得到的API函数是MulDiv,这么看来修复是有可能的,我们可以看到正常的API地址被保存在了堆栈中,确切点来说是[ESP - 0C]中。 这里我们可以看到往下都是需要重定向的,到了460BA8,就是正常的IAT项了。 所以我们对460BA8这一项设置内存写入断点。 运行起来,到了这里。 我们可以看到对于正常的IAT项,[EBP - 0C]处并不会保存正确的API函数入口地址,所以说有点遗憾,不然我们可以使用一个简单的脚本轻松的修复IAT。 我们该怎么做呢?我们需要对写入IAT项的指令设置硬件执行断点,当脚本执行到这里的时候,我们判断EAX的值是正常的还是重定向的,如果是重定向的,那么我们就将[ESP + 0C]的值填充到IAT对应的条目中,如果是正常的IAT项的话,我们就不予处理,我们来看看该脚本如何编写。 以上就是完整的脚本,这里我是在下一行的4743d5处设置的硬件执行断点,因为硬件执行断点当将要执行该条指令的时候就断下来,不同于硬件写入或者访问断点。 这个脚本是基于HBP.txt改写的,首先对IAT项重定向的下一条指令4743d5处设置硬件执行断点。 这里是ToProcess这个分支,当脚本检测到中断异常,将EIP与4743d5进行比较,如果相等就跳转到ToRepair分支中。 ToRepair分支,我们首先判断EAX是否为正常,如果被重定向到壳所在区段的话,那么地址是小于500000的,反之,如果EAX的值大于500000,就表示该IAT项是正常的,我们就无须进行修复,回到开始处继续捕获下一次中断。如果EAX是重定向的值的话,我们就使用变量aux2来保存正确的API函数地址,正确的API函数地址保存在[ESP - 0C]中。我们将其写入到EDI指向的IAT项中即可。 下面我们就来执行一下该脚本,试试效果。 重启程序,将之前设置的硬件断点全部清空,接着对KiUserExceptionDispatcher的入口处以及ZwContinue的调用处分别设置断点,然后运行脚本。 程序运行起来了,我们来看下IAT。 嘿嘿,我们可以看到IAT项都被修复了。 我们将脚本重命名为IAT.txt。 下面我们需要定位IAT的起始地址以及IAT的大小。 这里我们可以看到IAT的起始地址为460818,结束于460F28。 OEP(RVA) = 271b5 IAT的起始地址(RVA) = 60818 IAT的大小 = 710 这里我们可以用的假的OEP,后面我们可以手工修改。 下一章节,我们来解决AntiDump,敬请关注。
本系列文章汉化版转载看雪论坛
感谢原作者:RicardoNarvaja(西班牙人)
感谢热心翻译的朋友: 1~3章译者:BGCoder 4~58章译者:安于此生
全集配套程序下载地址:
|