使用具有不同优化的 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 时出现奇怪的反编译的主要内容,如果未能解决你的问题,请参考以下文章