手动拆包时为什么要在 OEP 精确转储?

逆向工程 开箱 倾倒 进口改造 操作
2021-06-19 01:26:34

当程序计数器处于 OEP 时,转储进程的确切原因是什么?我还没有找到合适的答案。

这个链接说:

为了识别 IAT 结构,Import Reconstructor 需要知道我们的应用程序的 OEP(解压后的代码)。

这给我留下了以下问题:

  1. 但是,了解 OEP 与 IAT 有何关系?
  2. 当应用程序在内存中解包时,我们不能通过遍历 PE 头并获取 IT 的地址,然后获取 IAT 的地址来获取指向 IAT 的指针吗?
  3. 为什么我们不在 OEP 上转储应用程序,而是在导致 OEP 的jmp 上还是 OEP 后的一对二指令?
2个回答

但是,了解 OEP 与 IAT 有何关系?

OEP 与 IAT 无关,但被导入重建工具用于查找封隔器创建的 IAT 类结构的位置。

当应用程序在内存中解包时,我们不能通过遍历 PE 头来获取指向 IAT 的指针吗?

这正是需要导入重构的原因。因为恶意软件以某种方式故意破坏 IAT,只保留一小部分强制性功能,将解析大部分 API 的工作作为解包代码的一部分。因此导入重建需要我们通过其他方式找到IAT(因为PE定义的IAT是不完整的/伪造的)。

为什么我们不在 OEP 上转储应用程序,而是在导致 OEP 的 jmp 上说?还是 OEP 后的一对二指令?

转储时,重要的是已执行与解扰打包代码相关的所有代码。否则,OEP 可能不是有效的可执行代码。除此之外(以及与导入重建相关的问题)转储并仅将 PE 的入口点调整为 OEP 完全没问题。大多数转储工具都允许这样做。


除了回答您的具体问题外,以下是有关 IAT 操作的加壳程序类型以及在转储的 PE 中获得功能性 IAT 所需的条件:

  1. 当加壳器不改变原始导入表时,导入重建是不必要的。大多数 PE 转储程序会在原始导入表有效时复制它,或者将其与 PE 一起转储。

  2. 一些加壳器携带另一个最初隐藏的 PE,并且只对其整体进行解密/解扰。这些包装工也将完好无损地携带 IAT,大多数自卸车将自动获得 IAT。

  3. 一些打包者会创建他们自己的替代 IAT 并实现他们自己版本的 API 加载/解析。对于这些加壳程序,导入重建实用程序将需要定位该替代(或者,我们应该说是真实的吗?)IAT 并从头开始在重建的 PE 中创建一个新的 IAT(基于原始 IAT 实际指向的那些 API)。然后,导入重建将查找“IAT 查找”偏移范围,并确保它们在加载 PE 时位于同一位置。因此,OEP 会扫描使用偏移表的呼叫,这些偏移表可能被怀疑为此类替代 IAT。

  4. 有些包装器不会创建单个 IAT,而是创建许多小的 IAT 表,这样您就不再称它们为“表”。在这些情况下,导入重建工具必须遇到足够多的小表并分别重建它们。在这些情况下,更重要的是不要让任何代码段仍然打包,因为仅由这些代码段使用的 API 将不会被重构。

  5. 另一种类型的加壳程序通过删除导入表的概念,而是在每次进行 API 调用时解析请求的 API,从而使静态反汇编的 API 解析变得更加困难(尽管不会阻止转储 PE 的执行)。这通常是通过为任何 API 分配一个无法轻易识别的密钥/哈希来完成的,并在每次调用时遍历 DLL 和导出表,为 API 生成相同的密钥/哈希,直到找到正确的密钥。这通常意味着不需要导入重构来执行和调试转储的 PE,但是人类逆向工程师将难以理解正在调用哪些 API。

我认为这里有些混乱。

但是,了解 OEP 与 IAT 有何关系?

它没有(对于良性软件)。但是,您链接的文章分析了打包的可执行文件。通常,恶意软件不会使用官方 IAT,而是通过在运行时创建自己的导入来隐藏其导入。工具应该可以帮助您重建某种“正常”的 IAT。

当应用程序在内存中解包时,我们不能通过遍历 PE 头并获取 IT 的地址,然后获取 IAT 的地址来获取指向 IAT 的指针吗?

为什么解压后的有效载荷要有自己的 PE 标头?我见过很多恶意软件,但这种情况很少见。

为什么我们不在 OEP 上转储应用程序,而是在导致 OEP 的 jmp 上说?还是 OEP 后的一对二指令?

以确保您获得正常的有效载荷。分析人员通常会尝试为其重新创建 PE 文件(通过重建 IAT、建立标题等)以使分析更轻松。

在本文中,他们尝试“修复”二进制文件