本文會演示兩個發生棧溢出的例子,並用OD工具演示整個過程。
案例一
案例代碼
// dishui_nx.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
void HelloWord()
{
printf("Hello World");
getchar();
}
void Fun()
{
int arr[5] = {1,2,3,4,5};
//覆蓋返回地址 Fun函數執行完就會Helloworld函數
arr[6] = (int)HelloWord;
}
int main(int argc, char* argv[])
{
Fun();
// printf("Hello World!\n");
return 0;
}
案例分析
1.使用OD載入, 運行到Fun函數內部,在堆棧中可以看到Fun函數的下一行彙編指令的地址和EBP的值
2.當運行到0040D7B2 pop edi ,發現0012FF30 處的值變爲dishui_n.0040100F,意味着Fun的返回地址被修改。
3.接着運行HelloWord函數,當運行到該函數的末尾時,發現返回地址是7C 930738.
4.HelloWord函數運行完後,程序跳轉到7C930738處。而不是main函數處。
案例二
案例代碼
#include "stdafx.h"
void Fun()
{
int i;
int arr[5] = {0};
for(i=0;i<=5;i++)
{
arr[i] = 0;
printf("Hello World!\n");
}
}
int main(int argc, char* argv[])
{
Fun();
// printf("Hello World!\n");
return 0;
}
案例分析
1.運行到Fun函數內部,執行循環結構
2.發現變量i 的值存放在[ebp-4]中,當i爲5時,[ebp
edx*4-18]就變爲[ebp-4],那麼i的值就被覆蓋。
3.那麼i的值一直不超過5,導致無限循環