2015-11-13 124 views
-2

以下是三个不同的.s文件的一部分。 .c文件已经编有三个不同的选项:此机器代码如何防止缓冲区溢出?

  1. -fno-直列-fstack保护器强,
  2. -fno-直列-fsanitize =地址,
  3. -fno内联-fno -stack-protector -zexecstack。

以下是的.S文件的内容:

handle_read: 
.LFB20: 
    .cfi_startproc 
    pushq %r12 
    .cfi_def_cfa_offset 16 
    .cfi_offset 12, -16 
    pushq %rbp 
    .cfi_def_cfa_offset 24 
    .cfi_offset 6, -24 
    movq %rsi, %r12 
    pushq %rbx 
    .cfi_def_cfa_offset 32 
    .cfi_offset 3, -32 
    movq 8(%rdi), %rbx 
    movq %rdi, %rbp 
    movq 160(%rbx), %rsi 
    movq 152(%rbx), %rdx 
    cmpq %rdx, %rsi 
    jb  .L394 
    cmpq $5000, %rdx 
    jbe  .L421 

handle_read: 
.LASANPC20: 
.LFB20: 
    .cfi_startproc 
    pushq %r15 
    .cfi_def_cfa_offset 16 
    .cfi_offset 15, -16 
    pushq %r14 
    .cfi_def_cfa_offset 24 
    .cfi_offset 14, -24 
    pushq %r13 
    .cfi_def_cfa_offset 32 
    .cfi_offset 13, -32 
    pushq %r12 
    .cfi_def_cfa_offset 40 
    .cfi_offset 12, -40 
    pushq %rbp 
    .cfi_def_cfa_offset 48 
    .cfi_offset 6, -48 
    movq %rdi, %rbp 
    addq $8, %rdi 
    pushq %rbx 
    .cfi_def_cfa_offset 56 
    .cfi_offset 3, -56 
    movq %rdi, %rax 
    shrq $3, %rax 
    subq $24, %rsp 
    .cfi_def_cfa_offset 80 
    cmpb $0, 2147450880(%rax) 
    jne  .L1170 
    movq 8(%rbp), %rbx 
    leaq 160(%rbx), %r13 
    movq %r13, %r15 
    shrq $3, %r15 
    cmpb $0, 2147450880(%r15) 
    jne  .L1171 
    leaq 152(%rbx), %r14 
    movq %rsi, %r12 
    movq 160(%rbx), %rsi 
    movq %r14, %rax 
    shrq $3, %rax 
    cmpb $0, 2147450880(%rax) 
    jne  .L1172 
    movq 152(%rbx), %rdx 
    leaq 144(%rbx), %rcx 
    cmpq %rdx, %rsi 
    jb  .L1054 
    cmpq $5000, %rdx 
    jbe  .L1055 
    movl $httpd_err400form, %eax 
    shrq $3, %rax 
    cmpb $0, 2147450880(%rax) 
    jne  .L1173 
    movl $httpd_err400title, %eax 
    movq httpd_err400form(%rip), %r8 
    shrq $3, %rax 
    cmpb $0, 2147450880(%rax) 
    jne  .L1174 


handle_read: 
.LFB20: 
    .cfi_startproc 
    pushq %r12 
    .cfi_def_cfa_offset 16 
    .cfi_offset 12, -16 
    pushq %rbp 
    .cfi_def_cfa_offset 24 
    .cfi_offset 6, -24 
    movq %rsi, %r12 
    pushq %rbx 
    .cfi_def_cfa_offset 32 
    .cfi_offset 3, -32 
    movq 8(%rdi), %rbx 
    movq %rdi, %rbp 
    movq 160(%rbx), %rsi 
    movq 152(%rbx), %rdx 
    cmpq %rdx, %rsi 
    jb  .L384 
    cmpq $5000, %rdx 
    jbe  .L411 

谁能告诉我这些代码如何防止缓冲区溢出?

+0

看看每个选项的文档,这应该有助于你理解在每种情况下正在做什么。 'fstack-protector-strong':https://lwn.net/Articles/584225/。你可以谷歌其他人。 – EkcenierK

+2

鉴于第一和第三个功能是相同的,我会说这里有些奇怪。此外,该函数没有导致缓冲区溢出的访问模式。我会说:**发布整个功能,不只是其中的一部分** – EOF

回答

2

您的handle_read函数不会最终在堆栈中分配任何东西,因此-fstack-protector-strong没有任何功能可以保护,因此此选项没有任何区别。 -zexecstack选项在生成的可执行文件中设置一个标志,告诉操作系统应该允许执行存储在堆栈中的代码。它对生成的程序集没有影响。

只有-fsanitize=address选项具有显示在您已发布的生成装配输出中的效果。它负责出现在第二个生成装配块中的shrq $3, rXX; cmp $0, 2147450880(%rXX); jne .LXXXX序列。这些指令查找函数在“影子内存”表中访问的内存中的每个地址。该表格记录哪些位置已被分配,哪些没有。如果插入的代码检测到程序尝试访问尚未分配的内存位置,则会导致程序退出并显示错误消息。

有关影子内存表如何工作以及AddressSanitizer如何工作的更多详细信息,请阅读作者的Usenix文件AddressSanitizer: A Fast Address Sanity Checker