提问者:小点点

两个具有完全相同汇编代码的编译二进制文件在破解二进制文件时表现不同?或者可能是我遗漏了什么?


我有两个exe文件一个是原始文件,另一个是软件矢量魔法破解exe文件,破解文件vmbe.zip两个文件的大小完全相同。

我正在使用ghidra反编译这些二进制文件然后我只是通过使用选项File-将这些文件导出为格式化c/c程序

然后我将这些文件打开到Visual Studio并应用Diff扩展来查找这些文件之间的差异,我可以通过按ALT F5导航到差异

然后我观察到一些函数只是未能反编译显示以下错误,但我只是使用Windows在Ghidra中搜索这些函数-

/*
Unable to decompile 'FUN_004475d0'
Cause: Exception while decompiling 004475d0: process: timeout
*/

现在我有两个. c文件一个是原始exe文件的反编译版本,另一个是破解的exe文件,修复较少的变量名称后,我们可以很容易地发现,这两个文件之间只有一个区别在函数的末尾FUN_0043a620

原始exe的反编译. c文件

    _bVar2 = uVar3 & 0xffffff00 | (uint)bVar2;
  }
  *in_FS_OFFSET = local_c;
  return _bVar2;
}

破解了exe的反编译. c文件

    _bVar2 = uVar3 & 0xffffff00 | 1;
  }
  *in_FS_OFFSET = local_c;
  return _bVar2;
}


在Ghidra中,我们可以看到只有一条汇编指令在内存位置更改0043a687

原始文件

        0043a687 b3  01           MOV        BL,AL

破解文件

        0043a687 b3  01           MOV        BL,0x1

现在我在原始exe文件中更改了该指令,并从选项File-导出二进制文件

然后我尝试我的破解二进制文件版本,只需用我的破解文件替换ogrine文件,它就不起作用,但当我尝试破解文件时,它就像一个魅力一样工作。

这个补丁看起来是一个正确的解决方案,因为这是通过观察返回值来决定软件注册与否的函数,我们只是让它始终返回1。我们可以在分解的. c文件
中搜索该函数FUN_0043a620的用法

 if (local_65 != 0) {
    uVar5 = FUN_0043a620();
    if ((char)uVar5 != '\0') {
      pQVar7 = (QString *)FUN_0043a580((char *)&local_54,"Thank you for activating!");
      local_4._0_1_ = 5;
      pQVar8 = (QString *)FUN_0043a580((char *)&param_1,"Activation succeeded");

而且

 uVar4 = FUN_0043a620();
  if ((char)uVar4 == '\0') {
    pQVar5 = (QString *)
             FUN_0044b910((char *)&local_14,

                          "Not activated. Click the \'Activate\' button on the first page to enable saving."
                         );

这正是我在查看破解二进制文件之前发现的,我尝试过,但它不起作用,然后我发现这个破解文件试图理解工作破解二进制文件与原始二进制文件之间的差异。


共1个答案

匿名用户

使用十六进制编辑器(FlexHex,BeyondCompare,…)并寻找两个文件之间的差异,也许还有其他不是代码差异的差异,例如-全局数据的一些变化。

为了理解其他字节是什么,您可以分析二进制文件

>

  • 静态:在GhidraIDA中打开它,并查找此数据的x-refs以及它使用的位置。很有可能它与您在代码中看到的其他更改有关。

    动态:尝试在访问此位置时设置硬件断点。