2017-05-30 41 views
0

私は現在「Hacking:The Art of Exploitation」という本を読んでいます。私はちょうど初めの章にしかいませんし、Cで基本的な文字列のコピーと入力関数を行っています。scanfによる不正な出力(ハッキング:搾取例のテクニック)

最新の例では、文字列を繰り返し印刷するためにstrcpyとscanfの組み合わせを使用しますが、私のために不正な形式の出力を生成します。次のように例を示します。

input.c:

#include <stdio.h> 
#include <string.h> 
int main() { 
    char message[10]; 
    int count, i; 

    strcpy(message, "Hello, world!"); 

    printf("Repeat how many times? "); 
    scanf("%d", &count); 

    for(i=0; i < count; i++) 
     printf("%3d - %s\n", i, message); 
} 

あなたが入力数を、それは何回も印刷する必要がありますブックによります。例えば

[email protected]:~/booksrc $ ./input 
Repeat how many times? 3 
0 - Hello, world! 
1 - Hello, world! 
2 - Hello, world! 

はこれが私のために動作しますが、何らかの形で "こんにちは、世界!"文字列が破損し、不正な形式になり、 "Hello、wor"だけが出力され、不正な文字が印刷されます。

[email protected]:~/booksrc $ ./input 
Repeat how many times? 3 
0 - Hello, wor 
1 - Hello, wor␦ 
2 - Hello, wor␦ 

それはUTF-8文字または類似した何かを反復処理だかのように、最後に印刷された間違った文字にいくつかの一貫性があるようです。最初の3つは、印刷不可能なUnicode文字を表すボックスを印刷し、さらに高い範囲が指定されていれば、最終的に実際の文字が印刷されます。

これはscanfとおそらく私の端末の使用と関係があると思います(Debian GNU/Linuxボックスでこのプログラムを実行していますが、デフォルトのGNOME端末を使用しています)。現在のバージョンではなく、gccの以前のバージョンで動作しましたか?scanfは現在のバージョンのCで異なって解釈されていますか?

追加情報については、gcc version 6.3.0を実行しています。

誰でも助けていただければ幸いです。ありがとう!それは小さなにあるので

+0

'char message [10];'これは小さいです。それは少なくとも 'char message [14];以上でなければなりません。 – BLUEPIXY

+0

'message'配列の境界から書き出すので、おそらく' count'と 'i'変数のためにメモリ上に書き込むでしょう。次に、 'count'と' i'に書き込むと、範囲外だったデ​​ータを上書きし、「間違った」出力につながります。 –

+1

あなたの 'message'配列は文字列を保持するのに十分な長さではありません - ' 'Hello、world!' 'は10文字以上です。文字列全体を保持するのに十分なスペースを確保してください。*さらに、0値の文字列ターミネータ。 –

答えて

3
char message[10]; 
... 
strcpy(message, "Hello, world!"); 

messageは全体Hello, world!を含めることはできません。あなたはこのように未定義の動作に陥っており、あなたが見ている奇妙な出力を説明しています。 messageのサイズを大きくするか、必要なサイズを動的に決定する必要があります。 strlenを使用してください。

2

問題は、メッセージバッファの長さです。文字列 "こんにちは、世界!"

#include <stdio.h> 
#include <string.h> 
int main() { 
    char message[14]; 
    int count, i; 

    strcpy(message, "Hello, world!"); 

    printf("Repeat how many times? "); 
    scanf("%d", &count); 

    for(i=0; i < count; i++) 
     printf("%3d - %s\n", i, message); 
} 

ヒント:代わりSTRLENのstrnlen活用され、最終的な長さはここでは14であるコードであるので、13文字strcpyの自動的に追加\0用+ 1を含んでいます。

0
echo "Hello, world!" | wc 
     1  2  14 

だからあなたの文字列は、14 + 1バイト最終0を持って、あなたは、10バイトの配列でそれを維持しようとします。

strcpyはオーバーフローを生成します。

関連する問題