java字节码

##字节码
能够恢复成一个类并在jvm中加载的字节序列
##利用URLClassLoader加载远程class文件
ClassLoader是java的类加载器,告诉java虚拟机如何加载这个类,默认根据类名加载类,并且这个类名是类完整路径,例如java.lang.Runtime
###URLClassLoader
正常情况下,java会根据sun.boot.class.path和java.class.path中列举的基础路径(这些路径是经过处理后的java.net.URl类)来寻找.class文件进行加载,基础路径有三种情况

  • URL未以斜杠 / 结尾,则认为是一个JAR文件,使用 JarLoader 来寻找类,即为在Jar包中寻找.class文件
  • URL以斜杠 / 结尾,且协议名是 file ,则使用 FileLoader 来寻找类,即为在本地文件系统中寻找.class文件
  • URL以斜杠 / 结尾,且协议名不是 file ,则使用最基础的 Loader 来寻找类
    ###defineClass
    在加载远程class文件、本地class或者jar包时,java都经历了

    其中
  • loadClass 的作用是从已加载的类缓存、父加载器等位置寻找类(这里实际上是双亲委派机制),在前面没有找到的情况下,执行 findClass
  • findClass 的作用是根据基础URL指定的方式来加载类的字节码,就像上一节中说到的,可能会在
    本地文件系统、jar包或远程http服务器上读取字节码,然后交给defineClass
  • defineClass 的作用是处理前面传入的字节码,将其处理成真正的Java类
    ###defineClass加载字节码
    ####使用反射进行加载
    Method defineclass = ClassLoader.class.getDeclaredMethod("defineClass",String.class,byte[].class,int.class,int.class);
    defineClass,setAccessible(true);
    byte[] code= Base64.getDecoder().decode("");
    Class hello = (Class) defineclass.invoke(ClassLoader.getSystemClassLoader(),"hello",code,0,code.length);
    hello.newInstance();
    ####利用TemplatesImpl加载字节码
    com.sun.org.apache.xalan.internal.xsltc.trax.TemplatesImpl这个类中定义了一个内部类
    TransletClassLoader :

    重写了defineClass方法,并且没有显式地声明其定义域。如果没有显式声明,则其作用域为default,可以被类外部调用,而TransletClassLoader#defineClass()向前追溯调用链以后可以发现,其最前面的两个方法为法 TemplatesImpl#getOutputProperties() 、 TemplatesImpl#newTransformer()
    #####使用newTransformer()构造poc
    byte[] code=Base64.getDecoder().decode("");
    TemplatesImpl obj = new TemplatesImpl();
    setFieldValue(obj,"_bytecodes",new byte[][]{code});
    setFieldValue(obj,"_name","HelloTemplatesImpl");
    setFieldValue(obj,"_tfactory",new TransformerFactoryImpl);
    obj.newTransformer();
    其中:
    setFieldValue 方法用来设置私有属性,可见,这里我设置了三个属性: _bytecodes 、 _name 和 _tfactory 。
    _bytecodes 是由字节码组成的数组; _name 可以是任意字符串,只要不为null即可;
    _tfactory 需要是一个 TransformerFactoryImpl 对象,因为
    TemplatesImpl#defineTransletClasses() 方法里有调用到
    _tfactory.getExternalExtensionsMap() ,如果是null会出错。
    另外,值得注意的是, TemplatesImpl 中对加载的字节码是有一定要求的:这个字节码对应的类必须
    是 com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet 的子类。
    因此在构造这个类的时候要写extends
Author

vague huang

Posted on

2022-09-14

Updated on

2023-02-14

Licensed under

Comments