32位汇编语言学习笔记(20)--栈破坏检测

还是使用前面缓冲区溢出的那个程序,使用-fstack-protector编译选项。

gcc -O1 -m32-fstack-protector-o bufovf bufovf.c

对映像文件进行反汇编:

objdump -d bufovf

得到如下结果:

bufovf:    file format elf32-i386

……

08048524 <getline>:

 8048524:       55                         push  %ebp

 8048525:       89e5                       mov   %esp,%ebp

 8048527:       83ec 28            sub   $0x28,%esp

 804852a:       895d f4            mov   %ebx,0xfffffff4(%ebp)

 804852d:       89 75 f8            mov   %esi,0xfffffff8(%ebp)

 8048530:       897d fc              mov   %edi,0xfffffffc(%ebp)

 8048533:       65 a1 14 00 00 00       mov   %gs:0x14,%eax//gs段地址偏移20的内存中值作为哨兵值装入eax

 8048539:       8945 f0            mov   %eax,0xfffffff0(%ebp)//ebp-16=eax,保存哨兵值到栈中

 804853c:       31c0                       xor   %eax,%eax//eax=0

 804853e:       8d75 e8                      lea   0xffffffe8(%ebp),%esi

 8048541:       8934 24                      mov   %esi,(%esp)

 8048544:       e85f fe ff ff               call  80483a8<gets@plt>

 8048549:       89f7                        mov   %esi,%edi

 804854b:       fc                          cld   

 804854c:       b9ff ff ff ff        mov   $0xffffffff,%ecx

 8048551:       b800 00 00 00         mov   $0x0,%eax

 8048556:       f2ae                        repnz scas %es:(%edi),%al

 8048558:       f7d1                        not   %ecx

 804855a:       83e9 01                      sub   $0x1,%ecx

 804855d:       890c 24            mov   %ecx,(%esp)

 8048560:       e873 fe ff ff              call  80483d8<malloc@plt>

 8048565:       89c3                        mov   %eax,%ebx

 8048567:       8974 24 04           mov   %esi,0x4(%esp)

 804856b:       8904 24                      mov   %eax,(%esp)

 804856e:       e891 ff ff ff               call  8048504<strcpy>

 8048573:       89d8                       mov   %ebx,%eax

 8048575:       8b 55 f0            mov   0xfffffff0(%ebp),%edx//edx=ebp-16

 8048578:       6533 15 14 00 00 00      xor   %gs:0x14,%edx//与哨兵值进行异或运算

 804857f:        7405                       je    8048586<getline+0x62>//等于0表示栈没有破坏,跳转到清理栈代码,继续运行

 8048581:       e862 fe ff ff              call  80483e8<__stack_chk_fail@plt>//如果栈被破坏,则执行栈检查失败处理函数。

 8048586:       8b5d f4            mov   0xfffffff4(%ebp),%ebx

 8048589:       8b75 f8            mov   0xfffffff8(%ebp),%esi

 804858c:       8b7d fc              mov   0xfffffffc(%ebp),%edi

 804858f:        89ec                        mov   %ebp,%esp

 8048591:       5d                         pop   %ebp

 8048592:       c3                         ret   

……


[root@bogon asm]# ./bufovf

Input>12345678

12345678


[root@bogon asm]# ./bufovf

Input>123456789

*** stack smashing detected ***: ./bufovfterminated

Aborted



当字符数达到9个时,程序检查到了栈被破坏,直接异常退出。按理说,当字符数达到8个时,栈就会被破坏(加上一个结尾0字符),没有被破坏,只能说明哨兵值的低位字节恰好是0


做一个实验检查一下哨兵值:

修改一下getline函数:

char *getline()

{

   char buf[8];

   char *result;

    gets(buf);

   result = malloc(strlen(buf));

    strcpy(result,buf);

    sleep(-1);

   return(result);

}

[root@bogon asm]# ./bufovf

Input>1234567


gdb att 6355

(gdb) bt

#0 0x00494402 in __kernel_vsyscall ()

#1 0x00e91fd0 in __nanosleep_nocancel () from /lib/libc.so.6

#2 0x00e91e1f in sleep () from /lib/libc.so.6

#3 0x080485af in getline ()

#4 0x080485f1 in main ()

(gdb) info frame 3

Stack frame at 0xbff9c630:

 eip= 0x80485af in getline; saved eip 0x80485f1

 called by frame at 0xbff9c640, caller of frameat 0xbff9c600

 Arglist at 0xbff9c628, args:

 Locals at 0xbff9c628, Previous frame's sp is0xbff9c630

 Saved registers:

  ebpat 0xbff9c628, eip at 0xbff9c62c

(gdb) x /20x 0xbff9c610

0xbff9c610:    0x34333231      0x00373635      0x0c3fd200      0x00f55ff4

0xbff9c620:    0x001d0ca0      0x00000000      0xbff9c638      0x080485f1

0xbff9c630:    0x080486e0      0xbff9c650      0xbff9c6a8      0x00e15e9c

0xbff9c640:    0x001d0ca0      0x08048620      0xbff9c6a8      0x00e15e9c

哨兵值的低位1个字节果然是0(小头排序)。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值