2010-10-26 45 views
5

找到堆棧溢出功能,我有以下的C應用程序:無法使用GDB

armv5l-linux-gnueabi-gcc -v 
Using built-in specs. 
Target: armv5l-linux-gnueabi 
Configured with: /home/tarjeif/svn/builder/build_armv5l-linux-gnueabi/gcc-4.4.1/gcc-4.4.1/configure --target=armv5l-linux-gnueabi --host=i486-linux-gnu --build=i486-linux-gnu --prefix=/home/tarjeif/svn/builder/build_armv5l-linux-gnueabi/toolchain --with-sysroot=/home/tarjeif/svn/builder/build_armv5l-linux-gnueabi/toolchain --with-headers=/home/tarjeif/svn/builder/build_armv5l-linux-gnueabi/toolchain/include --enable-languages=c,c++ --with-gmp=/home/tarjeif/svn/builder/build_armv5l-linux-gnueabi/gmp-5.0.0/gmp-host-install --with-mpfr=/home/tarjeif/svn/builder/build_armv5l-linux-gnueabi/mpfr-2.4.2/mpfr-host-install --disable-nls --disable-libgcj --disable-libmudflap --disable-libssp --disable-libgomp --enable-checking=release --with-system-zlib --with-arch=armv5t --with-gnu-as --with-gnu-ld --enable-shared --enable-symvers=gnu --enable-__cxa_atexit --disable-nls --without-fp --enable-threads 
Thread model: posix 
gcc version 4.4.1 (GCC) 

調用像這樣:

#include <stdio.h> 

void smash() 
{ 
    int i; 
    char buffer[16]; 
    for(i = 0; i < 17; i++) // <-- exceeds the limit of the buffer 
    { 
     buffer[i] = i; 
    } 
} 

int main() 
{ 
    printf("Starting\n"); 
    smash(); 
    return 0; 
} 

我用gcc以下版本的交叉編譯

armv5l-linux-gnueabi-gcc -ggdb3 -fstack-protector-all -O0 test.c 

當在目標上運行時,它輸出:

Starting 
*** stack smashing detected ***: ./a.out terminated 
Aborted (core dumped) 

我加載在gdb所產生的核心轉儲,得到以下回溯:

GNU gdb (GDB) 7.0.1 
Copyright (C) 2009 Free Software Foundation, Inc. 
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> 
This is free software: you are free to change and redistribute it. 
There is NO WARRANTY, to the extent permitted by law. Type "show copying" 
and "show warranty" for details. 
This GDB was configured as "--host=i486-linux-gnu --target=armv5l-linux-gnueabi". 
For bug reporting instructions, please see: 
<http://www.gnu.org/software/gdb/bugs/>... 
Reading symbols from /home/andersn/workspace/stacktest/a.out...done. 
Reading symbols from /home/andersn/workspace/stacktest/linux/toolchain/lib/libc.so.6...done. 
Loaded symbols for /home/andersn/workspace/stacktest/linux/toolchain/lib/libc.so.6 
Reading symbols from /home/andersn/workspace/stacktest/linux/toolchain/lib/ld-linux.so.3...done. 
Loaded symbols for /home/andersn/workspace/stacktest/linux/toolchain/lib/ld-linux.so.3 
Reading symbols from /home/andersn/workspace/stacktest/linux/toolchain /lib/libgcc_s.so.1...done. 
Loaded symbols for /home/andersn/workspace/stacktest/linux/toolchain/lib/libgcc_s.so.1 
Core was generated by `./a.out'. 
Program terminated with signal 6, Aborted. 
#0 0x40052d4c in *__GI_raise (sig=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:67 
67 ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory. 
    in ../nptl/sysdeps/unix/sysv/linux/raise.c 
(gdb) bt 
#0 0x40052d4c in *__GI_raise (sig=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:67 
#1 0x40054244 in *__GI_abort() at abort.c:92 
#2 0x40054244 in *__GI_abort() at abort.c:92 
#3 0x40054244 in *__GI_abort() at abort.c:92 
#4 0x40054244 in *__GI_abort() at abort.c:92 
#5 0x40054244 in *__GI_abort() at abort.c:92 
#6 0x40054244 in *__GI_abort() at abort.c:92 
... and so on ... 

現在的問題: 我完全無法找到導致堆棧GDB砸即使函數smash()函數不會覆蓋堆棧的任何結構數據,只會覆蓋堆棧保護器本身。我該怎麼辦?

+1

我認爲你的「等」可能已經省略了一些重要的信息。是__GI_abort真的是堆棧的底部? – SoapBox 2010-10-26 14:58:59

+0

我試着繼續GDB輸出,並在我放棄之前達到了#11087 ....所有相同的幀。 – anorm 2010-10-26 15:01:46

+0

你明確地破壞了堆棧 - 不要指望核心文件有整齊的鏈接調用框架然後:) – 2010-10-26 15:25:00

回答

8

問題是,編譯你的目標libc.so.6的GCC版本有問題,並且沒有爲__GI_raise發出正確的展開描述符。使用不正確的展開描述符時,GDB會在展開堆棧時進入循環。

您可以

readelf -wf /home/andersn/workspace/stacktest/linux/toolchain/lib/libc.so.6 

檢查開卷描述我想你會在GDB從任何程序調用中斷,例如得到完全相同的結果

#include <stdlib.h> 
void foo() { abort(); } 
int main() { foo(); return 0; } 

不幸的是,沒有比試圖建立GCC的新版本,然後重建整個「世界」與它什麼可以做,其他。

+0

是的,應該是這樣,簡而言之。但是,用新編譯器重新編譯libc.so可能就足夠了。 – user434507 2010-10-27 03:07:44

+0

剛剛重建libc.so.6可能還不夠:畢竟,不能保證foo()會得到正確的「舊」GCC展開描述符。 – 2010-10-27 03:55:18

0

您是否嘗試解決此投訴:「../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.」以查看實際能否解決符號會有所幫助?

+0

不,我沒有,但GDB不遺漏給定位置的符號信息,只有列表的源代碼文件。然而,我會嘗試你的建議...謝謝 – anorm 2010-10-26 15:00:19

+0

嗯,我試過這個沒有運氣。 GDB在raise.c中顯示了源代碼行,但回溯仍然是錯誤的。 – anorm 2010-10-26 15:06:23

2

即使使用-fstack-protector-all(甚至使用-Wstack-protector來警告未受保護的幀的函數),GDB也不能總是發現被搗毀的堆棧發生了什麼。 Example

在這些情況下,堆棧保護器已經完成了它的工作(殺死了一個行爲異常的應用程序),但還沒有完成調試器的任何好處。 (典型的例子是堆棧粉碎,其中寫入發生的次數足以跳過金絲雀。)在這些情況下,可能有必要通過斷點對代碼進行二進制搜索以縮小代碼的哪個區域造成的結果粉碎,然後通過粉碎單步驟,看看它是如何發生的。