使用具有不同优化的 gcc 时出现奇怪的反编译

Posted

技术标签:

【中文标题】使用具有不同优化的 gcc 时出现奇怪的反编译【英文标题】:Strange decompilation when using gcc with different optimization 【发布时间】:2020-06-02 10:27:12 【问题描述】:

我在 linux 5.4.18-1-MANJARO 上运行 gcc 版本 9.2.0 (GCC)

文件名:a.c

#include<stdio.h>

int
main(void) 
    int a;

    scanf("%d", &a);

    if (a < 5 || a > 6)
        puts("fail");
    else
        puts("succeed");

然后我运行:

gcc a.c -O0 -o a.out
gcc a.c -O1 -o b.out

我用 r2 反编译 a.out,得到了这个

undefined8 main(void)

    undefined8 uVar1;
    int64_t in_FS_OFFSET;
    int32_t var_ch;
    int64_t canary;

    canary = *(int64_t *)(in_FS_OFFSET + 0x28);
    sym.imp.__isoc99_scanf(0x2004, &var_ch);
    if ((var_ch < 5) || (6 < var_ch)) 
        sym.imp.puts("fail");
     else 
        sym.imp.puts("succeed");
    
    uVar1 = 0;
    if (canary != *(int64_t *)(in_FS_OFFSET + 0x28)) 
        uVar1 = sym.imp.__stack_chk_fail();
    
    return uVar1;

这是我的预期。

但是当我反编译 b.out 时,我得到了这个

undefined8 main(void)

    undefined8 uVar1;
    undefined8 extraout_RDX;
    int64_t iVar2;
    int32_t *piVar3;
    uint32_t uVar4;
    int64_t in_FS_OFFSET;
    int32_t iStack20;
    int64_t iStack16;

    iStack16 = *(int64_t *)(in_FS_OFFSET + 0x28);
    piVar3 = &iStack20;
    sym.imp.__isoc99_scanf(0x2004, piVar3);
    if (iStack20 - 5U < 2) 
        uVar4 = 0x200c;
        sym.imp.puts("succeed");
     else 
        uVar4 = 0x2007;
        sym.imp.puts("fail");
    
    if (iStack16 != *(int64_t *)(in_FS_OFFSET + 0x28)) 
        sym.imp.__stack_chk_fail();
        sym._init();
        iVar2 = 0;
        do 
            uVar1 = (**(code **)(segment.LOAD3 + iVar2 * 8))((uint64_t)uVar4, piVar3, extraout_RDX);
            iVar2 = iVar2 + 1;
         while (iVar2 != 1);
        return uVar1;
    
    return 0;

这似乎只检查 iStack20

我不明白它是如何工作的。

【问题讨论】:

【参考方案1】:

这里利用了整数下溢。操作

iStack20 - 5U

在两个操作数类型不同时执行无符号

否则[有符号不同],如果具有无符号整数类型的操作数的秩大于或 等于另一个操作数的类型的等级,然后操作数与 有符号整数类型转换为无符号操作数的类型 整数类型。

所以如果iStack20 UINT_MAX 附近),因此进行比较

iStack20 - 5U < 2

将是错误的。如果iStack20 > 6,那么结果无论如何都会大于2。所以保留了程序逻辑。

【讨论】:

以上是关于使用具有不同优化的 gcc 时出现奇怪的反编译的主要内容,如果未能解决你的问题,请参考以下文章

Visual Studio 2010 在编译 C++/CLI 项目时出现奇怪的错误

谁能帮我把一个hex文件反编译为c语言文件?

mex 编译时出现 GCC 版本警告

在 raspbian 上构建时出现 gcc 编译器错误

安装交叉编译的 GCC 时出现的错误

GCC - 将宏用于函数属性时出现“具有初始化程序但类型不完整”错误