ローダ

ローダ

執筆済 コンピュータ

実行ファイルをメモリに載せ、実行を開始させる。 OS の一部。

手順#

  1. execve システムコールが呼ばれる
  2. ヘッダを読み、形式とアーキテクチャを確認する
  3. セグメントを**仮想アドレス空間に対応づける**
  4. .bss をゼロで埋める
  5. スタックを用意し、引数と環境変数を積む
  6. 動的リンカを起動して共有ライブラリを解決する
  7. エントリポイントにジャンプする

実際には読み込まない#

「メモリに載せる」と言うが、 実際にはファイルをマップするだけで内容は読まない。

mmap でページテーブルに対応関係を登録し、 そのページに初めて触ったときの ページフォルトで読み込む(デマンドページング)。

  • 起動が速い(使う部分だけ読む)
  • 同じ実行ファイルの複数プロセスが .text の物理ページを共有できる

ASLR#

セグメントの配置アドレスを実行のたびに乱数で変える。

攻撃者が「この関数はこのアドレスにある」と 決め打ちできなくなるので、 バッファオーバーフローからの攻撃が難しくなる。

これに対応するため、実行ファイルは どこに置かれても動く形(PIE、位置独立実行形式)で 作られるようになっている。

参考文献#

  • Randal E. Bryant, David R. O’Hallaron. Computer Systems: A Programmer’s Perspective, 3rd ed. Pearson, 2016. https://csapp.cs.cmu.edu/
  • John R. Levine. Linkers and Loaders. Morgan Kaufmann, 1999.
  • Abhishek Bhattacharjee, Daniel Lustig. Architectural and Operating System Support for Virtual Memory. Morgan & Claypool, 2017. https://doi.org/10.1007/978-3-031-01757-5
ノート一覧を閉じる