一个小小的溢出试验

一个小小的溢出试验

  今天在学习溢出时写了个简单程序,源代码如下。
 1 #include  < stdio.h >
 2 #include  < stdlib.h >
 3
 4 int  foo_normal( char * );
 5 int  foo_abnormal( char * );
 6
 7 int  main()
 8 {
 9    int i;
10    char szTmp[] = {
11        0x310x310x310x31
12        0x320x320x320x32
13        0x330x330x330x33,
14        0x000x400x130x45,
15        
16        0x310x310x310x31
17        0x320x320x320x32
18        0x330x330x330x33,
19        0x4e0x130x400x00
20        }
;
21        
22    i = 0;
23    
24    if (i == 0)
25        foo_normal(szTmp);
26    else
27        foo_abnormal(szTmp);
28        
29    return(0);
30}
    
31
32
33 int  foo_normal( char *  _sz)
34 {
35    char buffer[5];
36    memcpy(buffer, _sz, sizeof(char)*32);
37    printf("Application terminates normally.\n");
38    return(0);
39}
    
40 int  foo_abnormal( char *  _sz)
41 {
42    char buffer[5];
43    memcpy(buffer, _sz, sizeof(char)*3);
44    printf("You should have never seen this.\n");
45    return (0);
46}
    

  打算通过foo_normal中的memcpy函数覆盖栈中的EIP,改为调用foo_abnormal处的语句,来达到溢出攻击的目的。按照正常情况看,在foo_normal中,栈里有4字节的CS和4字节的EIP,然后是5字节的字符串数组——对齐后是8字节,还有4字节的EBP。所以当往buffer中复制12字节数据就可以覆盖掉EIP而达到溢出的目的。但实际上使用32字节的数据覆盖buffer及其后的数据,才把EIP给照顾到。使用OllyDBG跟了一下:
 1  004013F2   / $   55             push    ebp
 2  004013F3   | .  89E5          mov     ebp, esp
 3  004013F5   | .  83EC  28        sub     esp,  28
 4  004013F8   | .  C74424  08   050 > mov     dword ptr [esp + 8 ],  5              ;  ||
 5  00401400    | .  8B45  08        mov     eax, dword ptr [ebp + 8 ]           ;  ||
 6  00401403    | .   894424   04      mov     dword ptr [esp + 4 ], eax           ;  ||
 7  00401407    | .  8D45 E8       lea     eax, dword ptr [ebp - 18 ]          ;  ||
 8  0040140A   | .   890424         mov     dword ptr [esp], eax             ;  ||
 9  0040140D   | .  E8 FE050000   call     < jmp. & msvcrt.memcpy >              ;  | \memcpy
10  00401412    | .  C70424 D01340 > mov     dword ptr [esp], 004013D0        ;  | ASCII  " Application terminates normally. " ,LF
11  00401419    | .  E8 EA050000   call     < jmp. & msvcrt.printf >              ; \printf
12  0040141E   | .  B8  00000000    mov     eax,  0
13  00401423    | .  C9            leave
14  00401424   \.  C3            retn

  发现在进入函数的时候申请了28个字节的空间——除去12字节给memcpy的参数,比预想的多了6字节。看来使用的3.3.1版本的gcc是16字节对齐的。

  ……让我抓狂了一个小时。

你可能感兴趣的:(一个小小的溢出试验)