gpt4 book ai didi

c++ - 指向多态类的悬挂指针会导致未定义的行为。它真的可以成为任何可以想象的腐败的根源吗?

转载 作者:可可西里 更新时间:2023-11-01 16:19:03 25 4
gpt4 key购买 nike

我知道未定义行为一旦发生,就无法再考虑代码了。我完全相信。我什至认为我不应该深入了解 UB:一个理智的 C++ 程序不应该使用 UB,Period。

但为了让我的同事和经理相信它的真正危险,我试图找到一个具体的例子,我们的产品确实存在一个错误(他们认为这并不危险,最坏的情况是总是因访问冲突而崩溃)。


我主要关心的是在指向多态类的悬垂指针上调用虚拟成员函数。

当一个指针被删除时,Windows 操作系统会在堆 block 的头部写入几个字节,通常也会覆盖堆 block 本身的第一个字节。这是它跟踪堆 block 的方式,将它们作为链表进行管理……操作系统的东西。

虽然它没有在 C++ 标准中定义,但多态性是使用虚拟表 AFAIK 实现的。在 windows 下,给定一个只继承一个基类的类,指向虚拟表的指针位于堆 block 的第一个字节。 (多重继承可能会更复杂,但我不会考虑这一点。我们只考虑基类A,以及继承A的几个B,C,D)。


现在让我们考虑一下我有一个指向 A 的指针,它被实例化为 D 对象。并且 D 对象已在代码的其他地方被删除:所以堆 block 现在是一个空闲堆 block ,它的第一个字节已被覆盖,因此虚拟表指针几乎随机指向内存中的某个地方,比方说地址 0x01234567

在代码的某处,我们调用:

void test(A * pA)   
{
# here we do not know that pA is dangling pointer
# that memory address has been deleted by another thread, in another part of the code
pA->SomeVirtualFunction();
}

我说得对吗:

  • 运行时会将地址 0x01234567 处的内存解释为虚拟表
  • 如果错误地将此内存地址解释为vtable,它不会进入禁止内存区域,则不会发生任何访问冲突
  • 被误解的虚表会提供一个随机地址供虚函数执行,比方说0x09876543
  • 随机地址 0x09876543 的内存将被解释为有效的二进制代码,并真正执行
  • 这可能导致任何可以想象到的腐败

我不想夸大其词,以说服。那么,我说的是正确的、可能的、可能的吗?

最佳答案

你的例子是有可能的。

然而,情况要糟糕得多。

如果有人在攻击您的应用程序的用户,那么内存将不会包含随机数据。攻击者将尝试并可能设法影响该数据的内容。一旦发生这种情况,攻击者就可以确定要执行的代码。一旦发生这种情况,除非您的应用程序被适本地沙箱化(我敢打赌您的合作开发人员不会采取这种态度),否则攻击者可能能够接管用户的计算机。

这不是假设的可能性,而是已经发生并将再次发生的事情。

关于c++ - 指向多态类的悬挂指针会导致未定义的行为。它真的可以成为任何可以想象的腐败的根源吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30967242/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com