| Zeile 50: | Zeile 50: | ||
An der Speicherstelle [ESP] befindet sich somit der alte EIP-Wert, an [ESP + 4] der alte CS-Wert und so weiter. Es ergibt sich also folgendes Bild für den Stackframe, zu dem Zeitpunkt, wenn die CPU sich bei dem Label ''interrupt_stub'' befindet: | An der Speicherstelle [ESP] befindet sich somit der alte EIP-Wert, an [ESP + 4] der alte CS-Wert und so weiter. Es ergibt sich also folgendes Bild für den Stackframe, zu dem Zeitpunkt, wenn die CPU sich bei dem Label ''interrupt_stub'' befindet: | ||
| − | + | (Erinnerung: Der Stack wächst nach unten, also in Richtung der niedrigen Adressen) | |
| − | : | + | {| {{Prettytable}} |
| − | + | ! Wert || Kommentar | |
| − | + | |- | |
| − | | USER SS | + | | : || hohe Adressen |
| − | + | |- | |
| − | | USER ESP | + | | USER SS || nur bei Interrupt in Ring 1-3 |
| − | + | |- | |
| − | | EFLAGS | + | | USER ESP || nur bei Interrupt in Ring 1-3 |
| − | + | |- | |
| − | | CS | + | | EFLAGS || |
| − | + | |- | |
| − | | EIP | + | | CS || |
| − | + | |- | |
| − | : | + | | EIP || ESP zeigt hier hin |
| − | + | |- | |
| + | | : || niedrige Adressen | ||
| + | |- | ||
| + | |} | ||
Diese 3 bzw. 5 Werte, die sich auf dem Stack befinden müssen wir also nicht noch einmal sichern. Allerdings müssen wir noch die General Purpose Register und die 4 Segment Register retten. Dies geschieht mit dem ''pusha'', sowie den 4 ''push''s. Zum Schluss werden mittels ''pop'' und ''popa'' die alten Werte dieser Register wiederhergestellt, bevor zum Aufrufer zurückgesprungen wird. Dies ist notwendig, um unsere weiter oben formulierte Forderung, dass wir den Zustand des Programms nicht ändern, zu erfüllen. Diese pauschale Sicherung aller Register erlaubt es uns im folgenden Code frei über alle Register zu verfügen. | Diese 3 bzw. 5 Werte, die sich auf dem Stack befinden müssen wir also nicht noch einmal sichern. Allerdings müssen wir noch die General Purpose Register und die 4 Segment Register retten. Dies geschieht mit dem ''pusha'', sowie den 4 ''push''s. Zum Schluss werden mittels ''pop'' und ''popa'' die alten Werte dieser Register wiederhergestellt, bevor zum Aufrufer zurückgesprungen wird. Dies ist notwendig, um unsere weiter oben formulierte Forderung, dass wir den Zustand des Programms nicht ändern, zu erfüllen. Diese pauschale Sicherung aller Register erlaubt es uns im folgenden Code frei über alle Register zu verfügen. | ||
| Zeile 74: | Zeile 77: | ||
Der Stack-Frame sieht nach dem ''push gs'' wie folgt aus: | Der Stack-Frame sieht nach dem ''push gs'' wie folgt aus: | ||
| − | + | (Erinnerung: Der Stack wächst nach unten, also in Richtung der niedrigen Adressen) | |
| − | : | + | {| {{Prettytable}} |
| − | + | ! Wert || Kommentar | |
| − | + | |- | |
| − | | USER SS | + | | : || hohe Adressen |
| − | + | |- | |
| − | | USER ESP | + | | USER SS || nur bei Interrupt in Ring 1-3 |
| − | + | |- | |
| − | | EFLAGS | + | | USER ESP || nur bei Interrupt in Ring 1-3 |
| − | + | |- | |
| − | | CS | + | | EFLAGS || |
| − | + | |- | |
| − | | EIP | + | | CS || |
| − | + | |- | |
| − | | EAX | + | | EIP || |
| − | + | |- | |
| − | | ECX | + | | EAX || |
| − | + | |- | |
| − | | EDX | + | | ECX || |
| − | + | |- | |
| − | | EBX | + | | EDX || |
| − | + | |- | |
| − | | ESP | + | | EBX || |
| − | + | |- | |
| − | | EBP | + | | ESP || das ESP, das in der obigen Tabelle auf EIP gezeigt hat |
| − | + | |- | |
| − | | ESI | + | | EBP || |
| − | + | |- | |
| − | | EDI | + | | ESI || |
| − | + | |- | |
| − | | DS | + | | EDI || |
| − | + | |- | |
| − | | ES | + | | DS || |
| − | + | |- | |
| − | | FS | + | | ES || |
| − | + | |- | |
| − | | GS | + | | FS || |
| − | + | |- | |
| − | : | + | | GS || ESP zeigt hier hin |
| − | + | |- | |
| + | | : || niedrige Adressen | ||
| + | |- | ||
| + | |} | ||
=== Kernel-Bedingungen === | === Kernel-Bedingungen === | ||