Frage

Ich habe ein „gefährliches“ Programm in C ++ geschrieben, die hin und her von einem Stack-Frame zu einem anderen springt. Das Ziel ist, springt von der untersten Ebene eines Call-Stack an einen Anrufer zu sein, etwas zu tun, und dann springt wieder nach unten, jedes Mal zwischendurch alle Anrufe zu überspringen.

ich tun dies, indem manuell die Stapelbasisadresse (Einstellung %ebp) zu ändern und auf ein Etikett Adresse zu springen. Es arbeitet völlig mit gcc und icc beide ohne Stapel Korruption überhaupt. Der Tag dieses arbeitete, war ein kühler Tag.

Jetzt nehme ich das gleiche Programm und es in C neu zu schreiben, und es funktioniert nicht. Insbesondere ist es nicht mit gcc v4.0.1 (Mac OS) arbeitet. Nachdem ich zu dem neuen Stapelrahmen (mit dem Stapel Basiszeiger korrekt eingestellt) springen, führen die folgenden Anweisungen, wobei kurz bevor ein Aufruf an fprintf. Der letzte Befehl aufgeführt hier abstürzt, dereferencing NULL:

lea    0x18b8(%ebx), %eax
mov    (%eax), %eax
mov    (%eax), %eax

Ich habe einige Debug getan, und ich habe das manuell durch Setzen des %ebx Register herausgefunden, wenn ich Stack-Frames wechseln (Wert unter Verwendung von I beobachtet, bevor die Funktion in erster Linie zu verlassen), ich den Fehler beheben. Ich habe gelesen, dass dieses Register beschäftigt sich mit "Position unabhängigen Code" in gcc.

Was ist positionsunabhängig Code? Wie funktioniert Position unabhängige Codes arbeiten? Worauf ist dieses Register zeigen?

War es hilfreich?

Lösung

PIC ist Code, der dynamisch verlagert wird, wenn es geladen wird. Code, der nicht-PIC ist hat Sprung und Call-Adressen zu Verbindungszeitpunkt festgelegt. PIC hat eine Tabelle, die alle Orte verweist, wo solche Werte vorhanden sind, ähnlich wie ein DLL.

Wenn das Bild geladen ist, wird der Lader dynamisch diese Werte aktualisieren. Andere Schemata Referenz einen Datenwert, der eine „Basis“ definiert, und die Zieladresse wird durch Ausführen von Berechnungen auf der Basis entschieden. Die Base wird in der Regel wieder vom Lader eingestellt.

Schließlich verwenden andere Systeme verschiedene Trampoline, die auf bekannten relativen Offsets nennen. Die relativen Offsets enthalten Code und / oder Daten, die von einem Lader aktualisiert werden.

Es gibt verschiedene Gründe, warum verschiedene Schemata ausgewählt werden. Einige sind schnell, wenn laufen, aber langsamer zu laden. Einige sind schnell zu laden, haben aber weniger Laufzeitleistung.

Andere Tipps

EBX verweist auf die globale Offset-Tabelle. Siehe diesen Hinweis über PIC auf i386 . Der Link wird erklärt, was PIC ist ein wie EBX verwendet wird.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top