
■ of3.exeの例外ハンドラ ■
前回は"of1.exe"と"of3.exe"との動作の違いが何なのかを説明
しました。
具体的には「強制終了されるまでの時間」が異なるという事を
説明し、この「時間の差」がどこからくるのかを説明する為に、
"of1.exe"でのバッファオーバーフローの様子と"of3.exe"での
バッファオーバーフローの様子を比較してみました。
以下に"of1.exe"と"of3.exe"でバッファオーバーフローが発生
した直後のバッファイメージを示します。
●"of1.exe"でコピー処理が行われた直後のスタック領域
スタック領域
┌┌──────┐┐
││ ││
││ ││
││ ││バッファ「b」のサイズ分
バッファb││ │├─┐  ̄
││ ││ │
││ ││ │
││ ││ │コピー
├├──────┤┤ │
││ ││ │
バッファa││ ││ │
││ ││ │
└××××××××│ │
× ×│←┘
┌× ×│
呼出し元 │× ×│
└××××××××┘
│ │
│ │
メッセージを┌├──────┤
表示するプロ││ │
グラムの場所└└──────┘
この時の「×」で囲まれた範囲がバッファオーバーフローの被
害範囲です。
●"of3.exe"でコピー処理が行われた直後のスタック領域
スタック領域
┌┌──────┐┐
││ ││
││ ││
││ ││
││ ││
││ ││
││ ││バッファ「b」のサイズ分
バッファb││ │├─┐  ̄
││ ││ │
││ ││ │
││ ││ │コピー
││ ││ │
││ ││ │
││ ││ │
├├──────┤┤ │
││ ││ │
バッファa││ ││ │
││ ││ │
└××××××××│ │
× ×│ │
┌× ×│ │
呼出し元 │× ×│ │
└× ×│ │
× ×│ │
× ×│ │
× ×│ │
× ×│ │
メッセージを┌× ×│ │
表示するプロ│× ×│←┘
グラムの場所└××××××××┘
"of3.exe"では、バッファbのサイズを大きくしているので、
バッファbのサイズ分だけコピー処理が行われる事により、
「メッセージを表示するプログラムの場所」情報も書き換わっ
てしまいました。
"of1.exe"と"of3.exe"との動作の違いは、この「メッセージを
表示するプログラムの場所」情報が書き換わってしまうのか、
そうでないのか、という違いだけです。
しかし「メッセージを表示するプログラムの場所」情報が書き
換わってしまう事により、この後の動作にある違いが生じる事
になります。
以下に"of3.exe"の動作イメージを示します。
「メッセージを表示するプログラムの場所」情報が書き換わっ
てしまう、という事に注意しながらご覧ください。
┌──────────────────────────┐
│ OF3.EXE │
│ │
└───┬──────────────────────┘
│ スタック領域
│call命令 格納 ┌──────┐
├─────────────────────→│ 呼出し元 │
│ 制御を移行┌────────┐ └──────┘
├────────→│ main関数 │
│ │ │
│ └───┬────┘
│ │
┌──┴──┐
│コピー処理│
└──┬──┘
│×バッファオーバーフロー発生
│ スタック領域
│ ┌──────┐
├───────→│1F 1E 1D 1C │
│ └──────┘
│処理終了 スタック領域
│どこへ戻るか参照┌──────┐
│←───────┤1F 1E 1D 1C │
│ └──────┘
×××××××
×そんな所に×
×実行可能な×
×プログラム×
×ありません×
×××××××
│
┌─────┘★例外発生
│ ┏━━━━━━━━━━━━━━┓
↓ ┃元々は「メッセージを表示する┃
┌──────────┐┃プログラムの場所」情報だが、┃
│ │┃バッファオーバーフローにより┃
│例外ハンドラ動作開始│┃書き換わっている。 ┃
│ │┗━━━━━━━━━━━┳━━┛
└─────┬────┘ ↓
│何を起動するか参照 ┌──────┐
│←─────────────┤FF FF FF FF │
↓ └──────┘
?????
「メッセージを表示するプログラムの場所」情報がバッファオ
ーバーフローにより「FF FF FF FF」という値に書き換わって
しまいました。
そしてその後、例外ハンドラは「FF FF FF FF」という場所に
制御を移行させようとします。
しかし、「FF FF FF FF」という場所には実行可能な命令は存
在しません。
この場合、どうなってしまうのでしょうか?
以前にも説明しましたが、ある場所へ制御を移行させようとし
て、そこに実行可能な命令が存在しない場合、インテルプロセ
ッサは「例外」を発生させます。
これはインテルプロセッサの仕様です。
そしてこの場合も再び例外が発生してしまいます。
以下に、再び例外が発生しているイメージを示します。
先ほどのイメージから1番最後の部分だけ抜粋して示します。
┌─────┘★例外発生
│ ┏━━━━━━━━━━━━━━┓
↓ ┃元々は「メッセージを表示する┃
┌──────────┐┃プログラムの場所」情報だが、┃
│ │┃バッファオーバーフローにより┃
│例外ハンドラ動作開始│┃書き換わっている。 ┃
│ │┗━━━━━━━━━━━┳━━┛
└─────┬────┘ ↓
│何を起動するか参照 ┌──────┐
│←─────────────┤FF FF FF FF │
制御を移行↓ └──────┘
×××××××
×そんな所に×
×実行可能な×
×プログラム×
×ありません×
×××××××
│★例外発生
さて、「そんな所に実行可能なプログラムありません。」とい
う例外が再び発生しました。
例外が発生した場合、インテルプロセッサの仕様により「例外
ハンドラ」というプログラムが動作開始します。
以下に例外ハンドラが動作開始しているイメージを示します。
先ほどのイメージとは1番下の部分が異なるだけです。
┌─────┘★例外発生
│ ┏━━━━━━━━━━━━━━┓
↓ ┃元々は「メッセージを表示する┃
┌──────────┐┃プログラムの場所」情報だが、┃
│ │┃バッファオーバーフローにより┃
│例外ハンドラ動作開始│┃書き換わっている。 ┃
│ │┗━━━━━━━━━━━┳━━┛
└─────┬────┘ ↓
│何を起動するか参照 ┌──────┐
│←─────────────┤FF FF FF FF │
制御を移行↓ └──────┘
×××××××
×そんな所に×
×実行可能な×
×プログラム×
×ありません×
×××××××
│★例外発生
┌─────┴────┐
│ │
│例外ハンドラ動作開始│
│ │
└──────────┘
新たに例外ハンドラが動作開始しています。
ここで動作開始している例外ハンドラは、1番最初に動作開始
した例外ハンドラと「全く同じもの」です。
全く同じものなので、先ほどと同じように「メッセージを表示
するプログラムの場所」へ制御を移行させようとしてしまいま
す。
以下にそのイメージを示します。
先ほどのイメージとは1番下の部分が異なるだけです。
┌─────┘★例外発生
│ ┏━━━━━━━━━━━━━━┓
↓ ┃元々は「メッセージを表示する┃
┌──────────┐┃プログラムの場所」情報だが、┃
│ │┃バッファオーバーフローにより┃
│例外ハンドラ動作開始│┃書き換わっている。 ┃
│ │┗━━━━━━━━━━━┳━━┛
└─────┬────┘ ↓
│何を起動するか参照 ┌──────┐
│←─────────────┤FF FF FF FF │
制御を移行↓ └──┬───┘
××××××× │
×そんな所に× │
×実行可能な× │
×プログラム× │
×ありません× │
××××××× │
│★例外発生 │
┌─────┴────┐ │
│ │ │
│例外ハンドラ動作開始│ │
│ │ │
└─────┬────┘ │
│何を起動するか参照 │
│←────────────────┘
↓
?????
ある場所へ制御を移行させようとして、そこに実行可能な命令
が存在しない場合、インテルプロセッサは例外を発生させます。
そしてこの場合も再び例外が発生してしまいます。
以下に再び例外が発生しているイメージを示します。
先ほどのイメージとは1番下の部分が異なるだけです。
┌─────┘★例外発生
│ ┏━━━━━━━━━━━━━━┓
↓ ┃元々は「メッセージを表示する┃
┌──────────┐┃プログラムの場所」情報だが、┃
│ │┃バッファオーバーフローにより┃
│例外ハンドラ動作開始│┃書き換わっている。 ┃
│ │┗━━━━━━━━━━━┳━━┛
└─────┬────┘ ↓
│何を起動するか参照 ┌──────┐
│←─────────────┤FF FF FF FF │
制御を移行↓ └──┬───┘
××××××× │
×そんな所に× │
×実行可能な× │
×プログラム× │
×ありません× │
××××××× │
│★例外発生 │
┌─────┴────┐ │
│ │ │
│例外ハンドラ動作開始│ │
│ │ │
└─────┬────┘ │
│何を起動するか参照 │
│←────────────────┘
制御を移行↓
×××××××
×そんな所に×
×実行可能な×
×プログラム×
×ありません×
×××××××
│★例外発生
さて、「そんな所に実行可能なプログラムありません。」とい
う例外がまたまた発生しました。
例外が発生した場合、インテルプロセッサの仕様により「例外
ハンドラ」というプログラムが動作開始します。
以下にそのイメージを示します。
先ほどのイメージとは1番下の部分が異なるだけです。
┌─────┘★例外発生
│ ┏━━━━━━━━━━━━━━┓
↓ ┃元々は「メッセージを表示する┃
┌──────────┐┃プログラムの場所」情報だが、┃
│ │┃バッファオーバーフローにより┃
│例外ハンドラ動作開始│┃書き換わっている。 ┃
│ │┗━━━━━━━━━━━┳━━┛
└─────┬────┘ ↓
│何を起動するか参照 ┌──────┐
│←─────────────┤FF FF FF FF │
制御を移行↓ └──┬───┘
××××××× │
×そんな所に× │
×実行可能な× │
×プログラム× │
×ありません× │
××××××× │
│★例外発生 │
┌─────┴────┐ │
│ │ │
│例外ハンドラ動作開始│ │
│ │ │
└─────┬────┘ │
│何を起動するか参照 │
│←────────────────┘
制御を移行↓
×××××××
×そんな所に×
×実行可能な×
×プログラム×
×ありません×
×××××××
│★例外発生
┌─────┴────┐
│ │
│例外ハンドラ動作開始│
│ │
└──────────┘
新たに例外ハンドラが動作開始しています。
ここで動作開始している例外ハンドラは、1番最初に動作開始
した例外ハンドラと「全く同じもの」です。
全く同じものなので、先ほどと同じように「メッセージを表示
するプログラムの場所」へ制御を移行させようとしてしまいま
す。
以下にそのイメージを示します。
先ほどのイメージとは1番下の部分が異なるだけです。
┌─────┘★例外発生
│ ┏━━━━━━━━━━━━━━┓
↓ ┃元々は「メッセージを表示する┃
┌──────────┐┃プログラムの場所」情報だが、┃
│ │┃バッファオーバーフローにより┃
│例外ハンドラ動作開始│┃書き換わっている。 ┃
│ │┗━━━━━━━━━━━┳━━┛
└─────┬────┘ ↓
│何を起動するか参照 ┌──────┐
│←─────────────┤FF FF FF FF │
制御を移行↓ └──┬───┘
××××××× │
×そんな所に× │
×実行可能な× │
×プログラム× │
×ありません× │
××××××× │
│★例外発生 │
┌─────┴────┐ │
│ │ │
│例外ハンドラ動作開始│ │
│ │ │
└─────┬────┘ │
│何を起動するか参照 │
│←────────────────┤
制御を移行↓ │
××××××× │
×そんな所に× │
×実行可能な× │
×プログラム× │
×ありません× │
××××××× │
│★例外発生 │
┌─────┴────┐ │
│ │ │
│例外ハンドラ動作開始│ │
│ │ │
└─────┬────┘ │
│何を起動するか参照 │
│←────────────────┘
↓
?????
ある場所へ制御を移行させようとして、そこに実行可能な命令
が存在しない場合、インテルプロセッサは例外を発生させます。
そしてこの場合も再び例外が発生してしまいます。
以下に再び例外が発生しているイメージを示します。
先ほどのイメージとは1番下の部分が異なるだけです。
┌─────┘★例外発生
│ ┏━━━━━━━━━━━━━━┓
↓ ┃元々は「メッセージを表示する┃
┌──────────┐┃プログラムの場所」情報だが、┃
│ │┃バッファオーバーフローにより┃
│例外ハンドラ動作開始│┃書き換わっている。 ┃
│ │┗━━━━━━━━━━━┳━━┛
└─────┬────┘ ↓
│何を起動するか参照 ┌──────┐
│←─────────────┤FF FF FF FF │
制御を移行↓ └──┬───┘
××××××× │
×そんな所に× │
×実行可能な× │
×プログラム× │
×ありません× │
××××××× │
│★例外発生 │
┌─────┴────┐ │
│ │ │
│例外ハンドラ動作開始│ │
│ │ │
└─────┬────┘ │
│何を起動するか参照 │
│←────────────────┤
制御を移行↓ │
××××××× │
×そんな所に× │
×実行可能な× │
×プログラム× │
×ありません× │
××××××× │
│★例外発生 │
┌─────┴────┐ │
│ │ │
│例外ハンドラ動作開始│ │
│ │ │
└─────┬────┘ │
│何を起動するか参照 │
│←────────────────┘
制御を移行↓
×××××××
×そんな所に×
×実行可能な×
×プログラム×
×ありません×
×××××××
│★例外発生
そろそろ、いいかげんにしろっ、というツッコミが入りそうで
す。(^^;
こうなってしまうと、ぐるぐると同じ処理を繰返してしまうの
です。
そして実は、この「ぐるぐると同じ処理を繰り返してしまう時
間」が"of1.exe"と"of3.exe"との「処理時間の差」になってい
たのです。
しかしここである疑問が浮かびます。
「強制終了されるまでの時間に差がある理由は分かったけど、
このまま永久にぐるぐると処理を続けてしまうの?」
このような疑問を持たれた方、ごもっともです。
実は永遠にこの処理を繰り返すわけではありません。
やはり最後には歯止めをかける人がいるのです。
それは誰なのでしょうか?
続きは次回に説明します。