关于 IDA 6.8 的问题,以及为什么它会创建不必要的变量

逆向工程 C++
2021-06-25 16:59:53

最近我一直在学习做 RE。

我在 10 秒内编写了一个简单的程序,我打算在 IDA 中处理它。

#include <iostream>

int main(int argc, char* argv[])
{
    printf("Hello, world!\n");

    int i = 0;

    if (i == 0)
    {
        printf("i == 0\n");
    }
    else
    {
        printf("i > 0 OR i < 0\n");
    }

    while (i == 0)
    {
        printf("I'm a while loop\n");
        _sleep(510);
    }
}

如您所见,它是主要功能。但是当我进入 IDA 并点击 start 它不是那个功能(假设 start 是主要功能,对吗?)

但是,在单击功能窗口中的一些功能后,我遇到了它。这里是

int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
    {
      char v3; // ST04_1@1
      char v4; // [sp+0h] [bp-4h]@0
      char v5; // [sp+0h] [bp-4h]@1

      printf("Hello, world!\n", v4);
      printf("i == 0\n", v3);
      while ( 1 )
      {
        printf("I'm a while loop\n", v5);
        sleep(0x1FEu);
      }
    }

我已经扭转了大部分。( printf 最初是 sub_50505 或类似的东西)。

然而,出于某种奇怪的原因,它创建了不必要的变量,我很好奇它为什么这样做。它应该只创建一个,即 i。

另外,为什么是 while (1) { ... }

不应该在 while (i == 0) { ... } 之前吗?

我对所有这些问题很好奇。谢谢!对不起,如果他们很傻。我是 RE 的新手!

1个回答

欢迎来到 RE。

它创建了不必要的变量,我很好奇它为什么这样做

问题出在 printf 函数上。

通常,当 IDA 遇到函数调用时,它会查找函数签名以了解在哪些位置传递了多少参数。

在 printf 函数的情况下,它至少是一个参数。为了知道传递了多少参数,需要评估格式字符串。然而,IDA 并没有而是采用一些启发式方法来确定堆栈的哪一部分“属于”这个函数调用。

由于主函数检索参数

(int argc, const char **argv, const char **envp)

调用时,IDA 会注意到堆栈中包含某些内容。

另外,为什么是 while (1) { ... }

很可能您的编译器优化了代码,因为他注意到 i 从未被分配过除 0 之外的任何其他内容。它还删除了 else 子句中的“死代码”。如果您使用 gcc,请尝试关闭优化(例如 -O0)