esp
質問のパート 2 への回答: 作成している syscall によっては、値を(arg 配列として)入れなければならない場合があります。それがシェルコードの終わりであれば、問題ありません。ただし、シェルコードにさらに多くのことがpush
あり、たまたま a を実行し、たまたまシェルコードesp
の残りのどこかを指している場合は、問題が発生する可能性があります (その時点で、独自の命令を上書きすることになるため)。sub $0x99, %esp
簡単な修正は、シェルコードの最初の部分で何かを行うことです。
編集(コメントに応じて)
おそらく私はあなたの質問を誤解しました。あなたが「スタックオーバーフロー」と言ったとき、私はあなたがバッファオーバーフローを意味していると思いました。私が正しく仮定した場合は、読み進めてください。あなたが本当に古典的なスマッシング・ザ・スタックのようなエクスプロイトについて話していると仮定すると(リンク先の写真に基づくとそうです)、nop
スレッドでバッファを埋め、shellcode
最後にリターンポインタを上書きしています. シェルコードは「位置独立コード」です。これは、レジスタやフラグなどの現在の状態に関係なく実行できる一連の命令であることを意味します。
通常、(これは、投稿したリンクがそれを示している方法でもあります)、バッファーにnopを入力し、その後にシェルコードを入力し、最後にnop sledのどこかを指すリターンアドレスを入力します。ret
命令が実行されると、入力されたアドレスがポップインされ%esp
、 4 ずつインクリメントさ%eip
れ%esp
ます (x86 の場合)。問題は、シェルコードに複数の命令がある場合、これが減分push
という副作用を持つことです。それらが十分にあり、シェルコードが最後まである場合 (つまり、リターンアドレスに隣接する場合)、シェルコードを命令で上書きすることになる可能性があります。 %esp
push
だから、実際にあなたの質問に答えるために。いいえ、シェルコードを「そのスタック」から分離する「メカニズム」はありません。これは、シェルコードのスタック自体がないためです。位置に依存しないコードであることを忘れないでください。マシンの状態に関係なく実行できる必要があります。必要なスタック管理は、シェルコード自体で実行する必要があります。そのため、コードに多くのステートメントがあるsub $0x99, %esp
場合は、シェルコードの先頭にa を提案しました。もう 1 つのオプションは、リターン アドレス (指し示すアドレス) とシェルコードpush
の間に十分なスペースがあることを確認することです。%esp-4