昨日の続き
解説編です。
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(安全にコピーする関数)を使うなど、注意しましょう。
また、このような技術は悪用しないように。