DigtheWay
Created At :
Views 👀 :
Dig the way
栈溢出
这是一道栈溢出的题目,拖进ida查看主函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
| int __cdecl main(int argc, const char **argv, const char **envp) { int v4; int v5; char Str[20]; int v7[3]; size_t v8; int v9; int v10; int v11[3]; int v12; size_t v13; FILE *Stream;
__main(); v11[0] = (int)func0; v11[1] = (int)func1; v11[2] = (int)func2; v7[0] = 0; v7[1] = 1; v7[2] = 2; v8 = 3; v9 = 3; v10 = 4; Stream = fopen("data", "rb"); if ( !Stream ) return -1; fseek(Stream, 0, 2); v13 = ftell(Stream); fseek(Stream, 0, 0); v12 = ftell(Stream); if ( v12 ) { puts("something wrong"); return 0; } else { for ( i = 0; i < (int)v13; ++i ) { v4 = i; Str[v4] = fgetc(Stream); } if ( strlen(Str) <= v13 ) { v13 = v8; i = 0; v12 = v10; while ( i <= 2 ) { v5 = i + 1; v7[v5] = ((int (__cdecl *)(int *, int, int))v11[i])(v7, v9, v10); v9 = ++i; v10 = i + 1; } if ( v8 ) { return -1; } else { get_key(v13, v12); system("PAUSE"); return 0; } } else { return -1; } } }
|
得到flag的条件是v8==0,但并没有对v8的操作,仔细看可以发现在while循环中当i=3时存在栈溢出,实际上是对v8进行赋值,这是再去看func0,func1,func2
1 2 3 4 5 6 7 8 9
| int __cdecl func0(int a1, int a2, int a3) { int v4;
v4 = *(_DWORD *)(4 * a2 + a1); *(_DWORD *)(a1 + 4 * a2) = *(_DWORD *)(4 * a3 + a1); *(_DWORD *)(a1 + 4 * a3) = v4; return 1; }
|
1 2 3 4 5 6 7
| unsigned int __cdecl func1(int a1, int a2, int a3) { return abs32(*(_DWORD *)(4 * a2 + a1) + *(_DWORD *)(4 * a3 + a1)) - abs32(*(_DWORD *)(4 * a3 + a1)) - abs32(*(_DWORD *)(4 * a2 + a1)) + 2; }
|
1 2 3 4 5 6 7
| unsigned int __cdecl func2(int a1, int a2, int a3) { return abs32(*(_DWORD *)(4 * a3 + a1)) - abs32(*(_DWORD *)(4 * a3 + a1) + *(_DWORD *)(4 * a2 + a1)) + abs32(*(_DWORD *)(4 * a2 + a1)) + 2; }
|
func0是一个互换函数,func1的返回值可以为0但func2的返回值恒大于0,所以可以利用读入data文件时的数据溢出来修改函数的参数,利用func0将func1和func2的顺序交换,这样才能使v8的值为0,读入的data会赋给str数组,而str数组的长度是20,然后就是v7的地址,偏移量分别就是20+0=20,20+4 =24,20+4 * 2=28,然后是v8,20+4 * 3=32,v9=>20+4 * 4=36,v10=>20+5 * 4=40,然后是三个函数,v11[0]=>20+4 * 6,v11[1]=>20+4 * 7,v11[2]=20+4 * 8
分析后可以知道,func的参数是v9和v10,但是需要将他修改为v11[1]和v11[2],也就是把36字节和40字节处的数据改为7和8
调用func1的时候v[2]=2,所以需要将v8改为-1,即地址为32处改为FF FF FF FF
![屏幕截图 2023-11-15 182751](D:\Blog\source_posts\DigtheWay\屏幕截图 2023-11-15 182751.png)
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 3049155267@qq.com