之前介绍了几种让IDA F5无法得知函数参数的技巧

混淆IDA F5的一个小技巧-x64

混淆IDA F5的一个小技巧-x86

本文介绍一种让IDA F5正常显示函数参数,但却并不是函数实际参数的技巧

比如显示是puts("7777"),但实际上运行时是puts("4396")

源码、编译

代码如下:

#include<stdio.h>
#include<stdlib.h>


int func(int a,int b){
    printf("%d %d\n",a,b);
    return a+b;
}

int main(int argc,char**argv){
    func(12345678,12345678);
    func(12345678,12345678);
    func(12345678,12345678);
    func(12345678,12345678);
    return 0;
}
//gcc -m32 main.c -o test

IDA打开,惯例先patch掉一些东西

最初的main函数

我们把0x0804846C0x0804847E全部nop

patch

我们主要利用在参数压栈过程中,使某段时间esp并不以4字节对齐的技巧,来欺骗IDA的参数识别

patch如下,main函数被显示栈不平衡,虽然不知道为什么,但这没有什么关系,我们还可以F5

其中0x0BC614E就是十进制12345678

因为栈是从高向低生长的,我们先多让esp减去一,再push参数

这将导致其实只让3个字节进入函数参数范围,最后的一个字节其实没有用

然后再inc esp消去影响

看起来IDA应该能很轻松发现这里参数有问题,但实际上...

main函数里是有一点差别

点进sub_8048474((int)&savedregs)

仍然显示的是func(12345678,12345678)

对于像我这样不喜欢动态调试只会F5的人...可以说是灾难了

动态调试

在gdb里调试一下看看参数具体状况

esp仍然以四字节对齐时,gdb-peda给了很多有用的栈上内容信息

再跟进一步,信息全乱了

在我们call func()前,栈上内容如图

参数分别是0xbc610xbc614e,并不像IDA识别的那样

而实际运行结果如下

尝试精确控制参数值

其实是可以精确控制成我们要的参数的值的,尝试控制第一个压栈的参数

patch形如这样

假装0x0ABCD6789是参数,但后面三条指令对它进行了修改

动态调试一波

伪装的参数刚压栈

断在两条指令后

注意栈上内容,0x55556666改变了两字节

这样我们确实可以精确的控制参数...

遗憾的是这个被F5识别出了意图:(

效果较好的一次

patch如图

F5结果

调试:

限于篇幅这段调试过程比较难说明,我自己调试时也想了很久,有兴趣的师傅们可以上手调试一下

结果就是,我们不仅可以欺骗IDA,还可以把0x89674523精确的控制成0xbc618967

运行结果:

总结

最后的一次控制参数比较烧脑,也可能是我还tcl...

欺骗IDA真是一种乐趣...

点击收藏 | 0 关注 | 2 打赏
  • 动动手指,沙发就是你的了!
登录 后跟帖