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

2019-05-08 约 1327 字 预计阅读 3 分钟

声明:本文 【混淆IDA F5的一个小技巧-x86】 由作者 ret2nullptr 于 2019-05-08 09:46:00 首发 先知社区 曾经 浏览数 25 次

感谢 ret2nullptr 的辛苦付出!

上一篇文章介绍了x64架构的程序通过patch让IDA无法正确识别参数的小技巧,本文补充一下x86架构中这个技巧的运用

平级函数的修改

源码、编译

测试程序源码如下:

vuln只是命名习惯了...并不是指漏洞函数

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

int func(int a) {
    int num = a; 
    printf("%d",a);
    getchar();
    getchar();
    return 1;
}

int func_wrapper(int b) {
    func(b+1); 
    int num = b;
    printf("%d",num);
    getchar();
    getchar();
    getchar();
    return 2;
}


int vuln(int num){
    printf("%d",num);
    return 0xff;
}

int main(int argc, char** argv) {
    func_wrapper(1);
    vuln(2);
    return 0;
}

程序没有什么特别的,注意getchar()因为没有参数,就是用来nop掉然后开始表演的,也不会影响堆栈平衡

编译:gcc -m32 main.c -o test

编译过后IDA打开,基本是这样

因为没有开优化,所以esp的加加减减没有被合并

patch

因为x64fastcall,前几个参数用寄存器传参;而x86则全是用栈传参

原先vuln函数显示是这样的(这两个就是"平级函数")

目的是让它显示成vuln(v3)这种形式,以达到一些干扰的效果

我们关注这段汇编

func_wrapper的参数是1,被push到栈中

vuln函数调用之前先收回了原先参数1的栈,又压入了自己的参数2

我们可以把vuln的参数改成1,比如这样

去掉了一个push 2,对应的,多sub esp,4

保存patch版本,重新打开

显示已经变成了这样

gdb-peda中调试一下,原先可以显示出Guessed arguments

现在虽然栈上的参数被我们改成了1,但也只是改了一个数值,而Guessed arguments已经显示错误了

子函数改父函数

很显然刚刚的技巧在动态调试时会暴露无遗,IDA F5虽然没有成功识别参数,但是也给出了程序的大致逻辑,这次我们用一些更复杂的方法来混淆干扰

源码、编译

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

int func() {
    getchar();
    getchar();
    getchar();
    return 1;
}

int func_wrapper(int num) {
    printf("%d",num);
    func();
    printf("%d",num);
    return 2;
}

int main(int argc, char** argv) {
    func_wrapper(1);
    return 0;
}

编译:gcc -m32 main.c -o test

我们的目标是让func_wrapper中的两次printf("%d",num);输出不同的值

patch1

关键的patchfunc()里,预留的3个getchar()就是nop后留下空间表演的

patch2

我们调试一下,看看nop时的esp的值,再根据func_wrapper的参数在栈上的地址,算出偏移

断在printf("%d",num);参数入栈前,发现0xffffcfd0处为参数

跟进,进入func()的一堆nop

此时esp的值0xffffcfb0

算出esp距离父函数的参数偏移为0x20

patch3

我们在func中修改如下

中间改掉的三行就是把父函数printf的参数改掉了

原先运行会输出两个1,但是由于我们把第二次输出的参数改成了2,输出如下

中途调的时候有好多小问题...

此时,IDA打开,func函数已经无法F5

func_wrapper中也看不出我们在func里做了什么手脚

总结

原理不难理解,实际上手作为花指令单靠patch显然效率太低也容易被发现

上次x64的技巧,我夜影大哥给了一个C语言内联汇编在复杂函数中悄咪咪内联传参的建议,之后会试一下

另外,考虑递归函数,如果也在内层把外层的参数改了,可能会让人疯掉...没有敢去尝试

比如用一个随机数函数,加上内联汇编,符合某条件就改外层参数,栈回溯时会非常复杂

关键词:[‘安全技术’, ‘二进制安全’]


author

旭达网络

旭达网络技术博客,曾记录各种技术问题,一贴搞定.
本文采用知识共享署名 4.0 国际许可协议进行许可。

We notice you're using an adblocker. If you like our webite please keep us running by whitelisting this site in your ad blocker. We’re serving quality, related ads only. Thank you!

I've whitelisted your website.

Not now