反序列化底层学习
反序列化底层学习
前言
以前也是懒得学,觉得没有必要,学到现在发现好多东西都需要学习java的底层,而且很多漏洞都是通过反序列化底层挖出来的,比如weblogic的一些绕过,我这里也主要是为了学习weblogic来学习的,所以一些细节不关注
DEMO
import java.io.*;
public class Main {public static class Demo implements Serializable {transient String name;public Demo(String name) {this.name = name;}public static void main(String[] args) throws IOException, ClassNotFoundException {Demo demo = new Demo("nn0nkey");ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("panda.out"));outputStream.writeObject(demo);outputStream.close();ObjectInputStream inputStream = new ObjectInputStream(new FileInputStream("panda.out"));inputStream.readObject();}}
}
反序列化分析
一般我们就知道反序列化会调用readobject方法,现在就好好分析一下readobject干了啥
首先判断是不是重载类型的,如果不是调用Object obj = readObject0(false);
去恢复对象
readObject0方法会对不同的类型进行不同的处理,我这里是object类型的
readOrdinaryObject(unshared)
我们继续看看是怎么处理的
内部调用ObjectStreamClass desc = readClassDesc(false);
去读取我们的序列化流的描述信息,跟进
可以看到也是按照不同的类型去处理,有null,引用类型,代理类型,class类型
我们进入到class类型
return readNonProxyDesc(unshared);
先进行一个检查是不是class类型,然后实例化一个desc对象,desc的信息是通过readClassDescriptor读取的
跟进readClassDescriptor
跟进readNonProxy
这个方法是真正意义上的操作
系统会先从字节流中读取类名信息name = in.readUTF();
,其次从字节流中读取serialVersionUID
的信息,然后再从字节流中读取各种SC_*
标记信息,通过该标记信息设置对应的成员属性,最后从字节流中读取每一个字段的信息这些字段信息包括:TypeCode
、fieldName
、fieldType
这里对应的方法是在序列化时使用的writeNonProxy
方法,在writeNonProxy
中写入的TypeCode
、fieldName
、fieldType
在这里被读取。
然后回到我们的readNonProxyDesc,封装好我的信息之后使用resolveClass(readDesc)处理为class
resolveClass就是使用class.forname去加载
然后调用initNonProxy处理读取到的信息初始化
最后返回desc对象
回到readOrdinaryObject
方法
关键在
做了一个判断desc.isExternalizable
,如果序列化的接口是Externalizable类型,就进入readExternalData,否则进入readSerialData
如果我们的demo对象接口类型是Serializable,所以进入了readSerialData
方法
readSerialData
方法中用了反射进行调用反序列化对象的readObject
方法
然后回到readSerialData,会反射调用readResolve方法
总结
那么多read方法,我们总结一下
readobject:单纯的入口点
readobject0:可以说是我们的readobject方法的具体逻辑点,会跟进不同的字节流选择不同的方法去处理
readOrdinaryObject:用来处理我们的object对象类型的,它用于调用序列化类中,readObject、readResolve、readExternal的方法会有一些选择
readClassDesc :分发用于处理字节流中TC_CLASSDESC的方法,用switch来选择需要处理的方法
readNonProxyDesc :真正用来处理字节流中的TC_CLASSDESC方法,会调用resolveClass进行创建反序列化的对象
resolveClass:是用Class.forName
来创建对象的地方,在这里可以做一个检查校验,用于反序列化拦截。
readNonProxy:真正读取我们描述信息的方法
参考
https://www.cnblogs.com/yyhuni/p/15127416.html
https://www.cnblogs.com/yyhuni/p/15127416.html
eadNonProxy:真正读取我们描述信息的方法
参考
https://www.cnblogs.com/yyhuni/p/15127416.html
https://www.cnblogs.com/yyhuni/p/15127416.html
https://www.cnblogs.com/yyhuni/p/15127416.html
相关文章:

反序列化底层学习
反序列化底层学习 前言 以前也是懒得学,觉得没有必要,学到现在发现好多东西都需要学习java的底层,而且很多漏洞都是通过反序列化底层挖出来的,比如weblogic的一些绕过,我这里也主要是为了学习weblogic来学习的&#…...

项目训练营第五天
项目训练营第五天 后端代码优化 通用异常处理类编写 Data public class BaseResponse<T> implements Serializable {int code;T data;String message null;String description null;public BaseResponse(int code, T data, String message, String description) {th…...
数据收集和数据分析
数据分析和收集是一个多步骤的过程,涉及到不同的方法和思维构型。 以下是一些常见的数据收集方法和数据分析的思维模式: ### 数据收集方法: 1. **调查问卷**: 通过设计问卷来收集定量或定性数据。(质量互变规律里面…...
Kubernetes(K8s)从入门到精通系列之十九:Operator模式
Kubernetes K8s从入门到精通系列之十九:Operator模式 一、动机二、Operators in Kubernetes三、Operator示例四、部署Operator五、使用Operator六、编写自己的operator Operator 是 Kubernetes 的软件扩展,它利用自定义资源来管理应用程序及其组件。 Ope…...

vuex的actions返回结果类型是promise及actions方法互相调用
this.$store.dispatch(‘logout’)返回的结果是Promise类型的 调用成功的情况下,返回状态为fulfilled,值为undefined。 所以可以直接进行.then操作: this.$store.dispatch(logout).then((result) > {console.log(result); });因为 Vuex …...

【干货】Jupyter Lab操作文档
Jupyter Lab操作文档1. 使用须知2. 定制化Jupyter设置主题显示代码行数设置语言更多设置 3. 认识Jupyter界面4. 初用Jupyter运行调试格式化查看源码 5. 使用Jupyter Terminal6. 使用Jupyter Markdown7. 上传下载文件(云服务器中的Jupyter Lab)上传文件到…...

iOS分享到微信,配置Universal Links,并从微信打开app,跳转到指定界面
iOS分享到微信之后,需要从微信浏览器直接打开app,跳转到指定界面,这个时候最主要的就是分以下几步(微信sdk集成就不说了) 1.配置Universal Links Universal Links是iOS新系统出来后通用链接,用于在第三方浏览器直接打开app&…...

基于SSM构建的校园失眠与压力管理系统的设计与实现【附源码】
毕业设计(论文) 题目:基于SSM构建的校园失眠与压力管理系统的设计与实现 二级学院: 专业(方向): 班 级: 学 生: 指导教师&a…...

SAP 初始化库存移动类型561501511区别简介
项目上线初始化库存经常会用到561这个移动类型,同时我们在平时测试的过程中也会用到会进行库存的初始化,用的比较多是就是561和501这两个移动类型,本文将测试移动类型561&501&511这三个移动类型,分析三者之间的区别&#…...

情感搞笑聊天记录视频:AI自动化生成技术,操作简单,教程+软件
在数字化时代,内容创作已成为吸引观众、传递信息的重要手段。随着人工智能技术的飞速发展,AI自动生成视频为创作者提供了新的工具和可能性。本文将介绍如何利用AI技术,通过情感搞笑聊天记录视频,在视频号上实现内容的自动化生成&a…...

RabbitMQ中lazyqueue队列
lazyqueue队列非常强悍 springboot注解方式开启 // 使用注解的方式lazy.queue队列模式 非常GoodRabbitListener(queuesToDeclare Queue(name "lazy.queue",durable "true",arguments Argument(name "x-queue-mode",value "lazy&…...

Java三层框架的解析
引言:欢迎各位点击收看本篇博客,在历经很多的艰辛,我也是成功由小白浅浅进入了入门行列,也是收货到很多的知识,每次看黑马的JavaWeb课程视频,才使一个小菜鸡见识到了Java前后端是如何进行交互访问的&#x…...

算法设计与分析 笔记
截图摘自湖南大学彭鹏老师的ppt。笔记也是根据他的ppt整理的。 动态规划 核心 用数组记录中间结果,避免重复计算 三角数塔问题 问题描述 给定一个三角形数塔,从顶部出发,每次只能移动到下一行的相邻元素。要求找到一条路径,…...
mapreduce的工作原理
mapreduce的工作原理 MapReduce是一种编程模型,用于处理大规模数据集的并行运算。它的核心思想是"分而治之",即把一个大数据集分解成多个小块,由多个处理单元并行处理,然后再将结果合并以得到最终结果。MapReduce模型包…...
vue中v-bind和v-model有什么区别
在Vue.js中,v-bind和v-model都是指令,用于实现数据和DOM元素之间的双向绑定,但它们的使用场景和功能有所区别。 v-bind: v-bind是一个通用指令,用于动态地绑定一个或多个属性,或者一个组件prop到表达式。它可以绑定任何…...

基于SpringBoot和PostGIS的某国基地可视化实战
目录 前言 一、Java后台开发设计与实现 1、模型层实现 2、控制层设计 二、WebGIS界面实现 1、列表界面的定义 2、全球基地可视化 三、成果展示 1、全球部署情况 2、亚太地区 3、欧洲基地分布 4、中东的部署 四、总结 前言 在之前的博客中,我们曾经对漂亮…...

为什么Linux服务器空间充足而实际上空间已满的原因
以下是一个典型的Linux服务器的磁盘空间使用情况表,展示了不同文件系统的大小、已用空间、可用空间和挂载点等信息 磁盘空间表的基本组成 Linux服务器的磁盘空间使用情况通常通过df命令查看,输出的表格包含以下几列: Filesystem:…...
【LC刷题】DAY16:530 501 236
【LC刷题】DAY16:530 501 236 文章目录 【LC刷题】DAY16:530 501 236530. 二叉搜索树的最小绝对差 [link](https://leetcode.cn/problems/minimum-absolute-difference-in-bst/description/)501.二叉搜索树中的众数236. 二叉树的最近公共祖先 [link](htt…...
Vue 3 的 Teleport 组件实现跨层级通信
突破组件边界 - 使用 Vue 3 的 Teleport 组件实现跨层级通信 你可能已经熟悉了组件的基本概念:每个组件都是一个独立的单元,拥有自己的模板、样式和逻辑。但是,有时候我们需要在不同层级的组件之间进行交互,这就需要用到 Vue 3 中新引入的 Teleport 组件。 Teleport 组件可以…...
chromadb
Chroma是一款AI开源向量数据库,用于快速构建基于LLM的应用,支持Python和Javascript语言。具备轻量化、快速安装等特点,可与Langchain、LlamaIndex等知名LLM框架组合使用。 官网: https://www.trychroma.com/ https://docs.trychr…...
KubeSphere 容器平台高可用:环境搭建与可视化操作指南
Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

XML Group端口详解
在XML数据映射过程中,经常需要对数据进行分组聚合操作。例如,当处理包含多个物料明细的XML文件时,可能需要将相同物料号的明细归为一组,或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码,增加了开…...
变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析
一、变量声明设计:let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性,这种设计体现了语言的核心哲学。以下是深度解析: 1.1 设计理念剖析 安全优先原则:默认不可变强制开发者明确声明意图 let x 5; …...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2
每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)
上一章用到了V2 的概念,其实 Fiori当中还有 V4,咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务),代理中间件(ui5-middleware-simpleproxy)-CSDN博客…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能
1. 开发环境准备 安装DevEco Studio 3.1: 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK 项目配置: // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...

elementUI点击浏览table所选行数据查看文档
项目场景: table按照要求特定的数据变成按钮可以点击 解决方案: <el-table-columnprop"mlname"label"名称"align"center"width"180"><template slot-scope"scope"><el-buttonv-if&qu…...
Vue 模板语句的数据来源
🧩 Vue 模板语句的数据来源:全方位解析 Vue 模板(<template> 部分)中的表达式、指令绑定(如 v-bind, v-on)和插值({{ }})都在一个特定的作用域内求值。这个作用域由当前 组件…...
深入解析 ReentrantLock:原理、公平锁与非公平锁的较量
ReentrantLock 是 Java 中 java.util.concurrent.locks 包下的一个重要类,用于实现线程同步,支持可重入性,并且可以选择公平锁或非公平锁的实现方式。下面将详细介绍 ReentrantLock 的实现原理以及公平锁和非公平锁的区别。 ReentrantLock 实现原理 基本架构 ReentrantLo…...