以下正文開始
我一直很好奇 check stack 有沒爆掉是怎麼做的, 一位朋友為我解惑, 就在 stack 底端塞個值, 檢查他就好了, 我頓時茅塞頓開, 原來如此。
不過讓我們看看有支援 stack protector 的 c compiler, 以下是 gcc 的 fstack-protector 實作。
gcc -m32 -g -static -fno-stack-protector stack_pro.c -o stack_pro.nosp gcc -m32 -g -static -fstack-protector stack_pro.c -o stack_pro.sp
L6, 7, 16, 17 就是這些魔法施行的地方。string[10] 從 0x12(%esp) 開始, 長度 10, 所以這個魔法標記紀錄在 0x1c(%esp), 0x1c-0x12 = 0xa, 在做完 memcpy (為什麼 strcpy 變成 memcpy 就不用管他了) 之後, 再來檢查 0x1c(%esp) 值是不是之前保存 (從 %gs:0x14 得來的) 的即可, 如果不一樣, 就去執行 __stack_chk_fail。
在我測試時, 這個值是:
%gs:0x14: 0x944bc400
不過似乎會一直變化, 每次執行都不一樣, 不是固定值。
這是把 0x1c(%esp) dump 出來, 本來應該要是 0x00 0xc4 0x4b 0x94 (little endian), 可是因為我們把 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" 覆蓋超過了 string[10], 所以就變成 0x41 0x41 0x41 0x41 ...
(gdb) x/32xb 0xffffd39c
0xffffd39c: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41
0xffffd3a4: 0x41 0x41 0x41 0x41 0x41 0x41 0x41 0x41
這是執行結果, 沒有 -fstack-protector 的版本, 自然是發出 Segmentation fault。
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.
NOTE: In Ubuntu 6.10 and later versions this option is enabled by
default for C, C++, ObjC, ObjC++, if neither -fno-stack-protector
nor -nostdlib are found.
至於 man page 的 8 byte 我怎麼試都觀察不到, 就沒辦法分享這段的意思了。stack overflow 有篇類似的, 可惜我找不到了。
有人認為 c++ 的邪惡在於 c++ compiler 產生太多我們沒寫的程式碼, 類似於這樣的行為。c++ exception 也是用類似的方似塞了不少程式碼。
沒有留言:
張貼留言
使用 google 的 reCAPTCHA 驗證碼, 總算可以輕鬆留言了。
我實在受不了 spam 了, 又不想讓大家的眼睛花掉, 只好放棄匿名留言。這是沒辦法中的辦法了。留言的朋友需要有 google 帳號。