c++ - 是否可以在Windows XP下用普通的C++程序覆盖代码段?

标签 c++ debugging visual-c++ assembly

我目前正在调查 Windows 崩溃转储,Visual Studio 调试器在打开转储文件时向我显示“非法指令 0xC000001D”。它显示此错误的代码位置显示了以下示例的反汇编:

 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
}

您是否知道实际上有可能无意中覆盖代码段中某些内容的任何情况?

我应该补充一点,真正的程序要复杂得多,有很多虚函数,一些成员函数指针等等,遗憾的是这个问题是不可重现的,我们目前只有这个看起来不错的转储文件. -- 尽管如此,转储文件在代码段中显示了一条非法指令,我不认为可能会弄乱代码段。

最佳答案

不,包含代码的内存页是写保护的。这种损坏只能发生在进程初始化时。但更可能的来源是软 RAM 错误。请您的客户运行 RAM 测试程序。考虑文件损坏是错误是可重复的。

关于c++ - 是否可以在Windows XP下用普通的C++程序覆盖代码段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4248170/

相关文章:

c++ - std::regex 未按预期工作

c++ - 使用 C++ 或 C 访问应用程序的 COM 接口(interface)

c++ - 谁包括谁得到定义?

c++ - 将自由函数转换为 DefaultConstructible 函数对象

c++ - 在 C++ 中构建简单的部分数组类时出现编译时错误

用于绘制 View 边缘的 Xcode 编译器标志

Android Studio调试清除应用程序数据但再次运行应用程序时数据没有被删除?

javascript - 如何在 Chrome 开发工具中找到跟随脚本加载时间线?

c++ - 当用户输入 "m"时,为什么我的代码不能直接进入 if 主体

c++ - _stat 返回不可能的 errno 代码 132