Windows 汇编指令如何无法读取其所在的内存

Windows 汇编指令如何无法读取其所在的内存,windows,exception,memory-management,x86,Windows,Exception,Memory Management,X86,在Windows XP中使用一些作为Windows服务的软件并从登录屏幕重新启动时,我看到一条臭名昭著的错误消息 “00x…”处的指令引用了“00x…”处的内存。记忆 无法阅读 我向开发人员报告了这个问题,但再次查看消息时,我注意到地址是相同的。所以 “00xdf3251”处的指令引用了“00xdf3251”处的内存。记忆 无法阅读 这是否是程序中的错误,但内存/访问权限的状态或其他阻止指令读取其所放置内存的内容是什么。这是特定于服务的吗 我猜有人试图在地址0xdf3251处执行指令,但该位置没

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

“00x…”处的指令引用了“00x…”处的内存。记忆 无法阅读

我向开发人员报告了这个问题,但再次查看消息时,我注意到地址是相同的。所以

“00xdf3251”处的指令引用了“00xdf3251”处的内存。记忆 无法阅读


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

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

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

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

  • 完全没有映射(根本没有映射页面)
  • 缺少写入权限(该页为只读)
  • 缺少执行权限(页面设置了“无执行”位)或
  • 缺少内核权限(页面标记为仅在内核中可访问)
不管它是在数据访问期间还是在获取指令时(后者就是我们的情况)

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


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

这种崩溃最典型的原因是堆栈损坏。一种非常常见的类型是堆栈缓冲区溢出。在堆栈上存储的数组中写入太多数据,会用数据覆盖函数的返回地址。当函数返回时,它会跳转到伪返回地址,程序就会崩溃,因为该地址没有代码。他们将很难修复这个bug,因为没有简单的方法来找出腐败发生的地方


这是一个臭名昭著的bug,它是恶意软件的主要攻击向量。因为它可以命令程序跳转到包含数据的任意代码。你应该和这些开发者坐下来谈谈,并指出这是一个重大的安全风险。治疗很简单,他们应该更新他们的工具。目前,针对缓冲区溢出的对策非常有用。

很好的解释,这里可能就是这种情况。不幸的是,这些对策并不能保证捕获所有可能导致这种情况的损坏。如果是释放bug后使用呢?释放崩溃后使用不会导致这种AV,代码和数据地址会有所不同。假设您有一个动态分配的结构,其中有一个函数指针,并且程序通过该指针调用函数。在释放结构之前,一切都很顺利,但要继续使用指向它的陈旧指针。然后,以前结构所在的内存被新分配的其他内容覆盖。嗯,当你只知道一个崩溃地址时,没有什么是不可能的。这就是为什么他需要与开发人员坐下来,以确保消除99%的此类碰撞几率。