共有ライブラリ
共有ライブラリ
コンパイラ、OS、ハッキング本などなど色んな本を読んでいると必ず出てくるキーワード、それが共有ライブラリ。避けては通れない共有ライブラリ。なぜならコンパイラ(gcc)は必ずプログラム共有ライブラリを使用しているからだ。C言語でmain関数の中を空にしてもスタートアッププログラムがリンクされる。
標準C libc
Linuxでは/libか/usr/libにインストールされるみたい。 とある環境のプロセスのメモリ情報
cat maps ldd a.out linux-gate.so.1 => (0xb776e000) libc.so.6 => /lib/libc.so.6 (0x49cbd000) /lib/ld-linux.so.2 (0x49c95000)
soフアイルが共有ファイル。やはり必ず使用されているみたい。 ちなみに標準CにはCで実装するには面倒なものをCで実装しているものと、アセンブラで書かれているものがある(システムコールラッパー)。
共有ファイルの仕組み
動的リンク
共有ライブラリはプログラム実行時に動的にリンクされる。ちなみに.interpセクションで指定されたダイナミックリンカ(通称ld.so)がexecveの際にメモリにロードされld.soが共有ライブラリを再帰的にリンクする。
共有ライブラリのシンボル解決
共有ライブラリは各プロセスで共有されて、各プロセスの仮想メモリにはそれぞれ別のアドレスに割り当てられる。さらに共有ライブラリは実行時にリンクされるので実行時までアドレスが決定されない。よってプログラムの実行時には共有ライブラリの参照箇所はシンボル解決が行われていな。なので、実行時にはわかっていない共有ライブラリのアドレスを調べてシンボル解決する仕組みが必要になる。それがGOTとPLT。
GOT
直接共有ライブラリへ参照はせず、GOT領域を使用する。GOTはデータ領域に配置されるので各プロセスが独自に持てる領域。なので各プロセスはここで各々プロセスによって異なる共有ライブラリへの参照を保持する。初期値はその共有ライブラリへのシンボル解決するアドレスへの値が入っていてシンボル解決するとこの各共有ライブラリの関数などに対応するGOT領域にアクセスすれば共有ライブラリに参照ができる。
PLT
PLTは対象の共有ライブラリへ参照するためにGOTに飛ぶ。PLT→GOT→共有ライブラリ。なんで二段階になっているかというと、はじめはシンボル解決するための処理が入るので(コレハ図をみないとわかりにくい)。 アセンブラではしたみたいな感じでかかれてる。
print@PLT