Frage zum Stackpointer



  • Hallo,

    ich lese zur Zeit ein Buch über Buffer Overflows und hätte da eine Frage zum Stack.

    Ich hab ein kleines Prog, das auf dem Stack 512 Byte reserviert, und anschließend den Wert vom esp, sprich Stackpointer ausgibt.

    Jedoch hat der Stackpointer bei jedem Programmaufruf einen anderen Wert, warum ist das so? Die Programme laufen ja in einem virtuellen Adressraum, der Stack beginnt immer an der selben Adresse und ist immer gleich Groß(?), also müsste er ja auch immer an der gleichen Stelle enden, oder?

    In den Listings meines Buches ist das der Fall, nur in der Realität nicht 😕

    Bitte korrigiert mich wenn ich da was falsch verstanden hab 🙂

    Kann mir jemand weiterhelfen?

    mfg Mortl



  • Du solltest angeben in welcher Umgebung dein Programm läuft.

    Unter Windows kannst du dir nie sicher sein das etwas so ist wie es sein sollte.



  • Also ich habe es bisher nur unter Linux(SUSE 10, Kernel 2.6) getestet.

    Habs dann doch mal unter Windows probiert und da geht es einwandfrei 🙄

    Mal ein Beispiel der Stackpointer(unter Linux):

    ESP: 0xbfb85dc8
    ESP: 0xbfab84f8
    ESP: 0xbfbc5608
    ESP: 0xbf97cbb8
    ESP: 0xbf8b4af8
    ESP: 0xbfe01848

    Wie gesagt, nach jedem Programmaufruf ein anderer, und auch noch ein ziemlich großer Unterschied zwischen ihnen.



  • Gerade bei Linux ist die "paralellietät" der Prozesse sehr groß.
    D.h.
    Es ist nicht immer vorhersehbar wann welcher Prozess gerade Speicher belegt.
    Gerade dann wenn er dynamisch angefordert wird.

    Als zwweites spielt die Speicherverwalltung damit rein.
    Der Speicher wir in verschieden großen Blocken angefordert und freigegeben.
    Es gibt verschiedene Methoden dies zu machen.
    Bei der ersten wird der erste Block benutzt der Past.
    Bei der zweiten der Block der am besten Past.

    Dann gibt es noch die "Müllabfuhr".
    Diese wird auch noch unregelmässig aufgerufen.
    a) wenn Zeit ist,
    b) wenn es nötig ist.



  • Ich hab immer gedacht das in jedem Programm der Stack an der (virtuellen) Adresse 0xffffffff beginnt und nach unten wächst und beim Zugriff die Adresse vom OS bzw. der MMU in die physikalische Adresse umgewandelt wird, oder hab ich das falsch verstanden?

    Daher ist es doch IMHO letztentlich egal wie die Daten physikalisch im RAM organisiert sind?

    Außerdem verwendet der Autor in meinem Buch auch Linux und hat bei jedem Programmaufruf denselben Stackpointer, vielleicht wende ich mich mal an ihn 🙂



  • Das der Stack mit -1 initialiesiert wird heist nicht das du das auch sehen kannst.
    Das der im Buch darstellt heist nicht das es wirklich so ist.
    Er kann das so angepasst haben das der Lesen nicht verwirt wird.
    Du weist nicht wirklich wie die Umgebung aussieht die der Autor bgenutzt hat.
    D.h:
    Er hat bestimmt einen eigenen Rechner dafür, auf dem nur Linux mit den System drauf ist.
    Da ist eine Wiederholbarkeit der Daten einfacher.

    ...................



  • Im 2.6er Kernel ist das sog. Address Space Layout Randomization (ASLR) implementiert. Das bedeutet, dass der Stack bei jedem Programmstart an einer anderen zufälligen Stelle positioniert wird. Dadurch soll eben genau das Ausnutzen von Buffer Overflows verhindert/erschwert werden.
    Das gleiche gilt für die libc Funktionen, wodurch somit auch "return into libc" Angriffe erschwert werden.

    ASLR ist meist standardmäßig aktiviert, ausschalten kannst du das Ganze indem du als root folgendes ausführst:

    echo 0 > /proc/sys/kernel/randomize_va_space
    

    Dann sollte sich dein Stack wieder "normal" verhalten..
    Microsoft zieht mit ASLR übrigens in Vista nach.

    MfG



  • Nette gedanken sind das hier. Woher weiß denn der Kernel, wo der Stack beginnt?

    Wenn das der Kernel herausbekommen kann, müsste das ein Treiber auch können, und somit ist das wiederum "einfach"?



  • JayJay schrieb:

    Nette gedanken sind das hier. Woher weiß denn der Kernel, wo der Stack beginnt?

    Weil der kernel deinen Stack erstellt?

    Wenn das der Kernel herausbekommen kann, müsste das ein Treiber auch können, und somit ist das wiederum "einfach"?[/quote]
    Auch nur in einem monolithischen Kernel... aber was willst du damit den sagen? unsicher? Das ist halt nunmal eine Eigenschaft eines monolithischen kernels...



  • rocksteady schrieb:

    Im 2.6er Kernel ist das sog. Address Space Layout Randomization (ASLR) implementiert. Das bedeutet, dass der Stack bei jedem Programmstart an einer anderen zufälligen Stelle positioniert wird. Dadurch soll eben genau das Ausnutzen von Buffer Overflows verhindert/erschwert werden.
    Das gleiche gilt für die libc Funktionen, wodurch somit auch "return into libc" Angriffe erschwert werden.

    ASLR ist meist standardmäßig aktiviert, ausschalten kannst du das Ganze indem du als root folgendes ausführst:

    echo 0 > /proc/sys/kernel/randomize_va_space
    

    Dann sollte sich dein Stack wieder "normal" verhalten..
    Microsoft zieht mit ASLR übrigens in Vista nach.

    MfG

    Ok, genau das wollte ich wissen, danke! 🙂


Anmelden zum Antworten