掃描二維碼
隨時(shí)隨地手機(jī)看文章
#include?
int?main(void)
{
????char?buff[10];
????memset(buff,?0,?sizeof(buff));
????gets(buff);?//gets不檢查輸入的字符串大小,可能造成緩存溢出
????printf("\n?The?buffer?entered?is?[%s]\n",?buff);
????return?0;
}
答:上面代碼里的問題在于函數(shù)?gets()
?的使用,這個(gè)函數(shù)從?stdin
?接收一個(gè)字符串而不檢查它所復(fù)制的緩存的容積,這可能會(huì)導(dǎo)致緩存溢出。這里推薦使用標(biāo)準(zhǔn)函數(shù)?fgets()
?代替。#include?
#include
int?main(int?argc,?char?*argv[])?
{?
????int?flag?=?0;?
????char?passwd[10];?
????memset(passwd,0,sizeof(passwd));?
????strcpy(passwd,?argv[1]);?
????if(0?==?strcmp("LinuxGeek",?passwd))?
????{?
????????flag?=?1;?
????}?
?????
????if(flag)?
????{?
????????printf("Password?cracked?\n");?
????}?
????else?
????{?
????????printf("Incorrect?passwd?\n");?
?????
????}?
????return?0;?
}
答:破解上述加密的關(guān)鍵在于利用攻破?strcpy()
?函數(shù)的漏洞。所以用戶在向?“passwd”
?緩存輸入隨機(jī)密碼的時(shí)候并沒有提前檢查?“passwd”
?的容量是否足夠。所以,如果用戶輸入一個(gè)足夠造成緩存溢出并且重寫?“flag”
?變量默認(rèn)值所存在位置的內(nèi)存的長(zhǎng) “密碼” ,即使這個(gè)密碼無(wú)法通過(guò)驗(yàn)證,?flag
?驗(yàn)證位也變成了非零,也就可以獲得被保護(hù)的數(shù)據(jù)了。例如:ubuntu@VM-16-5-ubuntu:~$?g ?-o?test?test.c
ubuntu@VM-16-5-ubuntu:~$?./test?aaaaaaaaaa
Incorrect?passwd?
雖然上面的密碼并不正確,但我們?nèi)匀豢梢酝ㄟ^(guò)?緩存溢出?繞開密碼安全保護(hù)。要避免這樣的問題,建議使用?strncpy()
?函數(shù)。#include?
void?main(void)?
{?
????char?*ptr?=?(char*)malloc(10);?
????if(NULL?==?ptr)?
????{?
????????printf("\n?Malloc?failed?\n");?
????????return;?
????}?
????else?
????{?
????????//?Do?some?processing?
????}?
?????
????return;?
}
答:盡管上面的代碼并沒有釋放分配給?“ptr”
?的內(nèi)存,但并不會(huì)在程序退出后導(dǎo)致內(nèi)存泄漏。在程序結(jié)束后,所有這個(gè)程序分配的內(nèi)存都會(huì)自動(dòng)被處理掉。但如果上面的代碼處于一個(gè)?“while循環(huán)”
?中,那將會(huì)導(dǎo)致嚴(yán)重的內(nèi)存泄漏問題!’freeze’
?的時(shí)候出問題,而?’zebra’
?則不會(huì),為什么?#include?
#include
#include
int?main(int?argc,?char?*argv[])?
{?
????char?*ptr?=?(char*)malloc(10);?
????if(NULL?==?ptr)?
????{?
????????printf("\n?Malloc?failed?\n");?
????????return?-1;?
????}?
????else?if(argc?==?1)?
????{?
????????printf("\n?Usage??\n");?
????}?
????else?
????{?
????????memset(ptr,?0,?10);?
????????strncpy(ptr,?argv[1],?9);?
????????while(*ptr?!=?'z')?
????????{?
????????????if(*ptr?==?'\0')?
????????????????break;?
????????????else?
????????????????ptr ;?
????????}?
????????if(*ptr?==?'z')?
????????{?
????????????printf("\n?String?contains?'z'\n");?
????????????//?Do?some?more?processing?
????????}?
???????free(ptr);?
????}?
????return?0;?
}
答:這里的問題在于,代碼會(huì)(通過(guò)增加?“ptr”
?)修改while循環(huán)里?“ptr”
?存儲(chǔ)的地址。當(dāng)輸入?“zebra”
?時(shí),while
?循環(huán)會(huì)在執(zhí)行前被終止,因此傳給?free()
?的變量就是傳給?malloc()
?的地址。但在?“freeze”
?時(shí),“ptr”
?存儲(chǔ)的地址會(huì)在?while
?循環(huán)里被修改,因此導(dǎo)致傳給?free()
?的地址出錯(cuò),也就導(dǎo)致了?seg-fault
?或者崩潰。atexit()
?并沒有被調(diào)用,為什么?#include??
#include?
#include?
void?func(void)?
{?
????printf("\n?Cleanup?function?called?\n");?
????return;?
}?
int?main(void)?
{?
????int?i?=?0;?
????atexit(func);?
????for(;i<0xffffff;i );?
????_exit(0);?
}
這是因?yàn)?_exit()
?函數(shù)的使用,該函數(shù)并沒有調(diào)用?atexit()
?等函數(shù)清理。如果使用?atexit()
?就應(yīng)當(dāng)使用?exit()
?或者?“return”
?與之相配合。#include?
int?main(void)?
{?
????char?*ptr?=?"Linux";?
????*ptr?=?'T';?
????printf("\n?[%s]?\n",?ptr);?
????return?0;?
}
答:這是因?yàn)?,通過(guò)?*ptr = ‘T’
,會(huì)改變內(nèi)存中代碼段(只讀代碼)“Linux”
?的第一個(gè)字母。這個(gè)操作是無(wú)效的,因此會(huì)造成?seg-fault
?或者崩潰。#include?
int*?inc(int?val)?
{?
??int?a?=?val;?
??a ;?
??return?