windows - 汇编程序指令如何无法读取它所在的内存

标签 windows exception memory-management x86

在 Windows XP 中使用某些作为 Windows 服务运行的软件并从登录屏幕重新启动,我看到一条臭名昭著的错误消息

The instruction at "00x..." referenced memory at "00x...". The memory could not be read.

我向开发人员报告了这个问题,但再次查看消息时,我发现地址是一样的。所以

The instruction at "00xdf3251" referenced memory at "00xdf3251". The memory could not be read.

无论这是否是程序中的错误,但内存/访问权限的状态是什么,或者阻止指令读取它所放置的内存的其他内容。它是特定于服务的东西吗?

最佳答案

我猜有人试图在地址 0xdf3251 处执行一条指令,并且该位置没有由可读和可执行的内存页面(可能完全未映射)备份。

如果是这种情况,则异常(实际上是页面错误)源自该指令,并且异常处理程序在堆栈上有其地址(返回的位置,以防异常可以以某种方式解决并且错误指令当处理程序返回时重新启动)。这是您看到的第一个地址。

页面错误处理程序读取的 CR2 寄存器,这是您看到的第二个地址,也具有相同的地址,因为它必须包含不可访问的内存位置的地址,无论是否页面错误是由以下原因引起的:

  • 完全没有映射(根本没有页面映射)
  • 缺少写权限(该页面是只读的)
  • 缺乏执行权限(页面设置了禁止执行位)或
  • 缺乏内核权限(该页面被标记为只能在内核中访问)

并且不管它是在数据访问期间还是在获取指令时(后者是我们的情况)。

这就是使指令和内存访问地址相等的方法。

代码很可能存在导致内存损坏的错误,并且某些指针(或堆栈上的返回地址)被指向无法访问的内存位置的虚假值覆盖。然后以某种方式指示 CPU 在那里继续执行(很可能使用以下指令之一:jmpcallret ).也有可能在某处出现竞争条件。

关于windows - 汇编程序指令如何无法读取它所在的内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10427676/

相关文章:

windows - 在 Windows 10 中找到 calc.exe 或 notepad.exe 或 ... 的实际位置

c# - 在发生未处理的异常后,我可以将执行返回到失败的方法吗?

memory-management - 架构式 TLB 与架构式页表

memory-management - 为什么 Haskell 编译器不促进确定性内存管理?

windows - 批处理文件变量在这种特殊情况下无法打印

c - windows 从游戏窗口获取像素

windows - 将应用程序的 64 位和 32 位版本滚动到同一个二进制文件中?

javascript - CreateGlobalJavascriptObject 问题

MySQL 在事务中捕获异常

c - 灵活数组成员的非静态初始化