金源娱乐混淆IDA F5的一个小技巧-x86_HUC惠仲娱乐

金源娱乐

上一篇文章介绍了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语言内联汇编在复杂函数中悄咪咪内联传参的建议,之后会试一下

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

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