Seasons.NET

ちょっとした技術ブログです

MinGWでのおもしろい挙動。

id:fkmさんの
http://d.hatena.ne.jp/fkm/20071116
がおもしろかったので、調べてみました。

1)ですが、
これは、deleteしたメモリは、あくまでヒープのエリアなので、deleteしたからと言って
書き込んだらエラーになるということはないです。
例えば、
a = new int;
delete a
a = new int;
とした場合、aには、連続して同じ値が入ります。もし、deleteを忘れたら、リークしているので、
aには、それぞれ別の値が入ります。
なのでプログラムは、落ちません。
2)がおもしろいんですが、
MinGWで int a[2]を宣言した時、

コンパイラの方ではかれるコードが、
movl $0x0,0xfffffff8(%bp)
movl $0x0,0xfffffffc(%ebp)
ってかんじで、ループしないで初期化してます。
なので、
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
a[3] = リターンアドレス
a[4] = なんか入ってるけど重要じゃない。
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
a[4]を書き換えても何もおきません。
試しに、a[3]を書き換えるとリターンできずにプログラムが落ちます。

んで、int a[3]で宣言すると、
esp - 18してスタック領域を初期化するので
仮に a[4],a[5]してもびくともしないのです。
3)は、不定な値のポインタを操作するので、そりゃ落ちます。
うまくヒープエリアをさせばいいけど、書き換えた時にそこを利用している
アプリで何も不具合がおきなければいいですがw

これは、MinGWとOllyDbgとか、objdumpとかで調べました。

ちなみにこの研究 = ウィルスに該当するプログラムという研究じゃないのであしからず。