使用 OllyDbg 进行逆向工程





5.00/5 (14投票s)
本文的目的是说明,如何通过使用 OllyDbg 工具来破解一个可执行文件,而无需查看其源代码。
摘要
本文的目的是说明,如何通过使用 OllyDbg 工具来破解一个可执行文件,而无需查看其源代码。尽管市面上有许多工具可以达到相同的目的,但 OllyDbg 之美在于它操作简单且免费提供。我们之前已经对 .NET 应用程序进行了大量的逆向分析。这一次,我们面对的是一个起源完全未知的应用程序。简单来说,我们的意思是,我们实际上并没有获得原始源代码。我们只有某个应用程序的可执行版本,而这在逆向工程的上下文中是一项艰巨的任务。
必备条件
安全研究人员必须对汇编编程语言有深入的了解。预计他们的机器将配置以下工具;
- OllyDbg
- 汇编编程知识
- CFF explorer
修补原生二进制文件
在不提供源代码的情况下,仍然可以修补相应的软件二进制文件,以去除供应商施加的各种安全限制,并修复源代码中的固有错误。软件中一种常见的限制类型是复制保护,这通常由软件供应商强制执行,以测试软件复制保护方案的稳健性。通常在复制保护中,用户在使用产品之前必须先注册。供应商规定了测试版软件的时间限制,以防止许可证滥用,并允许产品仅在功能受限模式下运行,直到用户注册。
可执行软件
下面的示例展示了一种绕过或删除复制保护方案的方法,以便在不延长试用期或不购买完整版本的情况下使用产品。复制保护机制通常涉及一个过程,软件会检查它是否应该运行,如果应该运行,则应暴露哪些功能。
一种在试用版或测试版软件中常见的复制保护方式是,允许程序运行直到某个特定日期。为了解释逆向工程,我们从互联网上下载了一个试用版软件,该软件的有效期为 30 天。正如你所见,以下试用版软件应用程序已过期,无法进一步运行,并在我们尝试执行它时显示错误消息。
我们不知道该软件是用什么编程语言或在哪个平台开发的。因此,第一个任务是确定其来源。我们可以使用 CFF explorer,它显示了一些重要信息,例如该软件是使用 VC++ 语言开发的,如下所示。
因此,我们可以轻松得出结论,这是一个原生可执行文件,它不是在 CLR 下执行的。我们不能使用 ILDASM 或 Reflector 来分析它的操作码。这次,我们必须选择另一种方法来破解原生可执行文件。
使用 OllyDbg 进行反汇编
当我们尝试加载 SoftwareExpiration.exe 文件时,它将拒绝运行,因为当前日期已超过授权试用版到期的日期。我们如何在使用此软件而不考虑试用期到期的情况下使用它?以下部分说明了在删除复制保护限制方面的步骤,如下所示:
路线图
- 加载过期程序以了解后台发生了什么。
- 在 OllyDbg 中调试此程序。
- 向后跟踪代码以识别代码路径。
- 修改二进制文件,使所有代码路径都能成功执行,并且不再命中试用期到期代码路径。
- 测试修改。
然而,这类任务也可以通过强大的工具 IDA Pro 来完成,但它是商业化的,并且不免费提供。OllyDbg 的功能不如 IDA Pro 强大,但在某些情况下很有用。首先,请从其官方网站下载 OllyDbg,并在您的机器上正确配置它。它看起来如下所示;
现在,从文件 à 打开菜单在 OllyDbg IDE 中打开 SoftwareExpiration.exe 程序,它将反编译该二进制文件。不要害怕那些奇怪的汇编代码,因为所有的修改都是在原生汇编代码中进行的。
这里,红框显示了程序的入口点指令,称为 00401204。CPU 主线程窗口以自上而下的方式显示执行的汇编指令形式的软件代码。这就是为什么我们前面说过,在对原生可执行文件进行逆向时,汇编编程知识是必不可少的。
不幸的是,我们没有实际的源代码,那么我们如何检查汇编代码呢?这里的错误消息“对不起,此试用软件已过期”可能有助于我们解决这个问题,因为通过这条错误消息,我们可以识别导致此消息出现的实际代码路径。
在错误对话框仍然显示的情况下,按 F9 或从调试菜单开始调试。现在,您可以找到时间限制代码。接下来按 F12 暂停代码执行,以便我们找到导致错误消息显示的导致代码。
好的。现在按 Alt+ K 查看调用堆栈。在这里,您可以轻松发现试用错误文本是 MessageBoxA 的参数,如下所示;
选择调用堆栈底部附近的 USER32.MessageBoxA,右键单击并选择显示调用,如下所示;
它显示了选择 MessageBoxA 的汇编调用的起始点。请注意,某些代码行旁边有一个大于符号 (>),表示另一行代码跳转到该位置。直接在 MessageBoxA 调用(右侧红色部分)之前,四个参数被推送到堆栈上。这里 PUSH 10 指令包含由另一行代码引用的 > 符号。
选择位于 004011C0 地址的 PUSH 10 指令,引用所选行的代码行将显示在 CPU 窗口顶部窗格下方的文本区域中,如下所示;
在上面的图中选择文本区域代码,然后右键单击以打开快捷菜单。它允许您轻松导航到引用所选行的代码,如下所示;
到目前为止,我们已经识别了负责生成错误消息的实际代码行。现在是时候对二进制代码进行一些修改了。前图中的上下文菜单显示,00401055 和 00401063 都包含跳转到用于消息框的 PUSH 10 的 JA(跳转到上方)。
因此,首先从上下文菜单中选择 Go to JA 00401055。现在您应该位于 0x00401055 地址的代码。您的最终目标是阻止程序命中错误代码路径。这可以通过将 JA 指令更改为 NOP(无操作)来实现,它实际上什么也不做。右键单击 CPU 窗口中的 0x00401055 指令,然后选择二进制,然后单击 Fill with NOPs ,如下所示;
此操作将 0x00401055 的所有相应指令填充为 NOPs,如下所示。
按连字符 (~) 返回到 PUSH 10,然后按照以下方式对 0x00401063 指令重复之前的过程;
现在,通过右键单击 CPU 窗口来保存修改。单击 Copy to Executable ,然后单击 All Modifications 。然后按下一个对话框中的 Copy all 按钮,如下所示;
在单击 Copy all 按钮后,将出现一个名为 SoftwareExpiration.exe 的新窗口。在这里,右键单击此窗口并选择 Save File ,如下所示。
最后,以新名称保存修改后的或已修补的二进制文件。现在加载修改后的程序,您可以看到没有显示任何过期错误消息。我们已成功击败了过期试用期限制。
最后说明
本文展示了一种使用 OllyDbg 来挑战复制保护措施强度的方法,并识别了如何使您的软件更安全地防止未经授权的使用。通过尝试破解您应用程序的复制保护,我们可以学到很多关于保护机制的稳健性。在产品公开上市之前进行这种测试,我们可以修改代码,使其在发布前能够更复杂地绕过复制保护。