補遺C. ROPを次に学ぶための地図
C.1 ガジェット
ROPでは、実行可能領域にすでにある「短い命令列 + ret」をガジェットとして扱う。スタック先頭に次のガジェットのアドレスがあれば、現在のretが次の命令列へ移る。
pop rdi
retこの二命令なら、スタック先頭の値をRDIへ入れ、その次の値をRIPへ入れる。本リポジトリの仮想レジスタ演習は、実際の戻り先を壊さずに状態遷移を観察する。
C.2 動的リンクとGOT/PLT
外部関数の呼び出しでは、PLTの入口とGOTの解決済みアドレス表が関与する。RELROはこの表の書き換え可能期間を制限する。これらは「戻り先の上書き」とは別の制御データの話であるため、本編では深入りしない。
C.3 本編とROPの接続点
retはスタック先頭の値をRIPへ入れる。popはスタック先頭の値をレジスタへ入れる。- 呼び出し規約が関数の引数レジスタを定める。
これらがつながると、スタックを「戻り先の一個の保存場所」から「複数の状態遷移を指定する列」として見られるようになる。