GCC 5 不会检测内联函数的堆栈粉碎,但 GCC 7 可以



这是我用来测试gcc堆栈保护功能的代码。

static inline void  charcpy(char* temp)
{
temp[0]='a';
temp[1]='b';
temp[2]='c';
temp[3]='d';
temp[4]='';
}
int main()
{
char temp[3];
charcpy(temp);
return 0;
}

当我使用 gcc 7.3 编译时(未指定任何标志(,我在桌面上收到以下运行时错误

*** stack smashing detected ***: <unknown> terminated
Aborted (core dumped)

uname -a 命令为我的桌面提供以下内容,如果重要的话

Linux lixun-Desktop 4.15.0-36-generic #39-Ubuntu SMP Mon Sep 24 16:19:09 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

但是,当我在使用gcc 5.4的服务器计算机上尝试相同操作时,没有显示任何错误。服务器计算机的 uname -a 命令是

Linux aggravation 4.4.0-137-generic #163-Ubuntu SMP Mon Sep 24 13:14:43 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

然后我使用 objdump -D a.out 检查他们的汇编代码,但仍然无法弄清楚为什么堆栈保护在服务器机器上不起作用。 这是我桌面上的输出(我只粘贴我认为可能重要的部分(

Disassembly of section .init:
0000000000000510 <_init>:
510:   48 83 ec 08             sub    $0x8,%rsp
514:   48 8b 05 cd 0a 20 00    mov    0x200acd(%rip),%rax        # 200fe8 <__gmon_start__>
51b:   48 85 c0                test   %rax,%rax
51e:   74 02                   je     522 <_init+0x12>
520:   ff d0                   callq  *%rax
522:   48 83 c4 08             add    $0x8,%rsp
526:   c3                      retq   
Disassembly of section .plt:
0000000000000530 <.plt>:
530:   ff 35 8a 0a 20 00       pushq  0x200a8a(%rip)        # 200fc0 <_GLOBAL_OFFSET_TABLE_+0x8>
536:   ff 25 8c 0a 20 00       jmpq   *0x200a8c(%rip)        # 200fc8 <_GLOBAL_OFFSET_TABLE_+0x10>
53c:   0f 1f 40 00             nopl   0x0(%rax)
0000000000000540 <__stack_chk_fail@plt>:
540:   ff 25 8a 0a 20 00       jmpq   *0x200a8a(%rip)        # 200fd0 <__stack_chk_fail@GLIBC_2.4>
546:   68 00 00 00 00          pushq  $0x0
54b:   e9 e0 ff ff ff          jmpq   530 <.plt>
Disassembly of section .plt.got:
0000000000000550 <__cxa_finalize@plt>:
550:   ff 25 a2 0a 20 00       jmpq   *0x200aa2(%rip)        # 200ff8 <__cxa_finalize@GLIBC_2.2.5>
556:   66 90                   xchg   %ax,%ax
...
Disassembly of section .text:
0000000000000560 <_start>:
560:   31 ed                   xor    %ebp,%ebp
562:   49 89 d1                mov    %rdx,%r9
565:   5e                      pop    %rsi
566:   48 89 e2                mov    %rsp,%rdx
569:   48 83 e4 f0             and    $0xfffffffffffffff0,%rsp
56d:   50                      push   %rax
56e:   54                      push   %rsp
56f:   4c 8d 05 ea 01 00 00    lea    0x1ea(%rip),%r8        # 760 <__libc_csu_fini>
576:   48 8d 0d 73 01 00 00    lea    0x173(%rip),%rcx        # 6f0 <__libc_csu_init>
57d:   48 8d 3d 24 01 00 00    lea    0x124(%rip),%rdi        # 6a8 <main>
584:   ff 15 56 0a 20 00       callq  *0x200a56(%rip)        # 200fe0 <__libc_start_main@GLIBC_2.2.5>
58a:   f4                      hlt    
58b:   0f 1f 44 00 00          nopl   0x0(%rax,%rax,1)
...
000000000000066a <charcpy>:
66a:   55                      push   %rbp
66b:   48 89 e5                mov    %rsp,%rbp
66e:   48 89 7d f8             mov    %rdi,-0x8(%rbp)
672:   48 8b 45 f8             mov    -0x8(%rbp),%rax
676:   c6 00 61                movb   $0x61,(%rax)
679:   48 8b 45 f8             mov    -0x8(%rbp),%rax
67d:   48 83 c0 01             add    $0x1,%rax
681:   c6 00 62                movb   $0x62,(%rax)
684:   48 8b 45 f8             mov    -0x8(%rbp),%rax
688:   48 83 c0 02             add    $0x2,%rax
68c:   c6 00 63                movb   $0x63,(%rax)
68f:   48 8b 45 f8             mov    -0x8(%rbp),%rax
693:   48 83 c0 03             add    $0x3,%rax
697:   c6 00 64                movb   $0x64,(%rax)
69a:   48 8b 45 f8             mov    -0x8(%rbp),%rax
69e:   48 83 c0 04             add    $0x4,%rax
6a2:   c6 00 00                movb   $0x0,(%rax)
6a5:   90                      nop
6a6:   5d                      pop    %rbp
6a7:   c3                      retq   
00000000000006a8 <main>:
6a8:   55                      push   %rbp
6a9:   48 89 e5                mov    %rsp,%rbp
6ac:   48 83 ec 10             sub    $0x10,%rsp
6b0:   64 48 8b 04 25 28 00    mov    %fs:0x28,%rax
6b7:   00 00 
6b9:   48 89 45 f8             mov    %rax,-0x8(%rbp)
6bd:   31 c0                   xor    %eax,%eax
6bf:   48 8d 45 f5             lea    -0xb(%rbp),%rax
6c3:   48 89 c7                mov    %rax,%rdi
6c6:   e8 9f ff ff ff          callq  66a <charcpy>
6cb:   b8 00 00 00 00          mov    $0x0,%eax
6d0:   48 8b 55 f8             mov    -0x8(%rbp),%rdx
6d4:   64 48 33 14 25 28 00    xor    %fs:0x28,%rdx
6db:   00 00 
6dd:   74 05                   je     6e4 <main+0x3c>
6df:   e8 5c fe ff ff          callq  540 <__stack_chk_fail@plt>
6e4:   c9                      leaveq 
6e5:   c3                      retq   
6e6:   66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)
6ed:   00 00 00 

这是服务器机器上的输出

Disassembly of section .init:
00000000004003f0 <_init>:
4003f0:   48 83 ec 08             sub    $0x8,%rsp
4003f4:   48 8b 05 fd 0b 20 00    mov    0x200bfd(%rip),%rax        # 600ff8 <_DYNAMIC+0x1d0>
4003fb:   48 85 c0                test   %rax,%rax
4003fe:   74 05                   je     400405 <_init+0x15>
400400:   e8 3b 00 00 00          callq  400440 <__libc_start_main@plt+0x10>
400405:   48 83 c4 08             add    $0x8,%rsp
400409:   c3                      retq   
Disassembly of section .plt:
0000000000400410 <__stack_chk_fail@plt-0x10>:
400410:   ff 35 f2 0b 20 00       pushq  0x200bf2(%rip)        # 601008 <_GLOBAL_OFFSET_TABLE_+0x8>
400416:   ff 25 f4 0b 20 00       jmpq   *0x200bf4(%rip)        # 601010 <_GLOBAL_OFFSET_TABLE_+0x10>
40041c:   0f 1f 40 00             nopl   0x0(%rax)
0000000000400420 <__stack_chk_fail@plt>:
400420:   ff 25 f2 0b 20 00       jmpq   *0x200bf2(%rip)        # 601018 <_GLOBAL_OFFSET_TABLE_+0x18>
400426:   68 00 00 00 00          pushq  $0x0
40042b:   e9 e0 ff ff ff          jmpq   400410 <_init+0x20>
0000000000400430 <__libc_start_main@plt>:
400430:   ff 25 ea 0b 20 00       jmpq   *0x200bea(%rip)        # 601020 <_GLOBAL_OFFSET_TABLE_+0x20>
400436:   68 01 00 00 00          pushq  $0x1
40043b:   e9 d0 ff ff ff          jmpq   400410 <_init+0x20>
Disassembly of section .plt.got:
0000000000400440 <.plt.got>:
400440:   ff 25 b2 0b 20 00       jmpq   *0x200bb2(%rip)        # 600ff8 <_DYNAMIC+0x1d0>
400446:   66 90                   xchg   %ax,%ax
...
Disassembly of section .text:
0000000000400450 <_start>:
400450:   31 ed                   xor    %ebp,%ebp
400452:   49 89 d1                mov    %rdx,%r9
400455:   5e                      pop    %rsi
400456:   48 89 e2                mov    %rsp,%rdx
400459:   48 83 e4 f0             and    $0xfffffffffffffff0,%rsp
40045d:   50                      push   %rax
40045e:   54                      push   %rsp
40045f:   49 c7 c0 40 06 40 00    mov    $0x400640,%r8
400466:   48 c7 c1 d0 05 40 00    mov    $0x4005d0,%rcx
40046d:   48 c7 c7 84 05 40 00    mov    $0x400584,%rdi
400474:   e8 b7 ff ff ff          callq  400430 <__libc_start_main@plt>
400479:   f4                      hlt    
40047a:   66 0f 1f 44 00 00       nopw   0x0(%rax,%rax,1)
0000000000400546 <charcpy>:
400546:   55                      push   %rbp
400547:   48 89 e5                mov    %rsp,%rbp
40054a:   48 89 7d f8             mov    %rdi,-0x8(%rbp)
40054e:   48 8b 45 f8             mov    -0x8(%rbp),%rax
400552:   c6 00 61                movb   $0x61,(%rax)
400555:   48 8b 45 f8             mov    -0x8(%rbp),%rax
400559:   48 83 c0 01             add    $0x1,%rax
40055d:   c6 00 62                movb   $0x62,(%rax)
400560:   48 8b 45 f8             mov    -0x8(%rbp),%rax
400564:   48 83 c0 02             add    $0x2,%rax
400568:   c6 00 63                movb   $0x63,(%rax)
40056b:   48 8b 45 f8             mov    -0x8(%rbp),%rax
40056f:   48 83 c0 03             add    $0x3,%rax
400573:   c6 00 64                movb   $0x64,(%rax)
400576:   48 8b 45 f8             mov    -0x8(%rbp),%rax
40057a:   48 83 c0 04             add    $0x4,%rax
40057e:   c6 00 00                movb   $0x0,(%rax)
400581:   90                      nop
400582:   5d                      pop    %rbp
400583:   c3                      retq   
0000000000400584 <main>:
400584:   55                      push   %rbp
400585:   48 89 e5                mov    %rsp,%rbp
400588:   48 83 ec 10             sub    $0x10,%rsp
40058c:   64 48 8b 04 25 28 00    mov    %fs:0x28,%rax
400593:   00 00 
400595:   48 89 45 f8             mov    %rax,-0x8(%rbp)
400599:   31 c0                   xor    %eax,%eax
40059b:   48 8d 45 f0             lea    -0x10(%rbp),%rax
40059f:   48 89 c7                mov    %rax,%rdi
4005a2:   e8 9f ff ff ff          callq  400546 <charcpy>
4005a7:   b8 00 00 00 00          mov    $0x0,%eax
4005ac:   48 8b 55 f8             mov    -0x8(%rbp),%rdx
4005b0:   64 48 33 14 25 28 00    xor    %fs:0x28,%rdx
4005b7:   00 00 
4005b9:   74 05                   je     4005c0 <main+0x3c>
4005bb:   e8 60 fe ff ff          callq  400420 <__stack_chk_fail@plt>
4005c0:   c9                      leaveq 
4005c1:   c3                      retq   
4005c2:   66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)
4005c9:   00 00 00 
4005cc:   0f 1f 40 00             nopl   0x0(%rax)
...

我还尝试在服务器机器上指定 -fstack-protector(-all 或 -strong(,它仍然没有显示错误。 有谁知道为什么会有区别?

服务器计算机将数组temp放置在main堆栈帧中的不同位置。 它使用此操作来计算地址,与帧指针的偏移量为 16 字节:

40059b:   48 8d 45 f0             lea    -0x10(%rbp),%rax

另一台计算机改用这个:

6bf:   48 8d 45 f5             lea    -0xb(%rbp),%rax

帧指针只有一个 11 字节的偏移量。 在这两种情况下,金丝雀都存储在偏移量 8 处。

结果,在服务器机器上,数组后有 5 个未使用的字节,溢出会溢出到该字节中。 金丝雀不会被覆盖,这就是未检测到溢出的原因。 但返回地址也不是,因此无法在此处重定向执行。

在实际软件中,这将是一个基于源代码级堆栈的缓冲区溢出,在编译的二进制文件中不会被意外利用。 这样的事情偶尔会发生。

最新更新