Wie man die GOT-Tabelle und die PLT-Tabelle genau versteht

WBOY
Freigeben: 2023-05-14 12:13:14
nach vorne
1418 Leute haben es durchsucht

0x01 Vorwort

Betriebssysteme verwenden normalerweise dynamische Verknüpfungen, um die Effizienz des Programmbetriebs zu verbessern. Bei der dynamischen Verknüpfung werden nicht alle Funktionen in der Linkbibliothek beim Laden des Programms geladen, sondern bei Bedarf, wenn das Programm ausgeführt wird Das Programm wird ins Leben geladen. Dieses Design kann den reibungslosen Programmbetrieb verbessern und den Speicherplatz reduzieren. Darüber hinaus erlauben moderne Betriebssysteme keine Änderung von Codesegmenten, sondern nur von Datensegmenten, sodass die GOT-Tabelle und die PLT-Tabelle entstanden sind.

0x02 Eine vorläufige Untersuchung der GOT-Tabelle und der PLT-Tabelle

Werfen wir einen kurzen Blick auf ein Beispiel

Wie man die GOT-Tabelle und die PLT-Tabelle genau versteht

Wir folgen scanf@plt

Wie man die GOT-Tabelle und die PLT-Tabelle genau versteht

und werden feststellen, dass es drei Codezeilen gibt

jmp 一个地址
push 一个值到栈里面
jmp 一个地址
Nach dem Login kopieren

Schauen Sie sich einfach den Namen der Funktion an. Da wir wissen, dass dies die PLT-Tabelle der Scanf-Funktion ist, wollen wir nicht überstürzen, wofür PLT verwendet wird. Schauen wir uns zunächst an, wohin der erste JMP springt .

Wie man die GOT-Tabelle und die PLT-Tabelle genau versteht

Tatsächlich ist dies die got-Tabelle der Funktion, die der plt-Tabelle entspricht. Wir werden feststellen, dass der Wert 0x201020 die Adresse des Stapelbefehls ist und die anderen Stellen 0 sind. Zu diesem Zeitpunkt haben wir Ich möchte fragen:

1. Habe einen Tisch und einen Plt-Tisch. Was ist der Sinn, warum das ganze Herumspringen?

2. Welche Verbindung besteht zwischen der got-Tabelle und der plt-Tabelle?

Wenn Sie also Fragen haben, lesen Sie zuerst die Antwort und bestätigen Sie sie dann. Wir müssen verstehen, dass Betriebssysteme normalerweise dynamische Verknüpfungen verwenden, um die Effizienz des Programmbetriebs zu verbessern, und nicht in das Codesegment zurückgeschrieben werden können.

Im obigen Beispiel können wir sehen, dass scanf -> scanf's plt table -> scanf's got table Der Wert der got-Tabelle ist uns im Moment egal ein Gedanke, der aus der got-Tabelle abgerufen werden kann. Finden Sie die echte Scanf-Funktion, die das Programm laden und ausführen kann.

Nachdem wir darüber nachgedacht haben, wird dies zu einem indirekten Adressierungsprozess

Wie man die GOT-Tabelle und die PLT-Tabelle genau versteht

Wir rufen den kleinen Codeabschnitt auf, der das Datensegment erhält, um die Funktionsadresse namens PLT (Procedure Linkage Table) zu speichern. Prozessverknüpfungstabellenspeicherung Das Datensegment der Funktionsadresse wird als globale Offset-Tabelle GOT (Global Offset Table) bezeichnet. Nachdem wir einen solchen Gedanken formuliert haben, können wir die darin enthaltenen Details sorgfältig verstehen.

0x03 Lassen Sie uns die GOT-Tabelle und die PLT-Tabelle noch einmal erkunden. Nachdem wir einen solchen allgemeinen Prozess verstanden haben, schauen wir uns Schritt für Schritt an, wie er heißt. Es gibt mehrere Zweifel, die gelöst werden müssen:

1 über die got-Tabelle? Kennen Sie die tatsächliche Adresse der Scanf-Funktion?

2. Wie ist die Struktur von got table und plt table? Schauen wir uns zunächst die PLT-Tabelle an. Wir haben gerade festgestellt, dass die dritte Codezeile in der Tabelle „scanf@plt“ eine Adresse von jmp ist. Dies ist tatsächlich der Anfang einer PLT-Tabelle (plt[0]). Es funktioniert: Auf

push got[1]
jmp **got[2]
Nach dem Login kopieren
folgt die plt-Tabelle für jede Funktion. Schauen wir uns zu diesem Zeitpunkt noch einmal diese mysteriöse GOT-Tabelle an

Wie man die GOT-Tabelle und die PLT-Tabelle genau versteht

Mit Ausnahme dieser beiden (die Adresse des Push 0xn der Funktionen printf und scanf, die die Adresse des zweiten Codes der entsprechenden plt-Tabelle ist), das andere got[ 1], got[2] ist 0, also was zeigt die plt-Tabelle auf die got-Tabelle, die 0 ist? Da wir mit einer Bedingung in Verzug geraten sind, erlauben moderne Betriebssysteme keine Änderung von Codesegmenten, sondern nur von Datensegmenten. Ein professionellerer Name sollte Laufzeitverschiebung sein. Wenn wir das Programm ausführen, haben sich unsere vorherige Adresse und der gespeicherte Inhalt geändert. Speichern wir vorher den Inhalt während des Links und führen Sie einen Vergleich durch. Führen Sie das Programm aus und setzen Sie einen Haltepunkt bei scanf Es kann festgestellt werden, dass sich die scanf@plt-Tabelle zu diesem Zeitpunkt geändert hat. Überprüfen Sie den Inhalt in got[4]

Es ist immer noch die Adresse von Push 0x1 und fahren Sie mit dem Debuggen fort wurde geändertWie man die GOT-Tabelle und die PLT-Tabelle genau versteht

Jetzt möchte ich fragen, wo ist das? Wie man die GOT-Tabelle und die PLT-Tabelle genau versteht

Wie man die GOT-Tabelle und die PLT-Tabelle genau versteht

Dann rufen Sie<_dl_fixup> in got[2] auf, um die Adresse in got[3];

zu ändern

那么问题就来了,刚才got[2]处不是0吗,怎么现在又是这个(_dl_runtime_resolve)?这就是运行时重定位。

其实got表的前三项是:

got[0]:address of .dynamic section 也就是本ELF动态段(.dynamic段)的装载地址
got[1]:address of link_map object( 编译时填充0)也就是本ELF的link_map数据结构描述符地址,作用:link_map结构,结合.rel.plt段的偏移量,才能真正找到该elf的.rel.plt
got[2]:address of _dl_runtime_resolve function (编译时填充为0) 也就是_dl_runtime_resolve函数的地址,来得到真正的函数地址,回写到对应的got表位置中。
Nach dem Login kopieren

那么此刻,got表怎么知道scanf函数的真实地址?

这个问题已经解决了。我们可以看一下其中的装载过程:

Wie man die GOT-Tabelle und die PLT-Tabelle genau versteht

Wie man die GOT-Tabelle und die PLT-Tabelle genau versteht

说到这个,可以看到在_dl_runtimw_resolve之前和之后,会将真正的函数地址,也就是glibc运行库中的函数的地址,回写到代码段,就是got[n](n>=3)中。也就是说在函数第一次调用时,才通过连接器动态解析并加载到.got.plt中,而这个过程称之为延时加载或者惰性加载。

到这里,也要接近尾声了,当第二次调用同一个函数的时候,就不会与第一次一样那么麻烦了,因为got[n]中已经有了真实地址,直接jmp该地址即可。

Das obige ist der detaillierte Inhalt vonWie man die GOT-Tabelle und die PLT-Tabelle genau versteht. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:yisu.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage