奇怪的 Ghidra 反编译器输出,用于简单的破解我

逆向工程 吉德拉
2021-06-18 14:58:57

这是针对crackme问题的Ghidra反编译器输出。具体来说,这一个
代码:

undefined8 entry(undefined8 param_1,char *param_2)
{
  int iVar1;
  size_t sVar2;
  char *pcVar3;
  char *pcVar4;
  char local_118 [9];
  char local_10f;
  long local_10;

  local_10 = *(long *)___stdinp;
  _strcspn("Enter the password...\n",param_2);
  _printf(local_118,0x100,*(undefined8 *)_fgets);
  pcVar3 = "\n";
  sVar2 = _strlen(local_118);
  pcVar4 = local_118;
  local_118[sVar2] = '\0';
  iVar1 = dyld_stub_binder();
  if (iVar1 == 10) {
    if (local_118[0] == local_10f) {
      _strcspn("Correct!\nthe password is: %s\n",local_118);
    }
    else {
      _wrong_password(pcVar4,pcVar3);
    }
  }
  else {
    _wrong_password(pcVar4,pcVar3);
  }
  if (*(long *)___stdinp == local_10) {
    return 0;
  }

我在理解输出时遇到了一些麻烦。

  1. printf 和 strcspn 函数似乎被切换了?
  2. local_10f变量从未初始化,但仍用于与密码进行比较。
  3. 我从阅读解决方案中知道,只要首尾字符相同,并且长度为10,那么密码就可以工作。“dyld_stub_binder”如何检查长度?在哪里比较第一个和最后一个字符?

谢谢你的帮助。

1个回答

好像你的Ghidra反编译出错了。您使用的是最新版本Ghidra吗?

我在最新版本中得到的输出是:

undefined8 entry(void)

{
  size_t sVar1;
  char local_118 [9];
  char local_10f;
  long local_10;

  local_10 = *(long *)___stack_chk_guard;
  _printf("Enter the password...\n");
  _fgets(local_118,0x100,*(FILE **)___stdinp);
  sVar1 = _strcspn(local_118,"\n");
  local_118[sVar1] = '\0';
  sVar1 = _strlen(local_118);
  if ((int)sVar1 == 10) {
    if (local_118[0] == local_10f) {
      _printf("Correct!\nthe password is: %s\n",local_118);
    }
    else {
      _wrong_password();
    }
  }
  else {
    _wrong_password();
  }
  if (*(long *)___stack_chk_guard == local_10) {
    return 0;
  }
                    /* WARNING: Subroutine does not return */
  ___stack_chk_fail();
}

这更有意义。我猜你的Ghidra版本在解析plt/imports 时有一些问题升级到最新版本并再次检查。

至于你的第二个问题:当你不理解反编译的时候,你应该总是去反汇编。

   100000e42        MOVSX      EAX,byte ptr [RBP + local_118]

   100000e49        MOVSX      ECX,byte ptr [RBP + local_10f]

   100000e50        CMP        EAX,ECX

您可以看到堆栈中的两个字节之间存在竞争。

在这种情况下RBP + local_118是指向用户字符串堆栈位置的指针。 0x118 - 0x10f = 9=> 您正在查看最后一个字符(字符串的索引 9 是第 10 个字符)。所以比较是在第一个和最后一个字符之间。