首页 > 解决方案 > 两个具有完全相同汇编代码的编译二进制文件在破解二进制文件时表现不同?或者我可能错过了什么?

问题描述

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

我正在使用 ghidra 反编译那些二进制文件然后我只需使用选项File->Export Program (O)将这些文件导出为格式化 c/c++ 程序

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

然后我观察到一些函数只是未能反编译显示以下错误,但我只是使用Windows->Functions在 Ghidra 中搜索这些函数,然后我再次一一反编译这些函数,然后将这些函数放入整个 .c 文件中的适当位置。

/*
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->Export Program (O)导出二进制文件

然后我通过用我的破解文件替换 ogrinal 文件来尝试我的破解二进制文件版本,它只是不起作用,但是当我尝试破解文件时,它就像一个魅力。

这个补丁看起来像是一个正确的解决方案,因为这是一个通过观察返回值来决定软件是否注册天气的函数,我们只是让它成为 always return 1FUN_0043a620我们可以在反编译的 .c 文件中搜索该函数的用途,
例如

 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."
                         );

这正是我在查看破解二进制文件之前发现的,我尝试了它,但它没有奏效,然后我发现这个破解文件试图了解工作破解二进制文件与原始二进制文件之间的差异。

我想知道为什么我的破解版无法工作,即使我从工作破解文件中复制了精确更改的汇编指令?

标签: diffreverse-engineeringpatchcrackingghidra

解决方案


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

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

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

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


推荐阅读