什么';在PHP7.4异常的源代码中唤醒的意义是什么?

什么';在PHP7.4异常的源代码中唤醒的意义是什么?,php,c,exception,deserialization,magic-methods,Php,C,Exception,Deserialization,Magic Methods,存在一种(相当新的)被称为的利用技术,该技术由PHP触发,如文件\u exists,取消链接。。。然后在实例化类中执行未序列化的代码,该类需要至少包含两个神奇方法\uuuu wakeup和\uu destruct中的一个 我的想法是在PHP的源代码中搜索内置的PHP类,这些类可能具有本机实现的神奇方法(\uuuu wakeup和\uuu destruct),作为此类类的一部分,并且可以在异常处理期间的反序列化过程中以某种方式被利用(这可能会在释放bug后触发某些使用)。事实上,我在几个异常类中发

存在一种(相当新的)被称为的利用技术,该技术由PHP触发,如
文件\u exists
取消链接
。。。然后在实例化类中执行未序列化的代码,该类需要至少包含两个神奇方法
\uuuu wakeup
\uu destruct
中的一个

我的想法是在PHP的源代码中搜索内置的PHP类,这些类可能具有本机实现的神奇方法(
\uuuu wakeup
\uuu destruct
),作为此类类的一部分,并且可以在异常处理期间的反序列化过程中以某种方式被利用(这可能会在释放bug后触发某些使用)。事实上,我在几个异常类中发现了
\uuuu wakeup
(获取所有内置类并检查它们是否具有
\uu wakeup
\uu destruct
方法的简单方法是使用PHP函数
获取声明的类()
)。但在目前看来,这似乎是无法开发的

所以问题不在于剥削

问题:我不明白的是为什么在异常中实现例如
\uu wakeup
?它是否只是一个占位符方法,用于扩展此类异常类并在以后编写自己的
\uuuu wakeup
/
\uuu destruct
方法

源代码:

第306-333行(php src/Zend/Zend_exceptions.c,php 7.4):

然后在第788-801行:


据我所知,这段代码正在验证异常属性的类型,如果类型不正确,则将它们设置为
null
。例如:

CHECK_EXC_TYPE(ZEND_STR_MESSAGE,  IS_STRING);
大致相当于PHP代码:

if (!is_string($this->message))
    $this->message = null;
类似地,结尾的代码以
pvalue=zend\u read\u property(…)
开始,检查
$this->previous
是否是一个实现可丢弃的对象。在PHP中,它大致相当于:

if (!is_object($this->previous) || !($this->previous instanceof Throwable)
    $this->previous = null;

至于为什么这段代码是PHP解释器的一部分?
异常
类的整体在这里用C代码定义。没有一个内置类或方法是用PHP编写的——它们不能,因为该语言无法将方法的PHP实现安装到用C声明的类中。

据我所知,这段代码正在验证异常属性的类型,如果类型不正确,则将其设置为
null
。例如:

CHECK_EXC_TYPE(ZEND_STR_MESSAGE,  IS_STRING);
大致相当于PHP代码:

if (!is_string($this->message))
    $this->message = null;
类似地,结尾的代码以
pvalue=zend\u read\u property(…)
开始,检查
$this->previous
是否是一个实现可丢弃的对象。在PHP中,它大致相当于:

if (!is_object($this->previous) || !($this->previous instanceof Throwable)
    $this->previous = null;

至于为什么这段代码是PHP解释器的一部分?
异常
类的整体在这里用C代码定义。没有一个内置类或方法是用PHP编写的——它们不能用PHP编写,因为该语言无法将方法的PHP实现安装到用C声明的类中。

我认为关键是,由于异常类应该是反序列化的,所以需要在C级添加
\uu wakeup()
方法(因为异常类属性也是在C中定义的)。

我认为问题的关键在于,由于异常类应该是反序列化的,所以它需要在C级别添加
\u wakeup()
方法(因为异常类属性也是在C中定义的).

好吧,你在描述
CHECK\u EXC\u TYPE
的代码。但是我很好奇为什么异常类的
\uuuu wakeup
方法需要在C级定义,而不是以后在PHP级,在PHP级我们可以定义像
\uu destruct
这样的神奇方法。所以我知道,我们在第306-333行中检查类型。但是什么呢这里定义
\uuuu wakeup
的意义是什么?在第788-801行中:
ZEND\u ME(异常,\uuuu wakeup,NULL,ZEND\u ACC\u PUBLIC)
只是说,
\uuuuu wakeup
是异常类的一部分,是公共的。就是这样。现在还不清楚它在这里做什么。让
\uuu wakeup
的意义在于它只在本地启用反序列化(而不定义自己的异常类)?但由于它没有
\u sleep
方法,它实际上不应该被序列化(但它仍然有效)。所以我觉得这毫无意义。“但我很好奇为什么异常类的
\u wakeup
方法需要在C级定义,而不是在PHP级定义。”--因为没有与
异常
类对应的PHP代码。该类完全是在PHP中定义的,所以任何方法都必须在那里定义。我认为你是对的。我认为关键是,由于异常类应该是反序列化的,所以需要在C级别添加
\uu wakeup()
方法(因为异常类属性也是在C中定义的)。也许你可以把你的评论移到上面的答案上,稍加修改,我就把它标记为已回答。再次感谢你。你正在描述
CHECK_EXC_TYPE
的代码。但是我很好奇为什么异常类的
\u wakeup
方法需要在C级定义,而不是在PHP级定义,比如说,在PHP级定义su像
\uuuu destruct
这样的神奇方法。所以我知道,我们正在检查第306-333行中的类型。但是在这里定义
\uuuu wakeup
有什么意义呢?在第788-801行:
ZEND\u ME(异常,\uu wakeup,NULL,ZEND\u ACC\u PUBLIC)
只是说,
\uuuuu wakeup
是异常类的一部分,是公共的。就是这样。现在还不清楚它在这里做什么。让
\uuu wakeup
的意义在于它只在本地启用反序列化(而不定义自己的异常类)?但由于它没有
\u sleep
方法,它实际上不应该被序列化(但它仍然有效)。所以我觉得这毫无意义。”但我很好奇为什么需要定义异常类的
\u wakeup
方法