Ste*_*and 10 c++ undefined-behavior dangling-pointer
我知道Undefined Behavior,一旦发生,就不可能再考虑代码了.我完全相信.我甚至认为我不应该过多地理解UB:一个理智的C++程序不应该与UB,Period一起玩.
但是为了让我的同事和经理们相信它的真正危险,我试图找到一个具体的例子,我们在产品中有一个错误(他们认为这不是危险的,最糟糕的是它总会崩溃访问违规).
我主要担心的是在悬挂指向多态类的指针时调用虚拟成员函数.
删除指针时,Windows操作系统将在堆块的标题中写入几个字节,并且通常还会覆盖堆块本身的第一个字节.这是跟踪堆块的方法,将它们作为链表进行管理......操作系统的东西.
虽然它没有在C++标准中定义,但多态性是使用虚拟表AFAIK实现的.在windows下,指向虚拟表的指针位于堆块的第一个字节中,给定一个只继承一个基类的类.(多继承可能更复杂,但我不会考虑这一点.我们只考虑基类A,以及几个B,C,D继承A).
现在让我们考虑我有一个指向A的指针,它被实例化为D对象.并且D对象已经在代码中的其他位置删除了:所以堆块现在是一个空闲的堆块,它的第一个字节已被覆盖,因此虚拟表指针几乎随机指向内存中的某个位置,让我们说地址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();
}
Run Code Online (Sandbox Code Playgroud)
我正确地说:
0x01234567就好像它是一个虚拟表一样0x098765430x09876543将被解释为有效的二进制代码,并且EXECUTED为real我不想夸大其词,以便说服.那么,我所说的是正确的,可能的,可能的吗?
你的例子是一种可能性。
然而,情况要糟糕得多。
如果有人攻击您的应用程序的用户,那么内存将不会包含随机数据。攻击者将尝试并可能设法影响该数据的内容。一旦发生这种情况,攻击者也许能够确定将执行哪些代码。一旦发生这种情况,除非您的应用程序被正确地沙箱化(我敢打赌,您的合作开发人员不会采取这种态度),否则攻击者可能能够接管用户的计算机。
这不是一种假设的可能性,而是已经发生并将再次发生的事情。
| 归档时间: |
|
| 查看次数: |
199 次 |
| 最近记录: |