2017-04-03 12 views
0

スタック保護をオフに、私はこのCコードを持っている原因:は、私は思っていた

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 

int fillBuffer(int argc, char *argv[]) { 
    char bufferA[4] = "aaa"; 
    char bufferB[4] = "bbb"; 

    if(argc > 1) 
    strcpy(bufferB, argv[1]); 

    printf("bufferA: %s\n", bufferA); 
    printf("bufferB: %s\n", bufferB); 

    return 0; 
} 

int main(int argc, char *argv[]) { 
    fillBuffer(argc, argv); 
    return 0; 
} 

をし、私が使用してスタック保護をオフにしてみました:-fno-スタックプロテクターを

とするとき私はやってそれを実行しよう:

bufferA:bufferB

F:

01 FFFFF ./programプログラム出力に、5F(キーをエスケープ)

私はbufferAがどのようにfになるのか分かりません。誰も私にこれを説明することはできますか?

+0

あなたは 'argv [1]'が '3'文字であることを確信していますか?... – LPs

+1

未定義の動作、何かが起こる可能性があります。これは一つの可能​​性にすぎません。 –

+0

Cコードがちょうど私たちに与えられました –

答えて

0

あなたのstrcpy呼び出しは安全ではなく、argv [1]に3文字以上が含まれていればスタックが壊れてしまいます。脱出、単にスペースと5Fを押すと、あなたは適切な出力を取得しないでください:あなたは脱出ヒットすると

scott> a.out 5f 
bufferA: aaa 
bufferB: 5f 

を、シェルは文字列パラメータに文字を追加することができ、そして、あなたのstrcpyのは安全ではないので(チェックしません。長さ)、バッファの終わりを超えてスタックを破壊します。あなたのバッファは4文字だけですので、3文字より長いパラメータが入力された場合、プログラムはスタックを破壊します。

して、それを修正する60のような、より合理的なものに4からあなたのバッファサイズを大きくし、パラメータが長すぎる場合は、バッファを超えないことを確実にするためにはstrncpyを使用するには:

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 

#define MAX_PARM_LEN 60 

int fillBuffer(int argc, char *argv[]) { 
    char bufferA[MAX_PARM_LEN] = "aaa"; 
    char bufferB[MAX_PARM_LEN] = "bbb"; 

    if(argc > 1) 
    strncpy(bufferB, argv[1], MAX_PARM_LEN); 

    printf("bufferA: %s\n", bufferA); 
    printf("bufferB: %s\n", bufferB); 

    return 0; 
} 

int main(int argc, char *argv[]) { 
    fillBuffer(argc, argv); 
    return 0; 
} 

最後の一つのポイント:スタック保護をオフにしないでください。

1

ローカルバッファAとBは、スタックに逆順で格納されます。したがって、メモリ上にバッファBを開始し、バッファAを開始します。

5 "f"をバッファBにstrcpyすると、最初の4つはバッファBに入り、最後の文字は\ 0 'をバッファーAに送信します。

バッファーを印刷すると、バッファーAには1 "f"とストリングターミネーターが含まれます。それはそれがどこから来るのかです。

関連する問題