bufferOverflow に関する宿題に取り組んでいます。テスト プログラムはfread()
、ファイルから 4096 バイトを読み取るために使用します。
kernel.randomize_va_space を 0 に設定し、gdb でプログラムを実行すると、fread() コマンドが何も返さないことがわかります。
kernel.randomize_va_space を 1 または 2 に設定し、gdb を使用してプログラムを再実行すると、fread がファイルを保存するバッファーに期待されるデータが表示されます。
ASLR によって fread が適切に機能しなくなるのはなぜですか?
参考までに: これは ubuntu 12.0.4 64 ビットで、プログラムは -c99 および -m32 フラグを使用して gcc にコンパイルされています。
この課題のために与えられたテスト プログラムは次のとおりです。
#include <stdio.h>
#define READSIZE 0x1000
void countLines(FILE* f){
char buf[0x400];//should be big enough for anybody
int lines=0;
fread(buf,READSIZE,1,f);
for(int i=0;i<0x400;i++)
if(buf[i] == '\n')
lines++;
printf("The number of lines in the file is %d\n",lines);
return;
}
int main(int argc,char** argv){
if(argc<2){
printf("Proper usage is %s <filename>\n",argv[0]);
exit(0);
}
FILE* myfile=fopen(argv[1],"r");
countLines(myfile);
return 0;
}
gdb で実行すると、次の行にブレークポイントを配置します。
for(int i=0;i<0x400;i++)
次に、gdb で次のことを行います。
(gdb) x $esp
0xbffff280 0xbffff298
私が行った場合:
(gdb) x /12wx $esp
最初の 4 バイトは buf のアドレスで、次の 4 バイトは fread に渡された 0x1000 であり、次の 4 バイトは同じく fread に渡された 0x01 であることがわかります。
これは、 のスタック フレームではなく、 fread 関数のスタック フレームのように見えますcountLines()
。
$esp が、終了したばかりのスタック フレームではなく、現在のスタック フレームを指していないのはなぜですか?
アップデート
次のようにコードを変更しました。
#include <stdio.h>
#define READSIZE 0x1000
void countLines(FILE* f){
char buf[0x400];//should be big enough for anybody
int lines=0;
int ferr=0;
fread(buf,READSIZE,1,f);
ferr=ferror(f);
if (ferr)
printf("I/O error when reading (%d)\n",ferr);
else if (feof(f))
printf("End of file reached successfully\n");
for(int i=0;i<0x400;i++)
if(buf[i] == '\n')
lines++;
printf("The number of lines in the file is %d\n",lines);
return;
}
int main(int argc,char** argv){
if(argc<2){
printf("Proper usage is %s <filename>\n",argv[0]);
exit(0);
}
FILE* myfile=fopen(argv[1],"r");
countLines(myfile);
return 0;
}
ASLR を無効にして実行すると、次のメッセージが表示されます: I/O errorwhen readin (1)
ASLR を有効にして (値 = 1) 実行すると、EOF に到達します。