我目前正在調查一個Windows崩潰轉儲,並在打開轉儲文件時,Visual Studio調試器向我顯示「非法指令0xC000001D
」。它示出該錯誤的代碼位置示出了沿着以下示例的拆解:是否可以在Windows XP下用普通的C++程序覆蓋代碼段?
void g(int x) {
00401E80 push ebp
00401E81 mov ebp,esp
if(x > 20) {
00401E83 cmp dword ptr [x],14h
00401E87 jle g+14h (401E94h)
x *= 4;
>00401E89 db 0fh // illegal instruction here
00401E8A db 0fh
00401E8B xadd eax,esp
00401E8E add cl,byte ptr [ecx+9EB0845h]
x += 42;
00401E94 mov ecx,dword ptr [x]
...
我手動通過改寫與在調試程序存儲器窗口一些無效值的功能碼創建在調試器上面的例子,但故障轉儲我調查顯示同樣的db 0fh
條目,顯然表明一條無效指令。該代碼也類似於我的轉儲文件顯示的內容,因爲無效指令之前的指令都顯得有效且與源代碼匹配。
現在問題是是否有可能在所有的正常編譯的C++程序 - 圍繞不惹內存頁面的訪問限制 - (在Windows XP中的Visual C++ 2005)弄亂的代碼段處理?
如果我嘗試從代碼中寫入上述示例中的函數地址,我總是得到一個訪問衝突,即代碼段內存頁似乎是寫保護的。
{
void* fnAddr = &g; // non-portable but OK in VC++
unsigned int x = 0xDEADBEEF;
// Simulate memory corruption: Try to write something to the code segment:
memcpy((char*)fnAddr+4, &x, sizeof(x)); // generated 0xC0000005 Access Violation
g(42); // call messed up function - never get here
}
您是否知道實際上可能會無意中覆蓋代碼段中某些內容的任何情況?
我應該補充一點,真正的程序很複雜,有很多虛函數,一些成員函數指針等等,這個問題很遺憾不能重現,我們目前只有這個轉儲文件看起來很好除此以外。 - 儘管如此,轉儲文件在代碼段中顯示非法指令,我不會認爲有可能弄亂代碼段。
這些文件看起來不錯。內存錯誤似乎不太可能,但我們會測試。也許轉儲文件沒有向我展示我認爲給我看的東西。 – 2010-11-23 07:41:44