如何找到代码在哪里循环——无限循环?

逆向工程 拆卸 调试器
2021-07-02 13:05:04

有什么方法或技术可以确定程序中的哪些代码循环?就像我的应用程序进入无限循环一样,我想确切地知道它在哪里循环?

1个回答

在这里回答以防其他人发现这个问题并需要更详细的答案。

前面有几个假设。OP 说“应用程序”,所以我假设操作系统 1) 具有内核/用户模式,2) 不是封闭系统(即不是设备或设备),3)有一些“进程”概念,以及 4 ) 有一个调试器,可让您调试特定进程(现有进程或调试器启动的进程)。想想 Windows,Linux。

为简单起见,我们假设应用程序是单线程的。闯入调试器后,处理器将在无限循环中执行(有一些警告)。

(如果应用程序是多线程的,那么您需要切换到当前正在运行的每个线程的上下文,并确定该线程是否正在执行无限循环。虽然不太可能,但应用程序可能同时具有多个无限循环。它也在应用程序未创建的线程中的回调函数中可能存在无限循环。)

在许多情况下,无限循环只是一些指令(为了讨论起见,说 < 50)。

使用一个小的无限循环,您可以在循环中单步执行(跳过函数调用)并表征整个循环。如果循环超过 8 条指令,如果您在一张纸上写下每个具有单个入口点和单个出口的程序集块(所谓的基本块)并在基本块之间绘制箭头,可能会有所帮助代表所有跳跃(和返回)。任何指向在您单步执行循环时未执行的代码的箭头都是潜在的循环出口。

如果没有这样的箭头,那么代码就被写成一个无限循环——这个循环可能是故意的,或者编码器只是犯了一个编码错误。如果有箭头,那么它们(通常)之前会出现某种测试/比较指令。您需要调查为什么这些测试/比较指令永远不会导致退出循环。

如果您有一个“大”无限循环,则单步执行每条指令变得不切实际(或至少令人厌烦)。要找到循环的原因,您需要充分了解所涉及的代码,以了解无限循环试图完成什么以及为什么不满足循环退出条件。在这里,您将使用其他 RE 技术来理解构成循环的代码。一旦你有了这样的理解,你就可以专注于理解为什么不满足循环退出条件。