该篇博客是在对于序列化和反序列化进行一个简单的基本的学习后,进行笔记整理对该知识点的理解与其基础要点,主要内容参考如下两篇文章。
参考链接:
https://www.freebuf.com/articles/web/167721.html
https://www.cnblogs.com/youyoui/p/8610068.html
0x01 序列化
php的序列化发生于存储或传递值过程中。
php序列化函数为:
string serialize(mixed $value) // $value为要序列化的对象或数组
serialize()函数返回一个字符串,可以很方便的传递给其他需要该对象的地方,且其结构和类型不会改变。
实例:
<?php $sites = array('Google', 'Runoob', 'Facebook'); $serialized_data = serialize($sites); echo $serialized_data . PHP_EOL; ?>
输出结果为:
a:3:{i:0;s:6:"Google";i:1;s:6:"Runoob";i:2;s:8:"Facebook";}
序列化格式:
String : s:size:value;
Integer : i:value;
Boolean : b:value;(保存1或0)
Null : N;
Array : a:size:{key definition;value definition;(repeated per element)}
Object : O:strlen(object name):object name:object size:{s:strlen(property name):property name:property definition;(repeated per property)}
序列化对象时,不会保留类中常量值,会保留父类中变量。
序列化中常见的魔法函数:
__construct() 创建对象时调用
__destruct() 销毁对象时调用
__toString() 当一个对象被当作一个字符串使用
__sleep() 在对象在被序列化之前运行
__wakeup 将在序列化之后立即被调用
选择对象序列化的变量
主要使用魔法方法:
public array __sleep( void )
* 若序列化对象时__sleep()魔术方法存在,则优先调用该方法,一般在类中通过重载该魔术方法进行使用
* 该方法返回值为一个数组,数组中为选择的应被序列化的对象变量
* 若不返回任何变量名,则序列化NULL,并报错
* 该方法不能返回父类的私有成员变量名,否则会报错,可用Serializable接口代替
* 常用于对大对象保存时进行清理工作,避免保存冗余数据
0x02 反序列化
序列化将对象作为字符串保存起来,同时PHP提供了反序列化函数:
mixed unserialize( string $str)
* 若字符串不可反序列化,则返回false并报错
* 若字符串可反序列化,则可为前文序列化格式中的类型
* 若反序列化后的变量为一个对象,则在重新构造对象后,php会检测是否有魔法函数__wakeup(),并尝试调用
0x03 序列化和反序列化用途
序列化和反序列化一般用作数据的缓存,如cookie、session缓存等。再例如,项目中一个class中存有一些变量,该class实例化后若一直不销毁,在使用过程中对其中变量会造成修改,当下一次调用它时,会浪费系统资源,于是即可将该对象序列化,作为字符串存储,等到要使用时再反序列化调用。
序列化和反序列化在Java中使用相对较多,即如json数据。
在PHP中使用的主要函数如下:
json_encode()
json_decode()
总而言之,序列化与反序列化即为将项目中的对象序列化为字节流,方便存储及调用。
至此,只是对于序列化与反序列化的基础认识及理解,之后会通过对一些反序列化漏洞的CTF例题进行研究,从而深入理解与学习反序列化。