我目前正在调查一个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