文件上传代码分析
目录
- 不同类型的语言
- 脚本语⾔/解释型语⾔
- ⼀次编译到处运⾏
- 编译型语⾔
- 不同语⾔的webshell上传差异
- 脚本语⾔/解释型语⾔
- ⼀次编译到处运⾏
- 编译型语⾔
- ⽂件上传到webshell
- 任意⽂件上传
- js检测
- 解析规则
- MIME
- ⽂件头
- 后缀检测失效
- NTFS Tricks
不同类型的语言
脚本语⾔/解释型语⾔
代表就是php/jsp/asp这种,他们的运⾏模式是⼀套动态解释引擎+脚本代码,在这种运⾏模式
下,我们⼀旦能够获取cmdshell或者物理设备,等同于我们能看到全部的代码。
所以对于php/jsp/asp⽽⾔,简单记为我们能看到所有的代码,是纯⽩盒审计。
⼀次编译到处运⾏
代表就是java/python/.net
他们的运⾏模式是将代码编译成中间语
⾔,并且在不同的操作系统上运⾏有不同的虚拟机,由虚拟机来完成将中间语⾔(ir)run起
来的操作。因为其强⼤的跨平台能⼒,也迅速得到推⼴。
对于java/python/.net这种虚拟机+字节码的运⾏模式,我们简单记为,可以恢复并看到
80%以上的代码来进⾏审计,基本等于⽩盒审计。
编译型语⾔
C/go/c++
对于编译型语⾔,基本看不到代码。
不同语⾔的webshell上传差异
脚本语⾔/解释型语⾔
可以上传webshell并运⾏
⼀次编译到处运⾏
视情况⽽定:
python基本不能直接上传webshell,因为没办法路由到webshell⽂件。
java要看中间件,有的中间件解析jsp的情况下,是可以通过上传jsp的webshell,有的中间件
不解析jsp就没办法了。
.net也是⼀样的道理,但是从经验来看,.net搭建的⽹站很多可以直接上传aspx的webshell。
编译型语⾔
没有办法上传webshell,但是在某些情况下可以通过上传+其他利⽤来进⾏rce。
⽂件上传到webshell
⽂件上传能够到webshell,归根结底是2个层⾯的问题:后缀处理、运⾏环境(操作系统、中
间件)
任意⽂件上传
<?php
// 设置内容类型和字符编码
header("Content-type: text/html;charset=utf-8");
// 关闭错误报告
error_reporting(0);// 设置上传目录
define("UPLOAD_PATH", dirname(__FILE__) . "/upload/");
// 设置上传目录的URL路径
define("UPLOAD_URL_PATH", str_replace($_SERVER['DOCUMENT_ROOT'], "", UPLOAD_PATH));$is_upload = false;// 检查上传目录是否存在,如果不存在则创建
if (!file_exists(UPLOAD_PATH)) {mkdir(UPLOAD_PATH, 0755);
}// 检查是否提交了表单
if (!empty($_POST['submit'])) {// 检查是否有文件上传if (!$_FILES['file']['size']) {echo "<script>alert('请添加上传文件')</script>";} else {// 获取上传文件的文件名$name = basename($_FILES['file']['name']);// 移动上传的文件到指定目录if (move_uploaded_file($_FILES['file']['tmp_name'], UPLOAD_PATH . $name)) {$is_upload = true;} else {echo "<script>alert('上传失败')</script>";}}
}
?>
这是⼀个最简单的任意⽂件上传的原型,上传来的⽂件只是取了下⽂件名,就通过
move_uploaded_file写⼊到
UPLOAD_PATH . $name 去了。没有任何检查。
js检测
<?php
header("Content-type: text/html;charset=utf-8");
error_reporting(0);// 设置上传目录
define("UPLOAD_PATH", dirname(__FILE__) . "/upload/");
define("UPLOAD_URL_PATH", str_replace($_SERVER['DOCUMENT_ROOT'], "", UPLOAD_PATH));$is_upload = false;// 检查上传目录是否存在,如果不存在则创建
if (!file_exists(UPLOAD_PATH)) {mkdir(UPLOAD_PATH, 0755, true); // 添加了第三个参数true,以允许递归创建目录(如果需要的话)
}// 处理文件上传
if (!empty($_POST['submit'])) {if ($_FILES['file']['size'] == 0) {echo "<script>alert('请添加上传文件')</script>";} else {$name = basename($_FILES['file']['name']);if (move_uploaded_file($_FILES['file']['tmp_name'], UPLOAD_PATH . $name)) {$is_upload = true;} else {echo "<script>alert('上传失败')</script>";}}
}
?><!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>JavaScript 绕过</title><link href="./attachs/bootstrap.sketchy.min.css" rel="stylesheet">
</head>
<body><div class="container"><div class="jumbotron"><h1 class="text-center">永远不要相信用户的输入</h1><img src="./imgs/js.png" class="rounded mx-auto d-block" width="auto"><br><p class="lead">“永远不要相信用户的输入” 是进行安全设计和安全编码的重要准则。换句话说,任何输入数据在证明其无害之前,都是有害的。许多危险的漏洞就是因为过于相信用户的输入是善意的而导致的。</p><br><div><?phpif ($is_upload) {echo '<img src="./upload/' . $name . '" class="rounded mx-auto d-block" width="100px">';}?></div><form action="" method="post" enctype="multipart/form-data" onsubmit="return checkfilesuffix()"><div class="form-group"><label for="exampleFormControlFile1">文章插入图片</label><input type="file" class="form-control-file" name="file" id="file"><input type="submit" name="submit" value="Upload"></div></form></div></div><script>function checkfilesuffix() {var file = document.getElementsByName('file')[0].value;if (file == "" || file == null) {swal("请添加上传文件", "", "error");return false;} else {var whitelist = new Array(".jpg", ".png", ".gif", ".jpeg");var file_suffix = file.substring(file.lastIndexOf("."));if (whitelist.indexOf(file_suffix) == -1) {swal("只允许上传图片类型的文件!", "", "error");return false;}}return true; // 添加了返回true,以确保在文件后缀合法时表单能够提交}function error() {swal("上传失败", "", "error");}</script><script src="./attachs/sweetalert.min.js"></script>
</body>
</html>
在整个输⼊流转中,真正决定⽂件是否写⼊的是后端代码路由,⽽从它往前数,⽹络层⾯我们
是可控的,所以完全不必要去管js的事情。
解析规则
不同中间件不同版本有不同的利⽤⽅式
MIME
<?php
header("Content-type: text/html;charset=utf-8");
error_reporting(0); // 通常不建议在生产环境中完全关闭错误报告// 设置上传目录
define("UPLOAD_PATH", dirname(__FILE__) . "/upload/");
// 注意:UPLOAD_URL_PATH的定义可能不正确,它应该是一个相对于网站的URL路径
// 但当前代码尝试从服务器路径中移除DOCUMENT_ROOT,这通常不会得到正确的URL
define("UPLOAD_URL_PATH", str_replace($_SERVER['DOCUMENT_ROOT'], "", UPLOAD_PATH));if (!file_exists(UPLOAD_PATH)) {mkdir(UPLOAD_PATH, 0755); // 创建上传目录,权限设置为755
}$is_upload = false;if (!empty($_POST['submit'])) {// 检查文件类型是否为允许的图像类型if (!in_array($_FILES['file']['type'], ["image/jpeg", "image/png", "image/gif", "image/jpg"])) {// 注意:echo中的black()函数未定义,可能是想调用alert()或其他函数echo "<script>alert('文件类型不允许');</script>"; // 修改为alert,并给出明确的错误信息exit();} else {$name = basename($_FILES['file']['name']); // 获取上传文件的原始名称// 将文件从临时目录移动到指定上传目录if (move_uploaded_file($_FILES['file']['tmp_name'], UPLOAD_PATH . $name)) {$is_upload = true; // 标记文件上传成功} else {echo "<script>alert('上传失败');</script>"; // 文件上传失败时给出提示}}
}
?>
⽂件头
<?php
header("Content-type: text/html;charset=utf-8");
// 关闭错误报告(不推荐在生产环境中这样做)
error_reporting(0);// 设置上传目录
define("UPLOAD_PATH", dirname(__FILE__) . "/upload/");
// 注意:UPLOAD_URL_PATH的定义可能不正确,应该根据实际情况设置
define("UPLOAD_URL_PATH", str_replace($_SERVER['DOCUMENT_ROOT'], "", UPLOAD_PATH));// 如果上传目录不存在,则创建它
if (!file_exists(UPLOAD_PATH)) {mkdir(UPLOAD_PATH, 0755);
}$is_upload = false;if (!empty($_POST['submit'])) {// 检查文件大小是否为0if (!$_FILES['file']['size']) {echo "<script>alert('文件大小为0,上传失败');</script>";exit();}// 读取文件的前4个字节(文件头)$file = fopen($_FILES['file']['tmp_name'], "rb");$bin = fread($file, 4);fclose($file);// 检查文件类型(通过MIME类型和文件头)$allowedMimeTypes = ["image/jpeg", "image/jpg", "image/png", "image/gif"];$allowedFileHeaders = ["89504E47", "FFD8FFE0", "47494638"]; // 分别对应PNG, JPEG, GIF的文件头if (!in_array($_FILES['file']['type'], $allowedMimeTypes)) {echo "<script>alert('文件类型不允许');</script>";exit();} elseif (!in_array(bin2hex($bin), $allowedFileHeaders)) {echo "<script>alert('文件头不匹配,可能是非法文件');</script>";exit();}// 获取原始文件名$name = basename($_FILES['file']['name']);// 移动上传的文件到指定目录if (move_uploaded_file($_FILES['file']['tmp_name'], UPLOAD_PATH . $name)) {$is_upload = true;} else {echo "<script>alert('文件上传失败');</script>";}
}
?>
我们知道,⽂件头是⽂件格式的普适约定,⼀般在⼀个⽂件的前⼏个字节。
但是对于php/asp/jsp这种解释型语⾔⽽⾔,灵活性很强,并不要求脚本代码位于⽂件的开头,这样的话,我们就可以在开头使⽤图⽚⽂件的⽂件头,在中间或者后⾯的位置插⼊脚本语⾔,进⾏getshell。
与上⾯类似的,这种检测⽅式也没有触及到核⼼,并没有去检测filename字段的后缀。
后缀检测失效
后缀检测失效,指的是程序员已经想到要检测filename字段的后缀了,但是因为业务能⼒不熟练,在检测过程中被绕过了,导致webshell上传。
<?php
// ...(之前的代码,如header设置、错误报告关闭、上传目录定义等)if (!empty($_POST['submit'])) {// 获取上传文件的原始名称$name = basename($_FILES['file']['name']);// 定义黑名单,包含不允许上传的文件扩展名$blacklist = array("php", "php5", "php4", "php3", "phtml", "pht", "jsp", "jspa", "jspx", "jsw", "jsv", "jspf", "jtml", "asp", "aspx", "asa", "asax", "ascx", "ashx", "asmx", "cer", "swf", "htaccess", "ini");$name = str_ireplace($blacklist, "", $name);// 检查文件是否成功上传if (move_uploaded_file($_FILES['file']['tmp_name'], UPLOAD_PATH . $name)) {$is_upload = true;} else {// 上传失败,显示错误消息echo "<script>alert('文件上传失败');</script>";}
}
?>
将敏感后缀字符替换为空,那么就可以⽤pasxhp–>php来绕过
<?php
// 假设 UPLOAD_PATH 已经被定义为一个安全的上传目录路径if (!empty($_POST['submit'])) {// 获取上传文件的原始名称$name = basename($_FILES['file']['name']);// 定义黑名单,包含不允许上传的文件扩展名$blacklist = array("php", "php5", "php4", "php3", "phtml", "pht", "jsp", "jspa", "jspx", "jsw", "jsv", "jspf", "jtml", "asp", "aspx", "asa", "asax", "ascx", "ashx", "asmx", "cer", "swf", "htaccess", "ini");// 逐个替换黑名单中的扩展名为空格(注意:这种方法不安全,应该使用白名单)foreach ($blacklist as $extension) {$name = str_replace('.' . $extension, ' ', $name); // 注意添加点号来匹配完整的扩展名}// 移除文件名中多余的空格(可能由于多个扩展名被替换而产生)$name = preg_replace('/\s+/', '_', $name); // 使用下划线替换空格,或者您可以选择删除它们// 为了安全起见,这里应该添加额外的逻辑来确保 $name 只包含允许的字符和格式// 例如,您可以使用 pathinfo 来获取文件的扩展名,并检查它是否在您的白名单中// 但由于我们坚持使用黑名单方法(尽管不推荐),我们将跳过这一步// 检查文件是否成功上传if (move_uploaded_file($_FILES['file']['tmp_name'], UPLOAD_PATH . $name)) {$is_upload = true;} else {// 上传失败,显示错误消息// 注意:在实际应用中,应该避免使用 JavaScript alert 来显示错误消息,因为这可能会暴露敏感信息// 更好的做法是在服务器端记录错误,并向用户显示一个通用的错误页面echo "<script>alert('文件上传失败,请重试。');</script>";}
}
?>
将敏感后缀字符替换成空格,那么以上的利⽤不能绕过了。但是这⾥忽略了运⾏
环境的因素,在windows下⼤⼩写通⽤,所以可以上传PHP后缀进⾏绕过。
<?php
// 定义允许上传的文件扩展名白名单
$whitelist = array("jpg", "jpeg", "png", "gif");// 假设 UPLOAD_PATH 是一个已定义的常量,指向安全的上传目录
define('UPLOAD_PATH', '/path/to/upload/directory/');// 确保上传目录存在且可写
if (!is_dir(UPLOAD_PATH) || !is_writable(UPLOAD_PATH)) {die('上传目录不存在或不可写。');
}// 检查是否提交了上传表单
if (!empty($_POST['submit'])) {// 获取上传文件的原始名称$originalName = basename($_FILES['file']['name']);// 获取文件的扩展名(不区分大小写)$ext = strtolower(pathinfo($originalName, PATHINFO_EXTENSION));// 检查文件的扩展名是否在白名单中if (in_array($ext, $whitelist)) {// 生成一个新的文件名(避免使用原始文件名,以防止安全问题)$newName = uniqid() . '.' . $ext;// 检查文件是否成功上传if (move_uploaded_file($_FILES['file']['tmp_name'], UPLOAD_PATH . $newName)) {$is_upload = true;echo "<script>alert('文件上传成功!');</script>";} else {// 上传失败,显示错误消息echo "<script>alert('文件上传失败,请重试。');</script>";}} else {// 文件扩展名不在白名单中,显示错误消息echo "<script>alert('不允许的文件类型。');</script>";}
} else {// 没有提交上传表单,可能显示一个上传表单echo '<form action="" method="post" enctype="multipart/form-data"><input type="file" name="file"><input type="submit" name="submit" value="上传"></form>';
}
?>
NTFS Tricks
这个技巧对于⼀些,限制⽐较严格的⿊名单检测,特别有效。
<?php
// 定义上传路径常量(请确保这是一个安全的路径)
define('UPLOAD_PATH', '/path/to/your/upload/directory/');// 确保上传目录存在且可写
if (!is_dir(UPLOAD_PATH) || !is_writable(UPLOAD_PATH)) {die('上传目录不存在或不可写。');
}// 检查是否提交了文件上传表单
if (!empty($_FILES['file']) && $_SERVER['REQUEST_METHOD'] === 'POST') {// 获取上传文件的原始名称$originalName = basename($_FILES['file']['name']);// 获取文件的扩展名(转换为小写)$ext = strtolower(pathinfo($originalName, PATHINFO_EXTENSION));// 定义黑名单数组$blacklist = array("php", "php5", "php4", "php3", "phtml", "pht", "jsp", "jspa", "jspx", "jsw", "jsv", "jspf", "jtml", "asp", "aspx", "asa", "asax", "ascx", "ashx", "asmx", "cer", "swf", "htaccess", "ini");// 如果文件扩展名不在黑名单中if (!in_array($ext, $blacklist)) {// 为了安全起见,生成一个新的文件名(避免使用原始文件名)$name = uniqid() . '.' . $ext;// 尝试移动上传的文件到指定目录if (move_uploaded_file($_FILES['file']['tmp_name'], UPLOAD_PATH . $name)) {$is_upload = true; // 文件上传成功标志(虽然在这个脚本中没有被进一步使用)echo "<script>alert('文件上传成功!');</script>"; // 显示成功消息(注意:在实际应用中,应避免在客户端显示敏感信息)} else {// 上传失败,显示错误消息echo "<script>alert('文件上传失败,请重试。');</script>"; // 显示失败消息(同样,应避免在客户端显示敏感信息)}} else {// 文件扩展名在黑名单中,显示错误消息echo "<script>alert('不允许的文件类型。');</script>"; // 显示黑名单错误消息(同样,应避免在客户端显示敏感信息)}
} else {// 没有提交文件上传表单或请求方法不是POST// 这里可以显示一个文件上传表单或其他内容echo '<form action="" method="post" enctype="multipart/form-data"><input type="file" name="file"><input type="submit" value="上传"></form>';
}
?>
此时,如果在windwos下可以上传shell.php::$DATA即可绕过。最终shell为shell.php。
相关文章:
文件上传代码分析
目录 不同类型的语言脚本语⾔/解释型语⾔⼀次编译到处运⾏编译型语⾔ 不同语⾔的webshell上传差异脚本语⾔/解释型语⾔⼀次编译到处运⾏编译型语⾔ ⽂件上传到webshell任意⽂件上传js检测解析规则MIME⽂件头后缀检测失效 NTFS Tricks 不同类型的语言 脚本语⾔/解释型语⾔ 代表…...
深入解析分布式遗传算法及其Python实现
目录 深入解析分布式遗传算法及其Python实现目录第一部分:分布式遗传算法的背景与原理1.1 遗传算法概述1.2 分布式遗传算法的引入1.3 分布式遗传算法的优点与挑战优点:挑战:第二部分:分布式遗传算法的通用Python实现2.1 基本组件的实现第三部分:案例1 - 基于多种交叉与变异…...
World of Warcraft /script SetRaidTarget(“target“, n, ““) n=8,7,6,5,4,3,2,1,0
魔兽世界执行当前目标标记方法 /script SetRaidTarget("target", n, "") n8,7,6,5,4,3,2,1,0 解析这个lua脚本 D:\Battle.net\World of Warcraft\_classic_\Interface\AddOns\wMarker wMarker.lua /script SetRaidTarget("target", 8, &quo…...
django authentication 登录注册
文章目录 前言一、django配置二、后端实现1.新建app2.编写view3.配置路由 三、前端编写1、index.html2、register.html3、 login.html 总结 前言 之前,写了django制作简易登录系统,这次利用django内置的authentication功能实现注册、登录 提示ÿ…...
阿里云整理(一)
阿里云整理 1. 介绍规模 2. 专业名词2.1 专有网络VPC2.2 安全组SG2.3 云服务器ECS2.4 资源组2.5 部署集2.5 web测试 1. 介绍 阿里云是一家提供云计算和人工智能服务的科技公司,成立于2009年,总部位于杭州。它为全球客户提供全方位的云服务ÿ…...
鸿蒙NEXT开发案例:文字转拼音
【引言】 在鸿蒙NEXT开发中,文字转拼音是一个常见的需求,本文将介绍如何利用鸿蒙系统和pinyin-pro库实现文字转拼音的功能。 【环境准备】 • 操作系统:Windows 10 • 开发工具:DevEco Studio NEXT Beta1 Build Version: 5.0.…...
Redis高级
目录 Redis事务 语法错误 执行错误 Redis持久化 RDB持久化 RDB原理 小结 AOF持久化 AOF原理 AOF配置 AOF文件重写 RDB与AOF对比 Redis主从复制架构 搭建主从复制架构 在redis目录创建三个目录 把原来的redis.conf配置分件分贝复制一件到这三个目录中 修改配置文件…...
八股文-基础知识-面试题汇总(一)
面向对象和面向过程的区别? 面向对象和面向过程是两种不同的编程范式,它们在设计和实现软件时有着不同的理念和方法。面向对象更适合大型、复杂的项目,尤其是需要维护和扩展的系统;而面向过程更适合小型、线性的任务或对性能要求…...
玩转合宙Luat教程 基础篇④——程序基础(库、线程、定时器和订阅/发布)
文章目录 一、前言二、库三、线程四、定时器五、订阅/发布5.1 回调函数5.2 堵塞等待一、前言 教程目录大纲请查阅:玩转合宙Luat教程——导读 写一写Lua程序基础的东西。 包括如何调用库,如何创建线程、如何创建定时器,如何使用订阅/发布事件。 二、库 程序从main.lua开始通…...
openssl颁发包含主题替代名的证书–SAN
原文地址:openssl颁发包含主题替代名的证书–SAN – 无敌牛 欢迎参观我的个人博客:无敌牛 – 技术/著作/典籍/分享等 在 X.509 证书中,commonName(CN)字段只能有一个值。如果让证书支持多个域名和IP地址,…...
Unity 2020、2021、2022、2023、6000下载安装
Unity 2020、2021、2022、2023、6000 下载安装 以Unity 6000.0.24fc1下载安装为例: 打开 https://unity.cn/ 优三缔 官方网站; 点击【产品列表】→点击【查看更多】→选择自己需要的版本→点【开始使用】 点击【从Unity Hub下载】 以Windows为例&am…...
Zustand:一个轻量级的React状态管理库
文章目录 前言一、安装Zustand二、使用Zustand三、实际案例结语 前言 在现代Web开发中,状态管理是一个常见的需求,特别是在构建大型或复杂的单页面应用程序(SPA)时。React等框架虽然提供了基本的状态管理功能,但对于复…...
信创改造 - TongRDS 替换 Redis
记得开放 6379 端口哦 1)首先在服务器上安装好 TongRDS 2)替换 redis 的 host,post,passwd 3)TongRDS 兼容 jedis # 例如:更改原先 redis 中对应的 host,post,passwd 改成 TongRDS…...
Css—实现3D导航栏
一、背景 最近在其他的网页中看到了一个很有趣的3d效果,这个效果就是使用css3中的3D转换实现的,所以今天的内容就是3D的导航栏效果。那么话不多说,直接开始主要内容的讲解。 二、效果展示 三、思路解析 1、首先我们需要将这个导航使用一个大…...
Unity清除所有的PlayerPrefs
方法1: 直接在你的代码中加入这句 PlayerPrefs.DeleteAll(); 方法2: 点击编辑窗口的这里...
[蓝桥杯 2021 省 AB2] 小平方
题目描述 小蓝发现,对于一个正整数 nn 和一个小于 nn 的正整数 vv,将 vv 平方后对 nn 取余可能小于 nn 的一半,也可能大于等于 nn 的一半。 请问,在 11 到 n−1n−1 中, 有多少个数平方后除以 nn 的余数小于 nn 的一半。 例如&…...
三种蓝牙架构实现方案
一、蓝牙架构方案 1、hostcontroller双芯片标准架构 手机里面包含很多SoC或者模块,每颗SoC或者模块都有自己独有的功能,比如手机应用跑在AP芯片上,显示屏,3G/4G通信,WiFi/蓝牙等都有自己专门的SoC或者模块࿰…...
MacOS系统上Jmeter 录制脚本遇到的证书坑位
一、JMeter介绍与安装 1,下载及安装 jmeter官网地址 二、录制百度链接https请求时,需要导入jmeter相关证书到macos系统的更目录中. 导入方式,直接拖入mac的系统中,始终新人就可以; 三、jmeter 创建相关的录制组件…...
【Linux学习】【Ubuntu入门】2-3 make工具和makefile引入
1.使用命令新建三个.c文件vi main.c,vi input.c,vi caclcu.c,两个.h文件vi input.h,vi caclcu.h 2.vi Makefile:新建Makefile文件,输入一下内容 注意:命令列表中每条命令前用TAB键,不…...
conda下载与pip下载的区别
一、conda下载与pip下载的区别 最重要是依赖关系: pip安装包时,尽管也对当前包的依赖做检查,但是并不保证当前环境的所有包的所有依赖关系都同时满足。 当某个环境所安装的包越来越多,产生冲突的可能性就越来越大。conda会检查当…...
ubity3D基础
Unity是一个流行的游戏开发引擎,它使用C#作为其主要的编程语言。以下是一些Unity中C#编程的基础概念: • Unity编辑器: • Unity编辑器是Unity游戏引擎的核心,提供了一个可视化界面,用于创建和管理游戏项目。 • C#脚本…...
408数据结构:栈、队列和数组选择题做题笔记
408数据结构 第一章 绪论 第二章 线性表 绪论、线性表选择题做题笔记 第三章 栈、队列和数组 栈、队列和数组选择题做题笔记 文章目录 408数据结构前言 一、队列二、栈和队列的应用总结 前言 本篇文章为针对王道25数据结构课后习题的栈、队列和数组的做题笔记,后续…...
如何在 Eclipse 中调试ABAP程序
原文链接:Debugging an ABAP Program ADT 中的调试器是一个重要的诊断工具,可用于分析 ABAP 应用程序。 使用调试器,您可以通过在运行时 Debug 单步执行(F5)程序来确定程序无法正常工作的原因。这使您可以看到正在执…...
React(五)——useContecxt/Reducer/useCallback/useRef/React.memo/useMemo
文章目录 项目地址十六、useContecxt十七、useReducer十八、React.memo以及产生的问题18.1组件嵌套的渲染规律18.2 React.memo18.3 引出问题 十九、useCallback和useMemo19.1 useCallback对函数进行缓存19.2 useMemo19.2.1 基本的使用19.2.2 缓存属性数据 19.2.3 对于更新的理解…...
ISUP协议视频平台EasyCVR萤石设备视频接入平台银行营业网点安全防范系统解决方案
在金融行业,银行营业厅的安全保卫工作至关重要,它不仅关系到客户资金的安全,也关系到整个银行的信誉和运营效率。随着科技的发展,传统的安全防护措施已经无法满足现代银行对于高效、智能化安全管理的需求。 EasyCVR视频汇聚平台以…...
Ubuntu20.04下安装向日葵
向日葵远程控制app官方下载 - 贝锐向日葵官网 下载Ununtu版的图形版本的安装deb包SunloginClient_15.2.0.63064_amd64.deb 直接执行 sudo dpkg -i SunloginClient_15.2.0.63064_amd64.deb 的话会报错: 如果在Ubuntu20.04里直接执行sudo apt install libgconf-2-4安装libgco…...
sql工具!好用!爱用!
SQLynx的界面设计简洁明了,操作逻辑清晰易懂,没有复杂的图标和按钮,想对哪部分操作就在哪里点击右键,即使你是数据库小白也能轻松上手。 尽管SQLynx是一款免费的工具,但是它的功能却丝毫不逊色于其他付费产品ÿ…...
Pytest-Bdd-Playwright 系列教程(13):钩子(hooks)
Pytest-Bdd-Playwright 系列教程(13):钩子(hooks) 前言一、什么是钩子?二、Pytest-Bdd 提供的钩子一览三、钩子用法详解1. pytest_bdd_before_scenario2. pytest_bdd_after_scenario3. pytest_bdd_before_s…...
【React 进阶】掌握 React18 全部 Hooks
一、数据更新驱动 1. useState 1. 基础介绍 useState主要用于声明和操作状态变量,可以使函数组件像类组件一样拥有state const [state, setState] useState(initialState);state:状态,作为渲染视图的数据源 setState:改变st…...
泥石流灾害风险评估与模拟丨AI与R语言、ArcGIS、HECRAS融合,提升泥石流灾害风险预测的精度和准确性
目录 第一章 理论基础 第二章 泥石流风险评估工具 第三章 数据准备与因子提取 第四章 泥石流灾害评价 第五章 HECRAS软件的应用 第六章 操作注意事项与模型优化 泥石流灾害的频发与严重后果,已成为全球范围内防灾减灾工作的重大挑战。随着科技的不断进步&…...
用js实现点击抽奖
用原生的JS来完成的一个小游戏,进行了简单的点击触发以及判断 css: <style>* {margin: 0;padding: 0;}body {background-color: #f7f7f7;display: flex;justify-content: center;align-items: center;height: 100vh;margin: 0;}.container {backg…...
JVM-类文件结构
类文件结构 JVM 的“无关性” 谈论 JVM 的无关性,主要有以下两个: 平台无关性:任何操作系统都能运行 Java 代码 语言无关性: JVM 能运行除 Java 以外的其他代码 Java 源代码首先需要使用 Javac 编译器编译成 .class 文件ÿ…...
丹摩征文活动|实现Llama3.1大模型的本地部署
文章目录 1.前言2.丹摩的配置3.Llama3.1的本地配置4. 最终界面 丹摩 1.前言 Llama3.1是Meta 公司发布的最新开源大型语言模型,相较于之前的版本,它在规模和功能上实现了显著提升,尤其是最大的 4050亿参数版本,成为开源社区中非常…...
深入探讨异步 API 的设计与实现
一、API 模式简介:同步与异步的对比 API 是客户端和服务器之间通信的桥梁。大多数 API 采用同步模式,执行的流程如下: 客户端发送请求。服务器处理请求。服务器返回响应。 同步模式对快速操作非常有效,比如数据查询或简单更新。…...
多模态大型语言模型(MLLM)综述
目录 多模态大语言模型的基础 长短期网络结构(LSTM) 自注意力机制 基于Transformer架构的自然语言处理模型 多模态嵌入概述 多模态嵌入关键步骤 多模态嵌入现状 TF-IDF TF-IDF的概念 TF-IDF的计算公式 TF-IDF的主要思路 TF-IDF的案例 训练和微调多模态大语言模…...
EasyPlayer-pro视频流播放学习
效果: 知识抢先看: 动态创建节点指的是通过 JavaScript 操作 DOM 来生成 HTML 元素并插入到页面中 document.createElement: 创建新的 HTML 元素节点。 // 创建一个 <div> 元素 const div document.createElement(div); // 设置其属性 div.id my…...
STM32F103C8T6实时时钟RTC
目录 前言 一、RTC基本硬件结构 二、Unix时间戳 2.1 unix时间戳定义 2.2 时间戳与日历日期时间的转换 2.3 指针函数使用注意事项 三、RTC和BKP硬件结构 四、驱动代码解析 前言 STM32F103C8T6外部低速时钟LSE(一般为32.768KHz)用的引脚是PC14和PC…...
springboot获取配置文件中的值
概括 在开发过程中,对于一些通用的配置,通常会定在一个配置文件中。通常为application.properties或者application.yml文件中。我们只需要在需要使用的地方通过注解直接获取即可。 使用 在springboot中可以通过使用value注解来读取配置文件中的属性。…...
Python 爬虫从入门到(不)入狱学习笔记
爬虫的流程:从入门到入狱 1 获取网页内容1.1 发送 HTTP 请求1.2 Python 的 Requests 库1.2 实战:豆瓣电影 scrape_douban.py 2 解析网页内容2.1 HTML 网页结构2.2 Python 的 Beautiful Soup 库 3 存储或分析数据(略) 一般爬虫的基…...
STM32C011开发(1)----开发板测试
STM32C011开发----1.开发板测试 概述硬件准备视频教学样品申请源码下载参考程序生成STM32CUBEMX串口配置LED配置堆栈设置串口重定向主循环演示 概述 STM32C011F4P6-TSSOP20 评估套件可以使用户能够无缝评估 STM32C0 系列TSSOP20 封装的微控制器功能,基于 ARM Corte…...
【GAMES101笔记速查——Lecture 19 Cameras,Lenses and Light Fields】
本章节内容:相机、棱镜、光场 计算机图形学的两种成像方法: 1.合成方法:光栅化、光线追踪(展示出现实没有的东西) 2.捕捉方法:相机(捕捉现实已有的东西) 目录 1 相机 1.1 针孔相…...
记录两次Unity编辑器和真机表现不符的情况,引用丢失等
如题,问题是在编辑器和打包在真机测试上的效果不一致。 首先,第一次遇到的问题是编辑器和真机上大量资源不符和丢失,多次对比表现为,异常和丢失内容都是两个版本之间变更的资源,判定为资源引用异常,尝试删…...
【Win】user32.SetWindowsHookExW - Notes
user32.SetWindowsHookExW user32.SetWindowsHookExW(idHook, lpfn, hMod, dwThreadId)用于在系统中安装钩子函数,以监视某些系统事件或消息。 Parameters idHook: int - 安装钩子的类型标识符;对应于不同的系统事件或消息类别。lpfn: callable - 指向…...
泷羽sec-linux
基础之linux 声明! 学习视频来自B站up主 泷羽sec 有兴趣的师傅可以关注一下,如涉及侵权马上删除文章,笔记只是方便各位师傅的学习和探讨,文章所提到的网站以及内容,只做学习交流,其他均与本人以及泷羽sec团…...
二叉树oj题解析
二叉树 二叉树的最近公共祖先什么是最近公共祖先?leetcode中求二叉树中最近公共祖先解题1.解题2. 根据二叉树创建字符串 二叉树的最近公共祖先 什么是最近公共祖先? 最近的公共祖先指的是这一棵树中两个节点中深度最大的且公共的祖先节点就是最近祖先节…...
python画图|无坐标轴自由划线操作fig.add_artist(lines.Line2D()函数
【1】引言 新发现了一种自由划线操作函数,和大家共享。 【2】官网教程 点击下述代码,直达官网: https://matplotlib.org/stable/gallery/misc/fig_x.html#sphx-glr-gallery-misc-fig-x-py 官网代码非常简洁,我进行了解读。 …...
Flutter封装Coap
前言 我们根据Coap数据通信流程写一个公共组件,用户只要在原本的组件外嵌套这个公共组件就可以使用Coap的功能,这样做更加的方便便捷。 具体步骤 封装一个udp函数 创建一个工厂函数,工厂函数初始化时监听广播数据发送广播函数:…...
openharmony napi调试笔记
一、动态库的编译 第一种openharmony交叉编译链配置方法 使用的编译环境是ubuntu20.04 1、使用vscode配置openharmony sdk交叉编译环境 首先下载openharmony的sdk,如native-linux-x64-4.1.7.5-Release.zip 解压后native目录下就是交叉编译用的sdk 在要编译的源…...
C++数据结构与算法
C数据结构与算法 1.顺序表代码模版 C顺序表模版 #include <iostream> using namespace std; // 可以根据需要灵活变更类型 #define EleType intstruct SeqList {EleType* elements;int size;int capacity; };// Init a SeqList void InitList(SeqList* list, int capa…...
MATLAB深度学习(六)——LSTM长短期神经网络原理与应用
LSTM的应用可以参见一个相当好的视频:小车倒立摆最优控制教程 - Part1 Simulink Simscape Multibody仿真建模_哔哩哔哩_bilibili 6.1 序列建模——循环神经网络 循环神经网络RNN是一类专门用于处理序列性数据x,,xn的神经网络结构,…...