首页
论坛
课程
招聘
[求助][已解决] 堆溢出 house of spirit 关于gcc编译后的栈空间变量顺序问题
2017-12-3 15:01 2557

[求助][已解决] 堆溢出 house of spirit 关于gcc编译后的栈空间变量顺序问题

2017-12-3 15:01
2557

问题

请教大家一个问题,ubuntu16.04中gcc(version 5.4.0 20160609 )在编译时,默认将函数中的数组变量放到高地址,这样在栈溢出时就无法溢出其他的局部变量了。这是这个版本gcc的默认编译设置,请问有什么方法可以关闭这个优化吗?

环境

➜ ~/Desktop/20171201-fastbin$ gcc --version
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.5) 5.4.0 20160609
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

➜ ~/Desktop/20171201-fastbin$ uname -a
Linux thinkpad 4.4.0-101-generic #124-Ubuntu SMP Fri Nov 10 18:29:59 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux

测试程序

gcc xx.c -o xx

#include<stdio.h>
#include<unistd.h>
void main()
{
    int a=1;
    char b[104];
    int c = 2;
    read(STDIN_FILENO,b,100);
    printf("end\n");   
}

反汇编结果

var_78= dword ptr -78h
var_74= dword ptr -74h
buf= byte ptr -70h
var_8= qword ptr -8

push    rbp
mov     rbp, rsp
add     rsp, 0FFFFFFFFFFFFFF80h
mov     rax, fs:28h
mov     [rbp+var_8], rax
xor     eax, eax
mov     [rbp+var_78], 1
mov     [rbp+var_74], 2
lea     rax, [rbp+buf]

在house of spirit中的体现就是,无法溢出将要free的指针了。
谢谢大家。

20171204 解决问题更新

gcc默认情况下会使用-fstack-protector-strong参数来编译,使用-fno-stack-protector参数可以关闭默认设置。

man gcc>
       -fstack-protector
           Emit extra code to check for buffer overflows, such as stack
           smashing attacks.  This is done by adding a guard variable to
           functions with vulnerable objects.  This includes functions that
           call "alloca", and functions with buffers larger than 8 bytes.  The
           guards are initialized when a function is entered and then checked
           when the function exits.  If a guard check fails, an error message
           is printed and the program exits.

       -fstack-protector-all
           Like -fstack-protector except that all functions are protected.

       -fstack-protector-strong
           Like -fstack-protector but includes additional functions to be
           protected --- those that have local array definitions, or have
           references to local frame addresses.

       -fstack-protector-explicit
           Like -fstack-protector but only protects those functions which have
           the "stack_protect" attribute

       -fstdarg-opt
           Optimize the prologue of variadic argument functions with respect
           to usage of those arguments.

           NOTE: In Ubuntu 14.10 and later versions, -fstack-protector-strong
           is enabled by default for C, C++, ObjC, ObjC++, if none of
           -fno-stack-protector, -nostdlib, nor -ffreestanding are found.

对比一下我们发现stack-protector的效果不仅仅是加入了canary,还增加了变量重排技术,类似windows VS中引入的GS编译技术。

➜ ~/Desktop/20171201-fastbin$ objdump -d testbianliang-2-no-stack-protector -M intel |  sed '/main>:/,/^$/!d' 
0000000000400566 <main>:
  400566:    55                       push   rbp
  400567:    48 89 e5                 mov    rbp,rsp
  40056a:    48 83 ec 70              sub    rsp,0x70
  40056e:    c7 45 fc 01 00 00 00     mov    DWORD PTR [rbp-0x4],0x1
  400575:    c7 45 f8 02 00 00 00     mov    DWORD PTR [rbp-0x8],0x2
  40057c:    48 8d 45 90              lea    rax,[rbp-0x70]
  400580:    ba 64 00 00 00           mov    edx,0x64
  400585:    48 89 c6                 mov    rsi,rax
  400588:    bf 00 00 00 00           mov    edi,0x0
  40058d:    e8 ae fe ff ff           call   400440 <read@plt>
  400592:    bf 24 06 40 00           mov    edi,0x400624
  400597:    e8 94 fe ff ff           call   400430 <puts@plt>
  40059c:    90                       nop
  40059d:    c9                       leave  
  40059e:    c3                       ret    
  40059f:    90                       nop

➜ ~/Desktop/20171201-fastbin$ objdump -d testbianliang-2 -M intel |  sed '/main>:/,/^$/!d' 
00000000004005d6 <main>:
  4005d6:    55                       push   rbp
  4005d7:    48 89 e5                 mov    rbp,rsp
  4005da:    48 83 c4 80              add    rsp,0xffffffffffffff80
  4005de:    64 48 8b 04 25 28 00     mov    rax,QWORD PTR fs:0x28
  4005e5:    00 00 
  4005e7:    48 89 45 f8              mov    QWORD PTR [rbp-0x8],rax
  4005eb:    31 c0                    xor    eax,eax
  4005ed:    c7 45 88 01 00 00 00     mov    DWORD PTR [rbp-0x78],0x1
  4005f4:    c7 45 8c 02 00 00 00     mov    DWORD PTR [rbp-0x74],0x2
  4005fb:    48 8d 45 90              lea    rax,[rbp-0x70]
  4005ff:    ba 64 00 00 00           mov    edx,0x64
  400604:    48 89 c6                 mov    rsi,rax
  400607:    bf 00 00 00 00           mov    edi,0x0
  40060c:    e8 9f fe ff ff           call   4004b0 <read@plt>
  400611:    bf c4 06 40 00           mov    edi,0x4006c4
  400616:    e8 75 fe ff ff           call   400490 <puts@plt>
  40061b:    90                       nop
  40061c:    48 8b 45 f8              mov    rax,QWORD PTR [rbp-0x8]
  400620:    64 48 33 04 25 28 00     xor    rax,QWORD PTR fs:0x28
  400627:    00 00 
  400629:    74 05                    je     400630 <main+0x5a>
  40062b:    e8 70 fe ff ff           call   4004a0 <__stack_chk_fail@plt>
  400630:    c9                       leave  
  400631:    c3                       ret    
  400632:    66 2e 0f 1f 84 00 00     nop    WORD PTR cs:[rax+rax*1+0x0]
  400639:    00 00 00 
  40063c:    0f 1f 40 00              nop    DWORD PTR [rax+0x0]

[培训]12月3日2020京麒网络安全大会《物联网安全攻防实战》训练营,正在火热报名中!地点:北京 · 新云南皇冠假日酒店

收藏
点赞0
打赏
分享
最新回复 (7)
雪    币: 60
活跃值: 活跃值 (15)
能力值: ( LV3,RANK:35 )
在线值:
发帖
回帖
粉丝
返無歸一 活跃值 2017-12-3 18:05
2
0
包在struct裡?
雪    币: 4343
活跃值: 活跃值 (43)
能力值: ( LV10,RANK:160 )
在线值:
发帖
回帖
粉丝
心许雪 活跃值 3 2017-12-4 09:48
3
0



返無歸一

包在struct裡?
您好,不是很明白包在stuct里是什么意思。可否具体解释一下呢?我的目标是希望,b数组可以在低地址,变量  c在高地址。
雪    币: 779
活跃值: 活跃值 (68)
能力值: ( LV12,RANK:280 )
在线值:
发帖
回帖
粉丝
Ox9A82 活跃值 3 2017-12-4 11:57
4
0
的确是会调整局部变量位置的  就跟GS一样
雪    币: 60
活跃值: 活跃值 (15)
能力值: ( LV3,RANK:35 )
在线值:
发帖
回帖
粉丝
返無歸一 活跃值 2017-12-4 17:53
5
0
我自己出题目给学弟玩得时候遇到同样的问题过,但不确定是不是你要的~

以下是随便举例,跟你的题目无关
int  i;  //HIGH
char  buf[10];  //low

但是编译好後会变成
char  buf[10];  //HIGH
int  i;    //LOW

避免你盖掉int  i

用struct{
        char  buf[10];
        int  i;
};
就会是buf在低,i在高
雪    币: 60
活跃值: 活跃值 (15)
能力值: ( LV3,RANK:35 )
在线值:
发帖
回帖
粉丝
返無歸一 活跃值 2017-12-4 17:54
6
0
reference
https://stackoverflow.com/questions/1102049/order-of-local-variable-allocation-on-the-stack
雪    币: 60
活跃值: 活跃值 (15)
能力值: ( LV3,RANK:35 )
在线值:
发帖
回帖
粉丝
返無歸一 活跃值 2017-12-4 17:56
7
0
喔喔原来你已经解决了XD
雪    币: 4343
活跃值: 活跃值 (43)
能力值: ( LV10,RANK:160 )
在线值:
发帖
回帖
粉丝
心许雪 活跃值 3 2017-12-5 10:09
8
0
返無歸一 喔喔原来你已经解决了XD
学习了,谢谢~XD
游客
登录 | 注册 方可回帖
返回