ida反编译失败应对

基本都是堆栈不平衡引起的

在IDA Pro中,如果返回之前没有清理堆栈分配(平衡堆栈指针),则反编译器将拒绝反编译该函数.

参考慎点!来自反编译器的危险 - FreeBuf网络安全行业门户

0x1

成因

程序存在一些故意干扰指令

比如用push(call 本函数内部) + n条指令 + retn来实际跳转,而IDA会将这个retn认为是整个函数结束

结果分析后发现调用栈不平衡,因此就提示sp analysis failed.

解决

分析干扰指令,并优化

2023ciscn华东南—colorful

直接反编译main

提示我们问题出在1d87处

标黄的retn被认为是main的结束,但显然不是,因此栈不平衡

且retn上面的部分都是干扰指令

那么就要想办法优化这部分指令

先分析干扰指令

  1. call loc_1D8F:push rip(1D8C),jmp loc_1D8F
  2. pop rax:将rax变为1D8C,再跳转
  3. inc rax:rax加1,成为1D8D,再跳转
  4. push rax; retn:将rax压入栈,并以此为返回地址
  5. 1D8D处的指令为E8 0D,即jmp 1d8c+D(即1d9c)

可以看到这部分代码没有实现任何功能,完全就是干扰

完全可以优化

在1d87处直接跳转到1d9c,其余代码全部nop

之后即可得到伪代码

结论

发现干扰指令并优化,去除提前出现的retn等会让ida误解的指令

0x2

解决

修正sp值

保持call或jmp等跳转指令前后栈平衡

call或jmp等跳转指令前的sp是多少,那么紧接在该指令后的sp也修改为多少

0x3

解决

选中红色代码部分,快捷键p创建函数,该部分即可得到伪代码

但前面的部分依然不行

再调整函数开始的sp尝试

0x4

成因

1
2
3
4
5
6
7
8
int one_function( int a,int b);

int another_function( int a, int b)
{
if ( a == 0 || b == 0 )
return -1;
return one_function(a,b);
}

其中return one_function(a,b)这条语句,在某些新的编译器,可能会编译成这样的指令序列:

1
2
3
mov esp, ebp
pop ebp
jmp one_funcion

而IDA是通过retn指令来识别函数的结束的,因为它不知道这里的意思,会把它当成一个函数内部 的跳转,最后就会出现sp analysis failed了。

解决

调整指令

ida调试elf

关于ubuntu中使用clash

0x1 clash设置

首先clash开启允许局域网连接,并记住端口一般是7890

0x2 设置网络

在网络的属性->共享中设置网络

0x3 查看vmnet8的ip

cmd窗口输入ipconfig获得vmnet8的ipv4地址

0x4 虚拟机代理设置

虚拟机设置->网络->代理,设置为手动并填充之前的信息