編譯環境:vs2010
1、C代碼如下(不要生成realse版本調試,因爲realse版本會把strcpy(buffer,password)這行代碼全部優化掉):
#include <stdio.h>
#include <Windows.h>
#define PASSWORD "123456"
int verify_password(char * password)
{
int authenticated;
char buffer[8];
authenticated=strcmp(password,PASSWORD);
strcpy(buffer,password);
return authenticated;
}
int main()
{
int valid_flag=0;
char password[1024];
FILE * fp=NULL;
if( !(fp=fopen("D:\\password.txt","r")) )
{
printf("open file fail!\n");
exit(0);
}
fscanf(fp,"%s",password);
fclose(fp);
fp=NULL;
valid_flag=verify_password(password);
if(valid_flag)
printf("incorrect password!\n");
else
printf("Congratulation! You have passed the verification!\n");
system("pause");
return 0;
}
2、debug編譯選項:
基本運行時檢查:默認值(就是兩者都不用)
緩衝區安全檢查:否
3、打開生成的exe文件,找到對應函數;
本來要順序執行0x00411377出的代碼,現在修改password.txt文件數據使其直接執行0x00411393處代碼(這之間的代碼不執行)
4、設置password.txt特定數據
5、
od調試截圖1(0x0012FB0C處值爲0x00411377):
F8後截圖2(0x0012FB0C處值已變爲0x00411393):
再一直F8至verify_password( )函數返回截圖3(返回地址已經不是0x00411377而是0x00411393):
6、繼續向下走(沒有發現因爲ebp被覆蓋引起的棧平衡導致程序崩潰)
在測試過程中發現編譯選項 ----基本運行時檢查:
會在編譯後的代碼中多次調用sub_41114A( )函數,這個函數中發現使用了"Unknown Runtime Check Error"字符串,strcpy( )函數後面也調用了這個函數:
使用上面的方法od調試運行時彈出檢查崩潰的提示