すりごまの鯖缶?ブログ 2缶目

鯖管のことだったりプログラミングのことだったりマイクラのことだったり

昨日の続き

解説編です。

	char line[255] = {0};
	char output[10] = {0};

はいこちら。
char配列を準備しています。
メモリ番地的に言うと

  • line : 0x0028FDD3
  • output : 0x0028FED2

となりました。(OllyDbgにて確認)

次に

	FILE *fp = fopen("bug.txt","r");
	fgets(line,255,fp);
	fclose(fp);

ファイル"bug.txt"から255byte読み込んで閉じます。

その後、

	strcpy(output, line);

はい。ここが問題のプログラムです。
このstrcpy。ソースを全部書き出し先にコピーします。
つまり、output用に確保されていたメモリを大幅に書き換えます。
ここで、もう一個関わってくる物があります。
メモリ番地です。
実は、このlineとoutputの先には戻り用の番地がスタックされているのです。
なので、outputにlineの中身がドバーッと書き込まれると番地を侵食することができます。
lineの中身をちゃんと?書くと、エントリーポイントや、別のプログラムに飛ばすことができます。
実際、このプログラムでは

abcdefghijklmnopqrstuvwxyz@(0x16)@(0x00)

というファイルをコピーしていきます。
最後の文字をよーく見てください。

@(0x16)@(0x00)

ここですね。
これをリトルエンディアンで表記すると、
0x00401640
つまり、戻り番地を0x00401640にすることで、エントリーポイントに無理やり戻すという荒業ができたのです。
これを、もし、別の場所にある悪意のあるコードに指定されたら。。。
((((;゚Д゚))))ガクガクブルブルですね。

なので、変数の確保には十分気をつけたり、文字列はstringを使う、文字列をコピーしたいならstrcpy_s(安全にコピーする関数)を使うなど、注意しましょう。
また、このような技術は悪用しないように。