2016-12-22 15 views
0

私は、このソースコードにバッファオーバーランについて学んでいます:gets()は ' 0'を無視しますか?

#include <stdio.h> 
int main() 
{ 
    char buf[16]; 
    gets(buf); 
    printf("buf @ %8p\n", (void*)&buf); 
    return 0; 
} 

私はBUF変数にNull文字(「\ 0」)を記述してみてください。

まず、gdbに、私はgets()関数の後、6行目にブレークポイントを設定し、r <<< $(python -c 'print "\0"*11 + "AAAA"')

でそれを実行し、私はスタックを探索するとき、私はそれだけでbufに「AAAA」を書き実現。何が起こるのですか?

(gdb) x/16xw &buf 
0xffffcf80: 0x41414141 0xffffd000 0xffffd04c 0x080484a1 
0xffffcf90: 0xf7fb43dc 0xffffcfb0 0x00000000 0xf7e1a637 
0xffffcfa0: 0xf7fb4000 0xf7fb4000 0x00000000 0xf7e1a637 
0xffffcfb0: 0x00000001 0xffffd044 0xffffd04c 0x00000000 

しかし、私はr <<< $(python -c 'print "\1"*11 + "AAAA"')でプログラムを実行すると、bufは次のようになります。

(gdb) x/16xw &buf 
0xffffcf80: 0x01010101 0x01010101 0x41010101 0x00414141 
0xffffcf90: 0xf7fb43dc 0xffffcfb0 0x00000000 0xf7e1a637 
0xffffcfa0: 0xf7fb4000 0xf7fb4000 0x00000000 0xf7e1a637 
0xffffcfb0: 0x00000001 0xffffd044 0xffffd04c 0x00000000 

のでgets()機能がNull文字を受信しませんかstdinはそれを無視するのだろうか?

P/S:私はgccの上gcc -m32 -fno-stack-protector -g stack.c -o stackでそれを建てた(Ubuntuの5.4.0-6ubuntu1〜16.04.4)5.4.0 20160609.


更新:いくつかの提案の後、Iこの方法を試してください。

#include <stdio.h> 
int main() 
{ 
    char buf[16]; 
    gets(buf); 
    printf("buf @ %8p\n", (void*)&buf); 
    for (int i = 0; i < 16; ++i) // this is for loop all the buf 
    { 
     printf("%02x ", buf[i]); 
    } 
    return 0; 
} 

それは '\ 0'

$ gcc -g j_stack.c -o j_stack 
$ python -c 'print "AAAA" + "\0"*6 + "AAAA"'| ./j_stack 
buf @ 0xffffcfbc 
41 41 41 41 00 00 00 00 00 00 41 41 41 41 00 ffffffff 
で動作します

しかし、どのように私は、gets'\0'を無視しないgdbプログラム

+0

マイナーヒント:パイプ、あなたが期待する結果が表示されるはずですあなたはすべての0xFFsまたはその –

+0

'gets'と' fgetsのようなものに初期化 'buf'をたい場合には、この出力を読み取ることが容易になるだろう'' \ 0 ''を特別に扱わない関数です。彼らはちょうど良いヌル文字を読み取ることができます。あなたのプログラムを使って '' ab \ 0c \ n "'という文字列を読みました。 –

+0

これは入力を提供するための "here strings"の使用によるものだと思います( '<<<')。これは、入力をプログラムに渡す非常に複雑な方法です。そう思わないのですか?方程式からgdbを取り出し、シェルからの標準的なパイプを使用してください。あなたはそれが働いているのを見てください。これが真実で、それで答えが価値があるかどうか私たちに知らせてください。 –

答えて

3

いいえ、それはありません。

この動作は、gets()、またはPython文字列とは関係ありません。あなたはシンプルで、あなたのプログラムを実行する場合

# python -c 'print "\0"*11 + "AAAA"' | wc -c 
16 
# python -c 'print "\0"*11 + "AAAA"' | hexdump 
0000000 0000 0000 0000 0000 0000 4100 4141 0a41 
0000010 

# cat <<< $(python -c 'print "\0"*11 + "AAAA"') | wc -c 
5 
# hexdump <<< $(python -c 'print "\0"*11 + "AAAA"') 
0000000 4141 4141 000a 
0000005 

# echo $(python -c 'print "\0"*11 + "AAAA"') | wc -c 
5 

:それは(明らかにNULLバイトを落とすなど、performs some manipulations on whatever you give it)サブシェルとバッシュ「herestring」構文を使用して、あなたのプログラムへの入力を提供している方法が原因です

python -c 'print "\0"*11 + "AAAA"' | ./myProgram 
+0

ありがとうございます。だから、 'gdb'のプログラムにどのように入力するのですか? – lzutao

+1

@ LzuTao:http://stackoverflow.com/q/8422259/560648 –

+0

ありがとうございます。プログラムを実行するたびに、gdbでstringを使うことができないので、入力ファイルを書くべきだと思います。 :( – lzutao

2

buf'\0'が含まれている入力を提供します。

私はgetsを呼び出した後

for(i = 0; i < 16; i++) printf("%02x", buf[i]); 
printf("\n"); 

を含めるようにプログラムを変更しました。私は、入力

abc\n 

上でプログラムを実行したと私は予想通り

61626300000000000000000000000000 

を見ました。私はその後、入力

ab\0c\n 

上でプログラムを実行しても、私が期待したものだった

61620063000000000000000000000000 

を見ました。


P.S.なぜあなたがした振る舞いを見たのか分かりませんが、<<<とそれらのpythonの断片で何をしているのか分かりません。私、私はunhexは、私は、よく、明白なことを行うための私のbinディレクトリに持っている小さなプログラムです

echo abc | a.out 

echo 616200630a | unhex | a.out 

を使用しました。

+0

あなたが言及したならどのコンパイラとOSを使用しましたか?この質問に記載されている動作は、1つのセットアップに固有のものかもしれません。 –

+0

私はMacOSの下でclangを使いました。しかし、私はその行動がシステム特有であるとは思わない。 'gets 'と' fgets'は特別に '\ 0'を扱うものとして文書化されておらず、実現したことは一度もありません。 –

+0

私はそれはシステム特有であるべきではないと思うが、彼らの観察を無効にする質問には何も明白ではない。 –

関連する問題