數組越界問題分析

一般狀況下在C語言中咱們定義一個大小爲5的數組是這樣的:html

int arr[5] = {1,2,3,4,5};

1,2,3,4,5這五個數字對應的下標是0,1,2,3,4,當咱們想訪問數組中第一個數字時,一般會使用arr[0]的形式去訪問,可是,若是咱們使用arr[5]=6來對超過數組大小的地方進行賦值,會發生什麼?
數組

編譯以後,發現編譯器並無報錯,也沒有警告,可是咱們知道,這裏其實已經發生了數組越界問題。
那咱們先來看一下不進行數組越界操做的時候反彙編是什麼樣的:
函數

再來看一下對數組進行越界操做的時候是什麼樣的:
code

對比以後發如今添加了一句arr[5]=6以後,反彙編代碼這裏多出一句0040104B mov word ptr [ebp],6,也就是6被存到內存地址爲[ebp]的地方了。
參照上一篇文章,能夠知道[ebp]是存放原ebp的地址,也就是函數執行第一步的push ebp,一個函數在開始執行前,會將下一條指令的地址壓入棧中,位置是[ebp+4],這裏咱們注意到,arr[5]的位置是[ebp],那麼[ebp+4]的位置就是arr[6],存放在這裏的值在函數結束以後會被存放到EIP中當成下一條指令的地址,執行此處的指令。
那麼咱們要是在arr[6]的位置換成另外一個函數的地址,那麼在這個函數結束後不就能夠自動調用另外一個函數了,因而將原來的代碼改爲這樣:htm

#include <stdio.h>

void First();
void Hello();

int main(void)
{
    First();
    return 0;
}

void First()
{
    int arr[5] = {1,2,3,4,5};
    arr[6] = (int)Hello;
}
void Hello()
{
    printf("Hello World!");
    getchar();
}

這樣,根據咱們的構想,在主函數裏面調用了First函數,可是在First函數結束後,會調用Hello函數:
blog

這裏能夠看到返回地址被改爲了Hello函數的入口地址:

從上面就能夠看出數組越界的危害性。內存

相關文章
相關標籤/搜索