GOTテーブルとPLTテーブルの詳細な知識

プログラムでのGOTGOTテーブルとPLTPLTテーブルの役割は非常に大きいです。以下の説明では、誰もが詳細に確認できることを願っています

説明には非常に単純な例を使用します。コードは次のとおりです。 
図1

ここに写真の説明を書きます

次にコンパイルします

次のように、gdb。/ a.outgdb。/ a.outで直接逆コンパイルし、disasmaindisasmainを介してmainmain関数で逆コンパイルしたコードを表示します。

写真3

ここに写真の説明を書きます

2つの関数が@ pltgets @ pltを取得し、@ pltputs @ pltを配置することを確認できます。これは、PLTPLTテーブル内のデータのアドレスなので、@ plt @ pltが後ろに追加されているのはなぜですか。逆コンパイルのコードのアドレスがPLTPLTテーブルのアドレスであるのはなぜですか?

理由
ユーザーエクスペリエンスとメモリCPU使用率を向上させるために、2つのテーブルがプログラムのコンパイルを支援するために使用されます。1つはPLTPLTテーブルで、もう1つはGOTGOTテーブルです。PLTPLTテーブルは内部関数テーブルと呼ばれ、GOTGOTテーブルはグローバル関数テーブルです。 (動的関数テーブルとも言えます。これは個人的な要求です。)2つのテーブルは対応しています。対応とは何ですか?PLTPLTテーブルのデータはGOTGOTテーブルのアドレスであり、1対1の対応として理解できます、以下に示すように:

写真4

PLTPLTテーブル内の各アイテムのデータ内容は、GOTGOTテーブル内の対応するアイテムのアドレスです。これは修正されています。PLTPLTテーブル内のデータは関数の実際のアドレスではなく、GOTGOTテーブルであることを誰もが知っています。アイテムのアドレスはとても穴が開いています。

実際、@ plt @ pltフラグを使用して関数を入力すると、GOTGOTエントリのデータは関数の最終アドレスであり、PLTPLTテーブルのデータはGOTGOTエントリのアドレスであるため、この関数は実際には一時的な効果です。 、PLTPLTテーブルを介してGOTGOTテーブルにジャンプして、関数の実際のアドレスを取得できます。

その質問が来て、この@ plt @ plt関数がどのようにして生まれたのか、この関数はコンパイルシステムによって追加されました。次に示すように、disas getを使用して内部のコードを確認できます。

写真5

ここに写真の説明を書きます

この関数には3行のコードしかないことがわかります
。1 行目がジャンプし、2行目がスタックにプッシュされ、3行目がジャンプです。説明:  最初の行ジャンプ、その役割はPLTPLTテーブルを介してGOTGOTにジャンプすることです特定の関数の最初の実行前は、この関数のPLTPLTテーブルに対応するGOTGOTテーブルのデータは、@ plt @ plt関数の2行目の命令のアドレスです。図の手順は次のとおりです。

jmpjmp命令はGOTGOTテーブルにジャンプします。GOTGOTテーブル
のデータは0x4004860x400486です。
命令アドレス0x4004860x400486にジャンプし、
push 0x3#実行します。これは
GOTGOT のインデックス番号
です。jmp0x400440 および0x4004400x400440を実行すると、PLT [0] PLT [0]アドレス
PLT [0] PLT [0]の命令がダイナミックリンカーの入り口に入ります。
実際の関数アドレスをGOTGOTテーブルに上書きする関数を実行します。
ここで、いくつか質問します: 
1. PLT [0] PLT [0]以前の考えによると、GOT [0] GOT [0]にジャンプすべきではありませんか? 
2.なぜpushpushプッシュ操作が途中で行われるのですか? 
3.プッシュされたシーケンス番号が0x30x3である理由は、最初は0x00x0であってはならないのですか?

問題
解決問題1

下の写真を見てください。 
写真6

ここに写真の説明を書きます

アドレス0x4004400x400440のデータコンテンツを確認しようとしたところ、問題が見つかりました。0x400440-0x4004500x400440-0x400450の間のデータは完全に不明であり、実際のP​​LT [x] PLT [x]のデータは0x4004500x400450から始まります。ここにのみ@ plt @ pltというサフィックスが付いたアドレスがありますが、disasがコードを見ると、0x4004400x400440から始まります。コードは、x / 5i 0x400440を介して0x4004400x400440で表示できます。 
図7

ここに写真の説明を書きます

#の後ろに1616の16進数が表示されます。一目でGOTGOTテーブルのアドレスを確認できます。objdump-R ./a.outを介してプログラムのGOTGOT関数のアドレスを表示できるので、なぜそれが確かなのですか。 、以下に示すように: 
図8

ここに写真の説明を書きます

ここにいくつかのGOTGOTアドレスがあります。これらはすべて0x601 ... 0x601 ...これらであることがわかりました。したがって、図77もGOTGOTアドレスであると結論付けることができます。その後、関数のGOTGOTアドレスを正式に保存する前に、 PLTPLTテーブルの前にいくつかの処理のためのアイテムがあります。当面は、これらのコードの使用を詳細に分析しませんが、puts @ pltputs @ pltの前の1616バイトもPLTPLTテーブルのコンテンツと見なされることを確認できます。 [0] PLT [0]、前の質問で述べたように、PLT [0] PLT [0]はGOT [0] GOT [0]にまったくジャンプしませんでした。それは、PLT [1]のようではありませんでしたPLT [1]これらはコード命令であるGOTGOTエントリのアドレスを格納しますつまり、PLT [0] PLT [0]は関数であり、この関数の関数はGOT [1] GOT [1] GOT [2] GOT [2]を使用して、関数の公式アドレスをGOTGOTテーブルに正しくバインドします。

ここで問題が再び発生したようです。元々、PLT [1] PLT [1]もGOT [1] GOT [1]にジャンプしましたが、GOT [2] GOT [2]も同じですが、これは2つのデータはPLT [0] PLT [0]によって使用されているようですが、同時にGOT [0] GOT [0]が消えているようです。GOT[0] GOT [0]は、GOT [ 1] GOT [1]およびGOT [2] GOT [2]はPLT [0] PLT [0]によって使用されるため、プログラムの実際の状況は、実際にはPLT [1] PLT [1]からGOT [3] GOT [ 3]、PLT [2] PLT [2]からGOT [4] GOT [4]なので、グラフ44を覆し、新しい処理テーブルを作成しました。

写真9

ここに写真の説明を書きます

そして、plt [0] plt [0]コードが行うことは次のとおりです。ダイナミックリンカーのエントリアドレスはGOT [2] GOT [2]に格納されるため、GOT [1] GOT [1]のデータは次のように使用されます。パラメータ、GOT [2] GOT [2]に対応する関数エントリアドレスにジャンプ、この動的リンカは、関数の実際のアドレスを対応するGOT [x] GOT [x]にバインドします。

これは、PLTPLTテーブルとGOTGOTテーブルです。要約すると、関数を呼び出すときに2つの方法があります。1つはPLTPLTテーブルを使用する方法で、もう1つはGOTGOTテーブルを使用する方法です。これは、PLTPLTテーブルが最終的にGOTGOTテーブルにジャンプし、これは関数の実際のアドレスです。関数を1回実行する前に、GOTGOTテーブルのデータは、@ plt @ plt関数の次の命令のアドレスです(図55を参照)。

質問2

真ん中のスタックプッシュは、PLTPLTに対応するGOTGOTエントリを決定することです。これはPLT [1]-> GOT [3] PLT [1]-> GOT [3]であり、0x30x3はGOTGOTの添え字33です。つまり、スタックの後、PLT [0] PLT [0]にジャンプします。次に、PLT [0] PLT [0]の命令が、スタック番号によって今回操作されるGOTGOTエントリの数を決定します

質問3

最初の問題は解決されたようです。ここで0x30x3をプッシュする理由は、GOT [0] GOT [0]、GOT [1]、GOT [1]、GOT [2] GOT [2]がすべてであるためです追加の用途があります。GOT [3]から始めるにはGOT [3]


————————————————
著作権に関する声明:この記事はCSDNブロガー "77458"のオリジナルの記事であり、CC 4.0 BY-SAの著作権契約に従います。元のソースリンクとこの声明を添付して転載してください。
元のリンク:https://blog.csdn.net/qq_18661257/article/details/54694748

元の記事を25件公開 賞賛された8件 20,000回以上の閲覧

おすすめ

転載: blog.csdn.net/boazheng/article/details/104283063