2012-04-06 19 views
3

Ist es möglich, einen üblichen Code Call Stack in C/C++ zu beschädigen? Ich meine nicht eine Art von Hack oder etwas, nur ein Versehen Fehler oder etwas, aber nicht zufällig, so dass es jedes Mal beschädigt. Jemand sagte mir, dass ein Ex-Kollege es geschafft hat, aber ich glaube nicht, dass es möglich ist. Hat jemand eine solche Erfahrung?C/C++ - Code, der den Aufrufstack beschädigt

+0

Es ist sehr einfach, Call-Stack in C/C++ zu beschädigen. Das ist der Grund, warum viele Leute sie hassen. – iammilind

Antwort

6

Ja, einfach. Eines der sehr häufigen Probleme in der Tat. Bedenken Sie:

void foo() 
{ 
    int i; 
    int *p = &i; 
    p -= 5; // now point somewhere god knows where, generally undefined behavior 
    *p = 0; // boom, on different compilers will end up with various bad things, 
     // including potentially trashing the call stack 
} 

Viele Fälle von einer Out-of-Grenzen Zugriff eines lokalen Array/Puffer mit Trashed Stapel landen.

6

Ja. Auf vielen Plattformen werden lokale Variablen zusammen mit dem Aufruf-Stack gespeichert. in diesem Fall außerhalb eines lokalen Array schreiben eine sehr einfache Art und Weise zu verderben:

void evil() { 
    int array[1]; 
    std::fill(array, array+1000000, 0); 
    return; // BOOM! 
} 

Mehr auf subtile Weise, einen Verweis auf eine lokale Variable Rückkehr könnte korrupt der Stapel von einer Funktion, die später genannt:

int & evil() { 
    int x; 
    return x; 
} 
void good(int & x) { 
    x = 0; 
    return; // BOOM! 
} 
void innocent() { 
    good(evil()); 
} 

Beachten Sie, dass keine dieser (und tatsächlich noch etwas, das den Stapel beschädigen könnte) legal sind; aber der Compiler muss sie nicht diagnostizieren. Zum Glück werden die meisten Compiler diese Fehler erkennen, solange Sie die entsprechenden Warnungen aktivieren.

+0

Und eine c-Variante mein sein als Linker findet doppelt schlecht (double a); ... file1.h 'Doppel Übel (Doppel a);' file1.c #include "file1.h" Doppel Übel (Doppel a) {return a * 5;} ' main.c #include 'Doppel Übel (void); // Deklaration only' int main (void) { printf ("% Das Ergebnis ist f, \ n", übel());// BOOM Rückgabe 0; } –