FromNandの日記

自分的備忘録

elf32の実行形式の「lea 0x4(%esp), %ecx」とは何なのか?

elf32では、main関数の最初にespを16bitの境界にアライメントする。
これは、おそらくSSE命令などのペナルティを避けるためだと考えられる。
しかし、単に「andl $0xfffffff0, %esp」などとすれば、スタートアップ関数直後のespの値が失われてしまう。
これは、mainが終了した時にまずいことが起こるため(スタックがずれてしまう可能性が非常に高い)、ecxにespの値を退避しておく必要がある。
ちなみに、なぜかelf64では同等のコードは生成されない。

(追記)
配列の範囲を超えてデータを書き込むことによるバッファオーバーフロー攻撃を行う際には、このコードが邪魔になることがある。
というのも、espのコピーを保存したecxの値はスタックにpushされて保管されるため、バッファオーバーフロー攻撃によってこれが破壊されるからである。
ecxの値が破壊されてしまうと、mainの終了間際にespの値が復元できなくなるため、プログラムがクラッシュする。
これを避けるためには、逆アセンブルしたコードを読んでecxの部分をピンポイントで避ける必要があるが、これは本当に面倒である。
もしかしたら、このコードはセキュリティを意識したものでもあるのかもしれない。(でも、64bitでは生成されないんだよなぁ...)
elf64ではこのようなコードは生成されないため、脳死でリターンアドレスを書き換えるだけで攻撃が成功する。