MetInfo6.0.0目录遍历漏洞原理分析
所需进行代码审计的文件路径:
C:\phpStudy\WWW\MetInfo6.0.0\include\thumb.php
C:\phpStudy\WWW\MetInfo6.0.0\app\system\entrance.php
C:\phpStudy\WWW\MetInfo6.0.0\app\system\include\class\load.class.php
C:\phpStudy\WWW\MetInfo6.0.0\app\system\include\moduleold_thumb.class.php
文件间的关联与作用
thumb.php:
<?php # MetInfo Enterprise Content Management System # Copyright (C) MetInfo Co.,Ltd (http://www.metinfo.cn). All rights reserved. define('M_NAME', 'include'); define('M_MODULE', 'include'); define('M_CLASS', 'old_thumb'); define('M_ACTION', 'doshow'); require_once '../app/system/entrance.php'; # This program is an open source system, commercial use, please consciously to purchase commercial license. # Copyright (C) MetInfo Co., Ltd. (http://www.metinfo.cn). All rights reserved. ?>此文件定义了 4 个常量。
M_NAME和M_MODULE被设为include,虽在此漏洞利用过程中未直接起关键作用,但它们是系统模块标识的一部分。重点是M_CLASS被定义为old_thumb,M_ACTION被定义为doshow,这两个常量为系统后续确定执行的类和方法提供了核心标识。同时,通过require_once '../app/system/entrance.php';引入系统入口文件 entrance.php,启动整个系统执行流程。重点代码:
<?php define('M_CLASS', 'old_thumb'); define('M_ACTION', 'doshow'); require_once '../app/system/entrance.php'; ?>
define函数:
define('M_CLASS', 'old_thumb');:这行代码使用define函数定义了一个名为M_CLASS的常量,并将其值设置为old_thumb。常量在整个脚本执行过程中值是固定不变的,不能被重新赋值。define('M_ACTION', 'doshow');:同样使用define函数定义了名为M_ACTION的常量,值为doshow。这些常量后续会被用来确定系统要执行的类和类中的方法。require_once语句:
require_once '../app/system/entrance.php';:require_once是 PHP 中用于引入外部文件的语句。它会尝试引入../app/system/entrance.php文件。如果该文件已经被引入过,require_once不会再次引入,以避免重复引入导致的问题。在这里,它的作用是启动系统的执行流程,进入entrance.php文件继续执行。
entrance.php:
//当前访问的主机名 define ('HTTP_HOST', isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : $_SERVER['SERVER_NAME']); //来源页面 define('HTTP_REFERER', $_SERVER['HTTP_REFERER']); //来源页面 define('REQUEST_URI', $_SERVER['REQUEST_URI']);//脚本路径 $phpfile = basename(__FILE__); $_SERVER['PHP_SELF']=htmlentities($_SERVER['PHP_SELF']); define ('PHP_SELF', $_SERVER['PHP_SELF']=="" ? $_SERVER['SCRIPT_NAME'] : $_SERVER['PHP_SELF']);if (!preg_match('/^[A-Za-z0-9_]+$/', M_TYPE.M_NAME.M_MODULE.M_CLASS.M_ACTION)) {echo 'Constants must be numbers or letters or underlined';die(); }require_once PATH_SYS_CLASS.'load.class.php';load::module();# This program is an open source system, commercial use, please consciously to purchase commercial license. # Copyright (C) MetInfo Co., Ltd. (http://www.metinfo.cn). All rights reserved.该文件首先定义了与 HTTP 请求和服务器相关的常量,如
HTTP_HOST用于获取当前访问的主机名,HTTP_REFERER记录来源页面,REQUEST_URI表示当前请求的 URI 等。这些常量主要用于系统对请求环境的识别和记录,但与本次路径穿越漏洞利用无直接关联。接着,它对M_TYPE.M_NAME.M_MODULE.M_CLASS.M_ACTION进行正则匹配检查,确保其由数字、字母或下划线组成,目的是保证系统常量的规范性。关键在于require_once PATH_SYS_CLASS.'load.class.php';引入了load.class.php文件,并调用load::module();方法。在调用load::module()方法时,默认会依据 thumb.php 中定义的M_CLASS和M_ACTION常量来确定要加载的类和执行的动作,由此建立起与 thumb.php 和load.class.php的紧密联系。重点代码:
require_once PATH_SYS_CLASS.'load.class.php'; load::module();
require_once语句:
require_once PATH_SYS_CLASS.'load.class.php';:这行代码引入了load.class.php文件,PATH_SYS_CLASS是一个预定义的路径常量(在提供的代码中虽然没有看到它的定义,但从代码逻辑推测应该是存在的),它和'load.class.php'拼接成完整的文件路径。引入这个文件是为了使用其中定义的load类及其相关方法。load::module()方法调用:
load::module();:这里调用了load类的静态方法module。load类定义在load.class.php文件中,module方法的作用是根据传入的参数(如果没有传入参数则使用默认值)来加载相应的类并执行类中的方法。在这个调用中,由于没有传入参数,它会使用默认的参数值,而默认值就与thumb.php中定义的M_CLASS和M_ACTION常量相关。
load.class.php:
class load {// ...public static function module($path = '', $modulename = '', $action = '') {if (!$path) {if (!$path) $path = PATH_OWN_FILE;if (!$modulename) $modulename = M_CLASS;if (!$action) $action = M_ACTION;if (!$action) $action = 'doindex';}return self::_load_class($path, $modulename, $action);}// ...private static function _load_class($path, $classname, $action = '') {$classname=str_replace('.class.php', '', $classname);$is_myclass = 0;if(!self::$mclass[$classname]){if(file_exists($path.$classname.'.class.php')){require_once $path.$classname.'.class.php';} else {echo str_replace(PATH_WEB, '', $path).$classname.'.class.php is not exists';exit;}$myclass = "my_{$classname}";if (file_exists($path.'myclass/'.$myclass.'.class.php')) {$is_myclass = 1;require_once $path.'myclass/'.$myclass.'.class.php';}}if ($action) {if (!class_exists($classname)) {die($classname . ' ' . $action . ' class\'s file is not exists!!!');}if(self::$mclass[$classname]){$newclass = self::$mclass[$classname];}else{if($is_myclass){$newclass = new $myclass;}else{$newclass = new $classname;}self::$mclass[$classname] = $newclass;}if ($action!='new') {if(substr($action, 0, 2) != 'do'){die($action.' function no permission load!!!');}if(method_exists($newclass, $action)){call_user_func(array($newclass, $action));}else{die($action.' function is not exists!!!');}}return $newclass;}return true;}// ... }该文件提供了一系列加载类、函数库、模块等的方法。其中
load::module方法至关重要,在没有传入特定参数时,它会使用默认值。这里if (!$modulename) $modulename = M_CLASS;和if (!$action) $action = M_ACTION;,意味着会使用 thumb.php 中定义的M_CLASS(即old_thumb)和M_ACTION(即doshow)。然后调用self::_load_class方法。_load_class方法会先检查要加载的类文件是否存在,若存在则引入。当$action存在且符合条件(以do开头)时,会实例化类并调用类中的对应方法。由于load::module方法在 entrance.php 中被调用,且根据 thumb.php 的常量设置,最终会调用old_thumb类的doshow方法。重点代码:
class load {public static function module($path = '', $modulename = '', $action = '') {if (!$modulename) $modulename = M_CLASS;if (!$action) $action = M_ACTION;return self::_load_class($path, $modulename, $action);}private static function _load_class($path, $classname, $action = '') {if ($action) {if (!class_exists($classname)) {die($classname . ' ' . $action . ' class\'s file is not exists!!!');}$newclass = new $classname;if ($action!='new') {if(substr($action, 0, 2) == 'do' && method_exists($newclass, $action)) {call_user_func(array($newclass, $action));}}return $newclass;}return true;} }
module方法:
public static function module($path = '', $modulename = '', $action = ''):这是load类的一个公共静态方法,接受三个参数$path(文件路径)、$modulename(类名)和$action(要执行的方法名)。if (!$modulename) $modulename = M_CLASS;:如果没有传入$modulename参数,就使用M_CLASS常量的值作为类名。if (!$action) $action = M_ACTION;:同理,如果没有传入$action参数,就使用M_ACTION常量的值作为要执行的方法名。return self::_load_class($path, $modulename, $action);:调用_load_class方法,并将当前的参数传递过去,_load_class方法会负责加载类并执行相应的方法。_load_class方法:
private static function _load_class($path, $classname, $action = ''):这是一个私有静态方法,用于实际加载类和执行方法。if ($action):检查是否传入了$action参数,如果有传入才会继续执行后续逻辑。if (!class_exists($classname)):检查指定的类名$classname是否存在,如果不存在就输出错误信息并终止脚本执行。$newclass = new $classname;:如果类存在,就实例化这个类。if ($action!='new'):如果$action不是new,则继续检查。if(substr($action, 0, 2) == 'do' && method_exists($newclass, $action)):检查$action是否以do开头,并且类中是否存在这个方法,如果满足条件,就使用call_user_func函数调用类中的方法。
old_thumb.class.php:
<?php # MetInfo Enterprise Content Management System # Copyright (C) MetInfo Co.,Ltd (http://www.metinfo.cn). All rights reserved.defined('IN_MET') or exit('No permission');load::sys_class('web');class old_thumb extends web{public function doshow(){global $_M;$dir = str_replace(array('../','./'), '', $_GET['dir']);if(substr(str_replace($_M['url']['site'], '', $dir),0,4) == 'http' && strpos($dir, './') === false){header("Content-type: image/jpeg");ob_start();readfile($dir);ob_flush();flush();die;}if($_M['form']['pageset']){$path = $dir."&met-table={$_M['form']['met-table']}&met-field={$_M['form']['met-field']}";}else{$path = $dir;}$image = thumb($path,$_M['form']['x'],$_M['form']['y']);if($_M['form']['pageset']){$img = explode('?', $image);$img = $img[0];}else{$img = $image;}if($img){header("Content-type: image/jpeg");ob_start();readfile(PATH_WEB.str_replace($_M['url']['site'], '', $img));ob_flush();flush();}} } # This program is an open source system, commercial use, please consciously to purchase commercial license. # Copyright (C) MetInfo Co., Ltd. (http://www.metinfo.cn). All rights reserved.此文件定义了
old_thumb类,其中doshow方法存在路径穿越漏洞。在doshow方法中,$dir = str_replace(array('../','./'), '', $_GET['dir']);从$_GET中获取dir参数,并尝试通过str_replace函数移除../和./来进行简单过滤。但这种过滤方式存在严重缺陷,攻击者可构造特殊输入如....//绕过过滤。随后,若满足一定条件,会使用readfile($dir);函数读取文件。若攻击者成功绕过过滤,就能利用该函数读取服务器上的任意文件,例如敏感文件/etc/passwd,从而导致敏感信息泄露。重点代码:
class old_thumb {public function doshow() {$dir = str_replace(array('../','./'), '', $_GET['dir']);if(substr(str_replace($_M['url']['site'], '', $dir),0,4) == 'http' && strpos($dir, './') === false){readfile($dir);}// ... 其他逻辑if ($img) {readfile(PATH_WEB.str_replace($_M['url']['site'], '', $img));}} }
old_thumb类:
class old_thumb:定义了一个名为old_thumb的类。doshow方法:
public function doshow():这是old_thumb类的一个公共方法。$dir = str_replace(array('../','./'), '', $_GET['dir']);:从$_GET超全局变量中获取名为dir的参数值,然后使用str_replace函数尝试移除字符串中的../和./。这里的意图是对用户输入的路径进行简单过滤,防止目录穿越。if(substr(str_replace($_M['url']['site'], '', $dir),0,4) == 'http' && strpos($dir, './') === false):进一步检查处理后的$dir参数,如果它以http开头并且不包含./,则执行readfile($dir);。readfile函数会读取指定路径的文件内容并输出。if ($img):在后续逻辑中,如果$img存在,也会使用readfile函数读取经过处理的路径对应的文件内容。这里的问题在于,str_replace函数的过滤方式不够严格,攻击者可以通过构造特殊的输入(比如....//)绕过过滤,从而实现路径穿越,读取服务器上的任意文件。
利用过程及方式
- 攻击者构造请求:攻击者精心构造一个包含恶意
dir参数的 HTTP 请求,假设系统访问入口为http://example.com/thumb.php,攻击者构造的请求可能是http://example.com/thumb.php?dir=../../../etc/passwd。这里使用../../../等目录穿越字符,试图突破正常的文件访问限制,访问到服务器上的敏感文件/etc/passwd。这是利用了old_thumb.class.php中doshow方法对dir参数过滤不严格的漏洞。- 系统执行流程:当攻击者的请求发送到服务器并到达 thumb.php 文件后,thumb.php 引入 entrance.php 文件,启动系统流程。entrance.php 文件在执行过程中,引入
load.class.php并调用load::module()方法。由于 thumb.php 中定义的M_CLASS为old_thumb,M_ACTION为doshow,load::module方法在执行时,会根据这些默认常量设置,通过_load_class方法实例化old_thumb类并调用其doshow方法。具体来说,load::module方法中if (!$modulename) $modulename = M_CLASS;和if (!$action) $action = M_ACTION;语句使得old_thumb类和doshow方法被选中,然后_load_class方法负责完成类的实例化和方法调用准备工作。- 漏洞触发:在
old_thumb.class.php的doshow方法被调用后,获取到攻击者传入的恶意dir参数。尽管进行了简单的str_replace过滤,但攻击者构造的特殊输入可能绕过该过滤。例如,若攻击者输入....//,经过str_replace后可能仍然包含有效的目录穿越字符。随后,readfile函数会尝试读取经过处理后的dir对应的文件路径。如果攻击者成功绕过过滤,readfile函数就会读取服务器上的敏感文件,如/etc/passwd,将文件内容返回给攻击者,导致敏感信息泄露。
代码分析和理解
- 常量定义的影响:thumb.php 中的常量定义在整个系统执行流程中起着关键的引导作用。
M_CLASS和M_ACTION常量如同系统执行的 “导航标”,虽然它们本身只是简单的字符串定义,但却决定了系统后续执行的具体类和方法。攻击者正是利用了这一机制,通过控制与这些常量相关的请求参数,间接地影响到存在漏洞的old_thumb.class.php中的doshow方法。这种常量定义方式在实现系统功能模块化和灵活性的同时,也为潜在的安全攻击留下了隐患,因为常量的全局有效性使得攻击者可以在系统的执行流程中找到切入点。- 文件加载和方法调用:entrance.php 引入
load.class.php并调用相关方法,体现了系统模块化设计的思路,将不同功能的代码分离到不同文件中,便于管理和维护。然而,这种设计也为攻击者利用模块间的关联创造了条件。load.class.php中的方法负责加载各类资源和调用相应的功能,其逻辑较为复杂。例如,load::module和_load_class方法之间的协作,通过层层传递参数和执行逻辑,最终实现类的加载和方法的调用。攻击者通过分析系统的这种执行逻辑,利用 thumb.php 中的常量设置,精准地控制load::module方法的参数,从而调用到存在漏洞的doshow方法。这表明在系统设计中,虽然模块化提高了开发效率,但也需要更加严格地把控模块间交互的安全性,避免因复杂的调用关系而引入安全风险。- 输入验证和过滤不足:
old_thumb.class.php中doshow方法对dir参数的验证和过滤过于简单。仅使用str_replace函数移除../和./,这种方式无法有效抵御目录穿越攻击。从安全编程的角度来看,对用户输入的验证应该采用更加严格和全面的方式,例如使用白名单过滤,只允许合法的字符和路径格式。攻击者通过构造特殊输入,如....//,可以轻易绕过这种简单的过滤机制。一旦绕过成功,readfile函数就会被攻击者利用来读取任意文件,这充分暴露了代码在安全防护方面的不足。在开发过程中,对于涉及文件操作的用户输入,必须进行严格的安全检查,以防止类似的路径穿越漏洞导致的安全问题。
相关文章:
MetInfo6.0.0目录遍历漏洞原理分析
所需进行代码审计的文件路径: C:\phpStudy\WWW\MetInfo6.0.0\include\thumb.php C:\phpStudy\WWW\MetInfo6.0.0\app\system\entrance.php C:\phpStudy\WWW\MetInfo6.0.0\app\system\include\class\load.class.php C:\phpStudy\WWW\MetInfo6.0.0\app\system\include…...
linux打包前端vue,后端springboot项目
第一步先对整个项目进行通过maven进行clean在进行compile 第二步直接进行打包package和install都可以 第三部把对应的jar放到服务器上 把jar包放到服务器上某个地址下,然后cd到这个目录下,然后执行命令 nohup java -jar ruoyi-admin.jar > springbo…...
Elasticsearch:使用 AI SDK 和 Elastic 构建 AI 代理
作者:来自 Elastic Carly Richmond 你是否经常听到 AI 代理(AI agents)这个词,但不太确定它们是什么,或者如何在 TypeScript(或 JavaScript)中构建一个?跟我一起深入了解 AI 代理的概…...
SQLAlchemy 支持特殊字符
postgresql 实践 pydantic 实践(一)基础 pydantic 实践(二)数据校验 SQLAlchemy 介绍与实践 SQLAlchemy 支持特殊字符 SQLAlchemy 支持特殊字符 1. 字符集介绍分析2. MySQL 支持特殊字符2.1. 更新 MySQL 字符集为 utf8mb42.2 更新…...
Docker 快速入门指南
Docker 快速入门指南 1. Docker 常用指令 Docker 是一个轻量级的容器化平台,可以帮助开发者快速构建、测试和部署应用程序。以下是一些常用的 Docker 命令。 1.1 镜像管理 # 搜索镜像 docker search <image_name># 拉取镜像 docker pull <image_name>…...
计算机网络 - OSI 七层模型
OSI 七层模型 OSI(Open System Interconnection,开放系统互联)模型由 ISO(国际标准化组织) 制定,目的是为不同计算机网络系统之间的通信提供一个标准化的框架。它将网络通信划分为 七个层次,每…...
如何调整yarn.nodemanager.vmem-pmem-ratio参数?
调整 yarn.nodemanager.vmem-pmem-ratio 参数的步骤如下: 1. 打开 YARN 配置文件 找到 yarn-site.xml 文件,该文件通常位于 Hadoop 配置目录中,例如 /etc/hadoop/conf 或 /opt/module/hadoop-3.1.3/etc/hadoop。 2. 找到并修改 yarn.nodemana…...
自顶向下学习K8S--部署Agones
本文在本人博客,原文地址:http://viogami.tech/index.php/blog/346/ 我是gopher,离不开云原生,自然也逃不了理解docker和K8S这俩。今天抽空想玩下agones,进而对K8S有实践性的理解。 学一个新事物从底层理论学肯定是最…...
unity中Xcharts图表鼠标悬浮表现异常
鼠标悬浮在面板附近,只显示单独的一个项目 而且无论鼠标如何移动,根本没有效果。 解决方案: 需要在对应的Canvas上绑定主相机才可以 鼠标移动到项目上就有信息展示了...
2025年最新自动化/控制保研夏令营预推免面试真题分享(东南大学苏州校区/华东理工/南航/天大)
笔者来2021级本科自动化专业,以下部分将介绍我在夏令营以及预推免期间发生经历和问题 东南大学苏州校区蒙纳士大学联培 东南大学苏州校区的项目算是一个比较小众的项目,是第一年在苏州校区,二三年到南京校区找导师(不提供住宿自…...
【Java SE】包装类 Byte、Short、Integer、Long、Character、Float、Double、Boolean
参考笔记:java 包装类 万字详解(通俗易懂)_java包装类-CSDN博客 目录 1.简介 2.包装类的继承关系图 3.装箱和拆箱 3.1 介绍 3.2 手动拆装箱 3.3. 自动拆装箱 4.关于String类型的转化问题 4.1 String类型和基本类型的相互转化 4.1.1 String —…...
口腔种植全流程AI导航系统及辅助诊疗与耗材智能化编程分析
一、系统架构与编程框架设计 口腔种植全流程人工智能导航系统的开发是一项高度复杂的多学科融合工程,其核心架构需在医学精准性、工程实时性与临床实用性之间实现平衡。系统设计以模块化分层架构为基础,结合高实时性数据流与多模态协同控制理念,覆盖从数据采集、智能决策到…...
小林coding-10道Java集合面试题
1.数组与集合区别,用过哪些?说说Java中的集合?Java中的线程安全的集合是什么?Collections和Collection的区别?集合遍历的方法有哪些? 2.List?讲一下java里面list的几种实现,几种实现有什么不同ÿ…...
Java 集合中ArrayList与LinkedList的性能比较
一、需求: 头部插入:向列表头部插入10万个整数。随机访问:从列表中间位置连续获取1万个元素。头部删除:从列表头部连续删除10万个元素。 二、 使用ArrayList与LinkedList测试 //常量定义,用于测试操作的次数…...
SQL问题分析与诊断(8)——前提
8.1. 前提 与其他关系库类似,SQL Server中,当我们对存在性能问题的SQL语句进行分析和诊断时,除了获取该SQL语句本身外,还需要获取SQL语句相应的查询计划及其相关的数据环境。这里,所谓数据环境,具体是指SQ…...
漏洞发现:AWVS 联动 XRAY 图形化工具.(主动+被动 双重扫描)
漏洞发现:AWVS 联动 XRAY 图形化工具. 漏洞发现是网络安全领域的关键环节,指通过技术手段识别计算机系统、网络设备或软件中存在的设计缺陷、配置错误或代码漏洞的过程。这些漏洞可能被攻击者利用,导致数据泄露、服务中断或权限提升等风险。…...
上门家政小程序实战,从0到1解决方案
一、逻辑分析 上门家政小程序主要涉及用户端和服务端两大部分。用户端需要实现服务浏览、预约下单、订单跟踪等功能;服务端则要处理订单管理、服务人员管理、数据统计等任务。以下是详细的功能模块分析: 用户注册与登录:用户通过手机号或第三…...
Linux ping/telnet/nc命令
在Linux操作系统中,ping命令用于测试网络连接和发送数据包到目的主机。 然而,ping命令默认情况下只能测试IP地址和域名,而无法直接测试端口号。 ping www.baidu.comping 192.168.0.1 测试端口 如果你想测试特定端口是否开放并响应ÿ…...
Netty - 从Nginx 四层(TCP/UDP)流量中获取客户端真实/网络出口IP
文章目录 一、背景与原理1.1 问题场景网络架构影响分析1.1 客户端与Nginx之间存在的NAT/VPN1.2 Nginx与RPC服务之间的NAT 1.2 技术原理 二、环境配置验证2.1 Nginx配置2.2 版本要求 三、Netty服务端实现3.1 Pipeline配置(核心代码)3.2 协议处理器实现3.3…...
【持续集成和持续部署】
大致流程: 提交代码--拉取下来新代码并自动构建与部署--应用接口探活--执行自动化测试--输出自动化测试报告 一、持续集成(Continuous Integration,CI) 持续集成是一种软件开发实践,开发团队成员频繁地将代码集成到…...
Transformers中的BertConfig、BertModel详解
目录 一、功能 二、用法 1.导入BertConfig 2. 初始化默认配置 3.使用配置初始化模型 使用场景: 1.自定义小型BERT模型 2.加载预训练模型配置 从 Hugging Face 模型库加载 bert-base-uncased 的默认配置: 通过 BertConfig,你可以灵活定义…...
Ubuntu下载docker、xshell
配置:VMware虚拟机、Ubuntu24.04.1 首先打开vm启动虚拟机 下载docker Ubuntu启动之后,按CTRLALTT 打开终端 1.更新软件包索引并安装依赖 sudo apt-get updatesudo apt-get install \ca-certificates \curl \gnupg \lsb-release 2.添加docker官方的GP…...
迅为iTOP-RK3576人工智能开发板Android 系统接口功能测试
2.1 开机启动 开发板接通电源,并按下电源开关,系统即启动,在启动过程中,系统会显示下图中的开机画面,它们分别是 Android 系统启动时的 Logo 画面: 最后会显示如下解锁画面: 2.2 命令终端 将…...
Android设计模式之工厂方法模式
一、定义: 定义一个用于创建对象的接口,让子类决定实例化哪个类。 二、组成: 1.抽象工厂:工厂模式的核心,声明工厂方法,返回抽象产品对象。 2.具体工厂:实现工厂方法,返还具体的产品…...
端侧设备(如路由器、家庭网关、边缘计算盒子、工业网关等)的典型系统、硬件配置和内存大小
🏠 家用/工业级边缘设备硬件概览 类型常见设备示例CPU 架构内存范围操作系统类型家用路由器TP-Link、小米、华硕、OpenWrtARM Cortex-A7/A964MB~256MBOpenWrt / DD-WRT / Embedded Linux智能家庭网关华为、绿米、天猫精灵、Aqara HubARM Cortex-M/R128MB~512MBEmbedded Lin…...
office_word中使用宏以及DeepSeek
前言 Word中可以利用DeepSeek来生成各种宏,从而生成我们需要各种数据和图表,这样可以大大减少我们手工的操作。 1、Office的版本 采用的是微软的office2016,如下图: 2、新建一个Word文档 3、开启开发工具 这样菜单中的“开发工具…...
数据结构day04
一 栈 1栈的基本概念 各位同学大家好,从这个小节开始,我们会正式进入第三章的学习,我们会学习栈和队列,那这个小节中我们会先认识栈的基本概念。我们会从栈的定义和栈的基本操作来认识栈这种数据结构,也就是要探讨栈的…...
质量工程:数字化转型时代的质量体系重构
前言:质量理念的范式转移阅读原文 如果把软件开发比作建造摩天大楼: 传统测试 竣工后检查裂缝(高成本返工) 质量工程 从地基开始的全流程监理体系(设计图纸→施工工艺→建材选择→竣工验收) IEEE研究…...
数据结构C语言练习(单双链表)
本篇练习题(单链表): 1.力扣 203. 移除链表元素 2.力扣 206. 反转链表 3.力扣 876. 链表的中间结点 4.力扣 21. 合并两个有序链表 5. 牛客 链表分割算法详解 6.牛客 链表回文结构判断 7. 力扣 160. 相交链表 8. 力扣 141 环形链表 9. 力扣 142 环形链表 II…...
QScreen 捕获屏幕(截图)
一、QScreen核心能力解析 硬件信息获取 // 获取主屏幕对象 QScreen* primaryScreen QGuiApplication::primaryScreen();// 输出屏幕参数 qDebug() << "分辨率:" << primaryScreen->size(); qDebug() << "物理尺寸:" << primar…...
