最近服務器上一個后台傳輸文件的服務,經常會報出異常來,只能強行終止並重啟。
昨天剛好有空,現場抓了一下dump,再把程序扔到IDA里看了一下,很快就找出原因了,原來是調用fclose時出錯的。
使用C的Runtime函數進行文件操作,也就是fopen,fread,ftell,fclose這些,本身這並沒有什么問題
但是出現異常的位置往上一點,程序寫了日志,主要內容是“打開文件失敗,錯誤原因:xxxxxx”
也就是說,在使用fopen打開文件失敗了之后,程序仍然使用了fclose來關閉這個無效的FILE指針,導致了異常的發生。
可以簡單用下面的代碼測試一下:
void TestFun() { FILE *fp; fp = fopen("C:\\nosuchfile.sys","r");//打開一個不存在的文件 printf("fp = 0x%X\n",fp); if (fp == NULL) { printf("Open file failed.\n"); } else { printf("Open file succeed.\n"); } fclose(fp);//這里將引發異常 }
事實上,我所知道的,用CloseHandle關閉一個無效的句柄同樣是會引發異常的。
本來打開操作就是失敗的,FILE指針也無效,再關它有什么意義呢?
解決辦法:直接把程序中這個調用打了個補丁,用nop指令填充了一下,就正常了。如下圖所示,將有顏色的三條指令用nop填充:

