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

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.




■デジタル用語辞典:
■ of1.cとof3.cとの違い ■

前回は"of3.c"というプログラムを作成し、実際に動作させて
みました。

以下に"of3.c"のソースコードを示します。


─↓"of3.c"ここから──────────────────
#include <stdio.h>
#include <string.h>
void main(void);

void main()
{
  unsigned char* i;
  unsigned char b[]= { 0x10, 0x11, 0x12, 0x13,
             0x14, 0x15, 0x16, 0x17,
             0x18, 0x19, 0x1a, 0x1b,
             0x1c, 0x1d, 0x1e, 0x1f,
             0xff, 0xff, 0xff, 0xff,
// ●↓ここから追加
             0xff, 0xff, 0xff, 0xff,
             0xff, 0xff, 0xff, 0xff,
             0xff, 0xff, 0xff, 0xff,
             0xff, 0xff, 0xff, 0xff,
             0xff, 0xff, 0xff, 0xff,
             0xff, 0xff, 0xff, 0xff,
             0xff, 0xff, 0xff, 0xff,
             0xff, 0xff, 0xff, 0xff,
             0xff, 0xff, 0xff, 0xff,
             0xff, 0xff, 0xff, 0xff,
             0xff, 0xff, 0xff, 0xff,
// ●↑ここまで追加
          };
  unsigned char a[]= { 0x0, 0x1, 0x2, 0x3,
             0x4, 0x5, 0x6, 0x7,
          };

  // スタック領域を表示する。
// ●変更↓スタック領域表示範囲変更
  for(i=&b[0];i<=&a[63];i+=4)
  {
    printf("%08X:%02X %02X %02X %02X\n", i, *i, *(i+1), *(i+2), *(i+3));
  }
  // バッファbをバッファaにコピーする。
  strncpy((char*)a, (char*)b, sizeof(b));
  printf("copy end\n");
  // スタック領域を表示する。
// ●変更↓スタック領域表示範囲変更
  for(i=&b[0];i<=&a[63];i+=4)
  {
    printf("%08X:%02X %02X %02X %02X\n", i, *i, *(i+1), *(i+2), *(i+3));
  }
}
─↑"of3.c"ここまで──────────────────


このプログラムはバッファbをバッファaにコピーするだけの
プログラムでした。

ところがコピーする際にバッファオーバーフローが発生し、強
制終了されてしまいます。

強制終了されてしまう、という点に関しては以前に作成した
"of1.c"というプログラムと同じですが、このプログラムの場
合、"of1.c"というプログラムとは、微妙に「強制終了のされ
方」が異なります。

今回は"of1.c"と"of3.c"との動作の違いを説明し、具体的にど
のような動作をしているか説明します。


まず、「強制終了のされ方」が異なると書きましたが、具体的
には「強制終了されるまでの時間」が異なります。

"of1.exe"を実行させると、実行させた瞬間、即、強制終了さ
れます。

ところが、"of3.exe"の方は、実行させると、少し時間が経過
してから強制終了されます。(微妙な差なので気付きにくいか
もしれません。)

何故、少し時間が経過してから強制終了されるのでしょうか?


それを説明する為に、まず"of1.exe"と"of3.exe"のバッファオ
ーバーフローの様子を見比べてみましょう。

以下に"of1.exe"を実行した時のバッファオーバーフローのイ
メージを示します。


●"of1.exe"でコピー処理が行われる前のスタック領域

         スタック領域
       ┌┌──────┐
       ││      │
       ││      │
       ││      │
  バッファb││      │
       ││      │
       ││      │
       ││      │
       ├├──────┤
       ││      │
  バッファa││      │
       ││      │
       └├──────┤
        │      │
       ┌├──────┤
  呼出し元 ││      │
       └├──────┤
        │      │
        │      │
        │      │
        │      │
 メッセージを┌├──────┤
 表示するプロ││      │
 グラムの場所└└──────┘


以前説明したように、スタック領域の中には「メッセージを表
示するプログラムの場所」情報が格納されています。
そして、それは上のイメージの様にスタック領域の下の方に格
納されています。

これはWindowsアプリケーションに共通した仕様です。

次に、バッファオーバーフロー発生直後の様子を見てみましょ
う。


●"of1.exe"でコピー処理が行われた直後のスタック領域

         スタック領域
       ┌┌──────┐┐
       ││      ││
       ││      ││
       ││      ││バッファ「b」のサイズ分
  バッファb││      │├─┐    ̄
       ││      ││ │
       ││      ││ │
       ││      ││ │コピー
       ├├──────┤┤ │
       ││      ││ │
  バッファa││      ││ │
       ││      ││ │
       └××××××××│ │
        ×      ×│←┘
       ┌×      ×│
  呼出し元 │×      ×│
       └××××××××┘
        │      │
        │      │
 メッセージを┌├──────┤
 表示するプロ││      │
 グラムの場所└└──────┘


バッファ「b」のサイズ分だけコピー処理が行われる為、バッ
ファオーバーフローが発生し、「呼出し元」の情報が書き換わ
ってしまいました。

この時の「×」で囲まれた範囲がバッファオーバーフローの被
害範囲です。


次に、"of3.exe"を実行した時のバッファオーバーフローの様
子を見てみましょう。
"of3.c"のプログラムでは、バッファbの「サイズを大きくし
ている」という事に注意しながら見てください。


●"of3.exe"でコピー処理が行われる前のスタック領域

         スタック領域
       ┌┌──────┐
       ││      │
       ││      │
       ││      │
       ││      │
       ││      │
       ││      │
  バッファb││      │
       ││      │
       ││      │
       ││      │
       ││      │
       ││      │
       ││      │
       ├├──────┤
       ││      │
  バッファa││      │
       ││      │
       └├──────┤
        │      │
       ┌├──────┤
  呼出し元 ││      │
       └├──────┤
        │      │
        │      │
        │      │
        │      │
 メッセージを┌├──────┤
 表示するプロ││      │
 グラムの場所└└──────┘


バッファbのサイズが大きくなっている以外は"of1.exe"と全
く同じです。

それではバッファオーバーフロー発生直後の様子を見てみまし
ょう。


●"of3.exe"でコピー処理が行われた直後のスタック領域

         スタック領域
       ┌┌──────┐┐
       ││      ││
       ││      ││
       ││      ││
       ││      ││
       ││      ││
       ││      ││バッファ「b」のサイズ分
  バッファb││      │├─┐    ̄
       ││      ││ │
       ││      ││ │
       ││      ││ │コピー
       ││      ││ │
       ││      ││ │
       ││      ││ │
       ├├──────┤┤ │
       ││      ││ │
  バッファa││      ││ │
       ││      ││ │
       └××××××××│ │
        ×      ×│ │
       ┌×      ×│ │
  呼出し元 │×      ×│ │
       └×      ×│ │
        ×      ×│ │
        ×      ×│ │
        ×      ×│ │
        ×      ×│ │
 メッセージを┌×      ×│ │
 表示するプロ│×      ×│←┘
 グラムの場所└××××××××┘


バッファbのサイズ分だけコピー処理が行われるので、バッフ
ァオーバーフローの被害範囲が広がっています。

これにより"of3.exe"の方では「メッセージを表示するプログ
ラムの場所」情報も書き換わってしまいました。

"of1.exe"と"of3.exe"の動作の違いは、この「メッセージを表
示するプログラムの場所」情報が書き換わってしまうのか、そ
うでないのか、という違いだけです。

しかし「メッセージを表示するプログラムの場所」情報が書き
換わってしまう事により、この後の動作にある違いが生じる事
になります。

それはどんな違いなのでしょうか?

続きは次回に。



▲このページの上へ

▲このページの上へ

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

▲このページの上へ