2010-10-26 15 views
5

ho la seguente applicazione C:Impossibile trovare la funzione smashing pila utilizzando GDB

#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; 
} 

I cross-compilati utilizzando la seguente versione di gcc:

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) 

invocato in questo modo:

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

Quando viene eseguito su destinazione, emette:

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

ho caricare il core dump conseguente gdb cedendo il seguente backtrace:

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 ... 

Ora, la domanda: Sono totalmente incapace di trovare la funzione che causa lo stack smashing da GDB, anche se la funzione smash() non sovrascrive alcun dato strutturale dello stack, solo la protezione dello stack stessa. Cosa dovrei fare?

+1

Penso che il tuo "e così via" possa aver omesso alcune importanti informazioni. __GI_abort è davvero il fondo della pila? – SoapBox

+0

Ho provato a continuare l'uscita GDB e ho raggiunto # 11087 prima di rinunciare .... Tutti i fotogrammi uguali. – anorm

+0

Stai esplicitamente corrompendo lo stack - non aspettarti che il file core abbia cornici di chiamata ben ordinate :) :) –

risposta

8

Il problema è che la versione di GCC che ha compilato il target libc.so.6 è errata e non ha emesso i descrittori di svolgimento per __GI_raise. Con descrittori di svolgimento non corretti, GDB entra in un ciclo mentre svolge lo stack.

È possibile esaminare i descrittori di rilassarsi con

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

mi aspetto che si otterrà esattamente lo stesso risultato in GDB da qualsiasi programma chiamando interruzione, per esempio

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

Purtroppo, non c'è molto che si può fare, altro che cercare di costruire nuova versione di GCC, e poi ricostruire l'intero "mondo" con essa.

+0

Sì, dovrebbe essere, in poche parole. Tuttavia, potrebbe essere sufficiente ricostruire libc.so con un nuovo compilatore. – user434507

+0

Ricostruire solo libc.so.6 può non essere sufficiente: dopo tutto, non v'è alcuna garanzia che foo() otterrà corretta descrittore di rilassarsi con il "vecchio" GCC sia. –

0

Hai provato a risolvere questo reclamo: "../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory." per vedere se effettivamente riuscire a risolvere i simboli potrebbe essere d'aiuto?

+0

No io non ho, ma GDB non manca le informazioni simbolo alla posizione indicata, solo il file di codice sorgente per la quotazione. Eppure, ci proverò il suo suggerimento ... Grazie – anorm

+0

Beh, ho provato questo senza fortuna. GDB ha mostrato la riga sorgente in raise.c ma il backtrace è ancora corrotto. – anorm

2

Non è il caso che GDB possa sempre calcolare cosa è successo a uno stack distrutto anche con -fstack-protector-all (e anche con -Wstack-protector per avvisare sulle funzioni con frame che non erano protetti). Example.

In questi casi il dispositivo di protezione dello stack ha svolto il proprio lavoro (ha ucciso un'applicazione non funzionante) ma non ha apportato alcun privilegio al debugger. (L'esempio classico è uno smash stack in cui si è verificata una scrittura con un passo abbastanza grande da saltare il canarino.) In questi casi può essere necessario effettuare una ricerca binaria attraverso il codice tramite punti di interruzione per restringere quale regione del codice sta causando il tormentone, poi il singolo passaggio attraverso lo scontro per vedere come è successo.

Problemi correlati