2017-02-08 65 views
0

我可以測試使用strncpy()具有較大源字符串則目標:金絲雀字如何讓gcc檢測緩衝區溢出?

int main() { 
    char *ptr = malloc(12); 
    strcpy(ptr,"hello world!"); 
    return 0; 
} 

-fstack-protector編譯和使用-S選項我:

.file "malloc.c" 
.text 
.globl main 
.type main, @function 
main: 
.LFB2: 
.cfi_startproc 
pushq %rbp 
.cfi_def_cfa_offset 16 
.cfi_offset 6, -16 
movq %rsp, %rbp 
.cfi_def_cfa_register 6 
subq $32, %rsp 
movl %edi, -20(%rbp) 
movq %rsi, -32(%rbp) 
movq %fs:40, %rax 
movq %rax, -8(%rbp) 
xorl %eax, %eax 
movq $0, -16(%rbp) 
movl $12, %edi 
call malloc 
movq %rax, -16(%rbp) 
movq -16(%rbp), %rax 
movabsq $8022916924116329800, %rdx 
movq %rdx, (%rax) 
movl $560229490, 8(%rax) 
movb $0, 12(%rax) 
movl $0, %eax 
movq -8(%rbp), %rcx 
xorq %fs:40, %rcx 
je .L3 
call __stack_chk_fail 
.L3: 
leave 
.cfi_def_cfa 7, 8 
ret 
.cfi_endproc 
.LFE2: 
.size main, .-main 

有人能向我解釋這是如何工作的?爲什麼不是「」字符串的\0也被「金絲雀字」覆蓋?

回答

2

有人可以向我解釋這是如何工作的?

加那利字從fs:40,並儲存在這裏架頂部閱讀:

movq %fs:40, %rax 
movq %rax, -8(%rbp) 

它的返回地址下方,所以如果你的代碼發生緩衝區溢出(這將是下面-8(%rbp))它將首先覆蓋-8(%rbp)位置。這將通過GCC這裏發出ret之前被檢測到:的-8(%rbp)

movq -8(%rbp), %rcx 
xorq %fs:40, %rcx  ; Checks that %fs:40 == -8(%rbp) 
je .L3     ; Ok, return 
call __stack_chk_fail ; Die 

作爲覆蓋內容將很可能是從適當的值(從fs:40安裝)不同。

爲什麼不是加那利語也被hello世界的\ 0覆蓋!?

你的代碼有堆溢出,沒有緩衝區溢出使SSP不禁...

+0

我明白了。謝謝 – Bionix1441

+1

@ Bionix1441如果您有興趣發現錯誤,而不是強化您的應用程序,我衷心推薦[Asan](https://github.com/google/sanitizers/wiki/AddressSanitizer)。它在GCC和Clang中都可用,並且可以發現更大的內存錯誤類別。 – yugr