分かりやす〜い
コンピュータ技術情報

TOPに戻る
▼Processor
バッファオーバーフロー
┣ 異常な動作
┣ 本当に怖い事
┣ プログラムを作る
┣ バッファオーバーフロ
┃ ーを発生させる

┣ スタック領域の構成
┣ 何故強制終了されるの
┃ か?

┣ 強制終了されないよう
┃ に作り変える

┣ 任意のコードを実行す
┃ る

┣ of1.cとof2.cとの違い
┣ 例外
┣ 例外ハンドラの行う事
┣ of3.cを作る
┣ of1.cとof3.cとの違い
┣ of3.exeの例外ハンド
┃ ラ

┣ of3.exeを強制終了す
┃ るのは?

┣ 例外ハンドラの特徴
┣ Blue Screen
┣ BufferOverFlow応用
┃ プログラム

┗ 機械語の説明

Copyright(C) 2001-2002.ugpop. All rights reserved.




■デジタル用語辞典:
■ 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"との「処理時間の差」になってい
たのです。


しかしここである疑問が浮かびます。

「強制終了されるまでの時間に差がある理由は分かったけど、
このまま永久にぐるぐると処理を続けてしまうの?」

このような疑問を持たれた方、ごもっともです。

実は永遠にこの処理を繰り返すわけではありません。

やはり最後には歯止めをかける人がいるのです。

それは誰なのでしょうか?

続きは次回に説明します。



▲このページの上へ

▲このページの上へ

▲このページの上へ

←前に戻る    ▲このページの上へ    続きを読む→

▲このページの上へ

▲このページの上へ