返回介绍

第四十一章 - 神马是 AntiDump

发布于 2025-01-31 21:07:00 字数 11239 浏览 0 评论 0 收藏 0

本章我们继续脱 PELock,修复其 IAT。

这里我们仍然采用最后一次异常法定位到 OEP 处。

好了,现在我们到达了假的 OEP 处,接着我们单击鼠标右键选择 Search for-All intermodular calls,查看 API 函数的调用列表。

这里我们随便选择一个,选中并双击之。

这里我们可以看到该 API 函数的入口地址位于 460D38 这个内存单元中的,也就是说 460D38 为 IAT 的其中一项。好,在数据窗口中定位到该地址。

我们可以看到这部分 IAT 项是正确的,我们往上看,定位 IAT 的起始位置。

这里很明显 460818 为 IAT 的起始位置,因为上面的项,查看参考引用的话,会发现没有参考引用处,并且也不属于系统 DLL 的区段。

这里很幸运,IAT 项都是正确的,没有被重定向,所以我们并不需要修复重定向,接下来,我们来定位 IAT 的结束位置。

这里灰色的部分没有问题,但是 460F24 这一项就是比较可疑了,这一项没有参考引用。灰色的这部分是属于 ole32.dll 的代码段的。

这里我们选中属于该 DLL 的某些项,会发现也没有参考引用。

我们回到 OEP 处,可以看到该 JMP 指令将要跳转的一个地址为 Axxxxx(在我的机器上为这种形式,在其他的机器上可能会不一样) 的形式,该地址不属于 exe 所在的区段,我们来看一看区段列表。

我们知道原始程序在 OEP 附近是太可能跳转到 exe 之外的区段的,那么 Axxxxx 所在的这个区段很可能是通过 VirtualAlloc 或者类似的函数创建的,所以这个区段很可能是壳创建的。

在这个区段中壳可能会将 IAT 的中某些值取出来加以变换就转化为 API 函数的调用了。下面我们来对 OD 的调试选项加以配置。

以上就是壳创建的一个区段,我们来查看一下 460F24 这一项的参考引用。

依然是什么也没有,别灰心。我们继续看下面一个区段。

也看不出什么端倪。

我们回头再看看 A80000 这个区段,我们注意到 A8003D 这处 CALL [460930],其对应的机器码为 FF15 30094600,也就是说如果 CALL [460F24]的话,其对应的机器码应该是 FF15 240F4600,也就是说可以通过这种方式来调用 API。

好了,下面我们搜索一下 FF15 240F4600 这串二进制串。

单击工具栏上面的 M 按钮打开区段列表窗口,选中第一个区段,单击鼠标右键选择-Search。

在 16 进制编辑框中写入 FF15240F4600 字节序列,单击 OK,会发现,什么也没找到,说明有可能不是通过间接 CALL,我们去掉前面的 FF15,再次搜索。

正好定位到了壳创建的这个区段,我们其反汇编代码是什么。

这里我们可以看到是通过 JMP 来调用的,而并非 CALL,所以机器码为 FF25,并非 FF15。也就是说 460F24 也是 IAT 中的一项。

所以说 IAT 的结束位置为 460F28。

IAT 的长度 = 结束位置 - 起始位置 = 460F28 - 460818 = 710

因此:

OEP 的 RVA = 271B0

IAT 起始地址的 RVA = 60818

现在我们可以看到 IAT 项都是正确的了,我们回到假的 OEP 处,将 stolen bytes 填充上。

stolen bytes 是 55 8B EC 6A FF 68 60 0E 45 00 68 C8 92 42 00 64 A1 00 00 00 00 50 64 89 25 00 00 00 00 83 C4 A8 53 56 57 89 65 E8 。

我们在数据窗口中定位到 4271B0 处,按照第 39 章介绍的方式将 stolen bytes 填充好。

现在我们来 dump,将 OEP 指定为 4271B0。

这里我们把 OEP 修正了。去掉 Rebuild Import 的对勾,我们不使用 OllyDump 的重建输入表的功能。

将 dump 出来的文件命名为 dumppeado pelock,现在我们来修复 IAT,打开 IMP REC,将 OEP 修正。

将 IAT 的信息填好,接着单击 Get Imports 按钮。

我们可以看到提示有无效的项,但是并没有经过重定向,只是每个 DLL 的 IAT 项原本应该是用零间隔开的,这里壳使用垃圾数据将零覆盖掉了。我们来看一看。

这里应该为零,用 IMP REC 修复很容易,我们单击 Show Invalid 即可。

这里我们可以看到 advapi32.dll 与 comctl32.dll 的项之间被垃圾数据隔开了,选中这些无效的项,单击鼠标右键选择 Cut thunk(s),剪切掉这些无效的项。

我们可以看到剪切掉这些无效的项后,显示的项都标识为有效的了。

接着我们单击 Fix Dump 按钮来修复刚刚 dump 出来的文件。

修复后的文件被重命名为了 dumpeado pelock_.exe。如果我们运行它的话,会提示错误。

下面我们需要用到 LordPe 来修复。

此时我们处在正确的入口点处,我们来看看 IAT。

我们可以看到这里 IMP REC 已经把 IAT 都修复了,各个 DLL 中的 IAT 项中间的间隔也由垃圾数据替换为了零。但是为什么运行起来还报错呢?

这就是我们接下来要讨论的一个话题,在修复了 IAT,以及 stolen bytes 以后,很多壳还会有 AntiDump。

有很多类型的 AntiDump,简单一点的 AntiDump 会校验映像的大小或者区段的个数,我们这个例子的 AntiDump 是壳创建了几个区段,在运行时会对原程序做一些处理,如果 dump 出来的程序不包含这些区段,那么程序就不能正常运行,我们来到入口点处。

当程序运行到 4271D6 处的 JMP 指令处的时候就会报错。

如果我们按 F7 键,会跳转到一个不存在的区段。

我们来看一看未脱壳的程序,会发现将跳转到壳运行时创建的一个区段中。

单击鼠标右键选择 Follow,就能够跟随到壳创建的区段中。

这里我们可以看到是调用了一个 API 函数,接着返回到主程序代码段,有很多方法可以解决这个问题,最简单的方法就是给 dump 出来的文件添加一个相同的区段,我们来看看。

首先添加报错的这个区段,如果添加了以后还报错,再次添加其他缺失的区段。

这里我们需要用到 PUPE 这款工具来 dump 缺失的区段。

选中 Pelock 所在的进程,单击鼠标右键选择 BOX OF TOOLS。

单击 Mapa(即 MAP) 按钮打开区段列表窗口,定位到报错的区段。

我们还记得报错的区段的起始地址为 A80000,我们一起来看一看。

我们单击 Volcar(PS:西班牙语译为 DUMP) 按钮,将其命名为 seccion(PS:西班牙语译为 section)。

现在我们打开 PEditor,将该区段添加到 dump 文件中。

通过 PEditor 打开 dump 出来的文件。

单击 sections 按钮。

这里我们可以看到 IMP REC 在为了修复 IAT 也给该程序添加了一个区段,名称为.mackt,我们将缺失的区段添加到最后。

在.mackt 这个区段上面单击鼠标右键选择 copy a section from HD to EOF。接着我们将新添加区段的起始地址修改为 A80000。

我们来计算一下该新区段的相对虚拟地址 = A80000 - 400000 = 680000。

也就是说新区段的起始地址 RVA = 680000。

下面我们通过 LordPe 来重建该 PE 就大功告成了。

正常运行,我们用 OllyDbg 打开它。

查看一下区段列表。

我们可以看到起始地址为 A80000 新添加的区段。

我们定位到 4271D6 地址处 JMP 指令,单击鼠标右键选择 Follow。

跳转到了缺失的区段中。

我们来对比一下未脱壳和脱完壳并修复后的区段。

未脱壳的区段:

脱完壳修复后的区段:

本章就到这里。(PS:后面一点总结部分,作者讲的有误,这里就略去了)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文