Java安全——JVM类加载器

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

Java类加载机制在Java安全知识体系中有着非常重要的地位,早在之前分析Shiro反序列化漏洞利用,以及学习蚁剑Java马,都和Java ClassLoader打过交道。笔者打算从把ClassLoader的原理、使用场景、自定义方式等多个方面剖析类加载器在Java安全中设计到的知识。

0x01 ClassLoader 简介

Java语言需要把代码编译成class文件,才能用JVM加载执行,那么ClassLoader就是负责将class文件加载到内存,生成对应的类。

0x1 ClassLoader类加载流程

从上图中可以看出ClassLoader的主要职能,将字节流加载到内存,并使用defineClass加载到JVM生成可以被调用的类。Java源码编译之后生成对应的字节码,字节码的存储形式不只局限于文件,还可以使用访问数据库,URL请求的方式进行获取。存储的字节码还可以使用加密算法进行加密,提高存储安全性。

0x2 常见类加载方式

在之前的《Shiro 反序列化漏洞的一些思考》文章中有提到,两种常见的类加载方式。

1.Class.forName 不能加载原生类型,但其他类型都是支持的

2.Classloader.loadclass 不能加载原生类型和数组类型,其他类型都是支持的

这两种类加载方式虽然在实际过程中有着区别,但是其底层都是使用ClassLoader实现类加载机制的。ClassLoader的加载原理并不复杂,相对复杂的是ClassLoader逻辑父节点和真实父类概念上的理解。逻辑父节点是为了双亲委派机制设计的,这样在类加载的时候可以通过parent属性找到上级ClassLoader进行加载。

0x3 获取ClassLoader

ClassLoader loader = null;
loader = Thread.currentThread().getContextClassLoader();//通过当前线程获取
loader = ClassLoader.getSystemClassLoader();
loader = this.getClass().getClassLoader();//通过已加载class获取

大多数时候采用第一种方式获取ClassLoader,有时第三种方式会获取的值为null

0x02 ClassLoader 类关系及类结构

笔者本小节主要介绍ClassLoader的类结构以及类关系,ClassLoader在代码实现上是抽象类。这就意味着在程序中ClassLoader应该有很多的子类,那么ClassLoader及其子类中有什么关键类方法和类属性,在这一小节中进行介绍。

0x1 类关系

类关系问题第一次遇到还是在分析Shiro反序列化的时候,当时使用Tomcat容器启动的Shiro应用,在具体调试过程中发现WebappClassLoaderBase这个Classloader子类继承了URLClassLoader,一开始对于这种想象是不能够理解的。于是对ClassLoader、URLClassLoader、AppClassLoader等概念产生了混淆,笔者根据之前师傅们的研究总结了他们之间的关系,如下图所示

URLClassLoader是类加载机制双亲委托机制中最靠近子类的父类。ExtClassLoader、AppClassLoader、WebappClassLoaderBase等都继承自URLClassLoader。

public class Mytest{
    public static void main(String[] arg){
        ClassLoader classloader  = Mytest.class.getClassLoader(); 
        System.out.println(classloader); 
        ClassLoader classloader1 = classloader.getParent();   
        System.out.println(classloader1);
        ClassLoader classloader2 = classloader1.getParent();
        System.out.println(classloader2);
    }
}

运行结果如下所示,我们可以发现ExtClassLoader的父类加载器为null,原因是BootStrapClassLoader由C实现,无法载Java代码中体现其类之间的关系,但是在实际使用过程中ExtClassLoader确实会委托顶级类加载器BootStrapClassLoader进行类加载,代码实现如下

Thread.currentThread().getContextClassLoader() Thread线程API中,getContextClassLoader()方法的描述为: * Returns the context ClassLoader for this Thread. The context * ClassLoader is provided by the creator of the thread for use * by code running in this t... 阅读详情

相关推荐

Thread.currentThread().getContextClassLoader().getResourceAsStream

打个简单的比方,你一个WEB程序,发布到Tomcat里面运行。首先是执行Tomcat org.apache.catalina.startup.Bootstrap类,这时候的类加载器是ClassLoader.getSystemClassLoader()。而我们后面的WEB程序,里面的jar、resources都是由Tomcat内部来加载的,所以你在代码中动态加载jar、资源文件的时候,首先应该是使用...

liudongdong_jlu 9999

ContextClassLoader介绍

Thread.currentThread().getContextClassLoader()的意义: 1,父Classloader可以使用当前线程Thread.currentthread().getContextLoader()中指定的classloader中加载的类。颠覆了父ClassLoader不能使用子Classloader或者是其它没有直接父子关系的Classloader中加载的类这

每天积累一点,一年后你会发现,自己变化很大 1575

ClassLoader,Thread.currentThread().setContextClassLoader,tomcat的ClassLoader

实际上,在Java应用中所有程序都运行在线程里,如果在程序中没有手工设置过ClassLoader,对于一般的java类如下两种方法获得的ClassLoader通常都是同一个  this.getClass.getClassLoader(); Thread.currentThread().getContextClassLoader(); 方法一得到的Classloader是静态的...

weixin_34400525的博客 459

Java类加载,getClassLoader()

转自 【java 类加载的深入研究1】loadClass()的研究,IBM深入探讨 Java 类加载器 类加载器基本概念 顾名思义,类加载器(class loader)用来加载 Java 类到 Java 虚拟机中。一般来说,Java 虚拟机使用 Java 类的方式如下:Java 源程序(.java 文件)在经过 Java 编译器编译之后就被转换成 Java 字节代码(.class 文件)。类加载...

Site_Dave的博客 1万+

Java安全之【JVM类加载器

这个月马上就又要过去了,还在找工作的小伙伴要做好准备了,小编整理了大厂java程序员面试涉及到的绝大部分面试题及答案,希望能帮助到大家《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!per©;%>

2401_84152879的博客 640

2024年网络安全最新Java安全之【JVM类加载器】(2)

URLClassLoader类中的ucp属性一般存放类加载路径,在双亲委派机制中每一个ClassLoader类都会对应它负责的加载路径。再者比较重要的是ClassLoader类中的关于类加载的方法。0x03 双亲委派机制双亲委派机制是Java类加载的核心,该机制一定程度的保证了类加载安全性。

2401_84264727的博客 859

最新Java安全——JVM类加载器

0x02 ClassLoader 类关系及类结构笔者本小节主要介绍ClassLoader的类结构以及类关系,ClassLoader在代码实现上是抽象类。这就意味着在程序中ClassLoader应该有很多的子类,那么ClassLoader及其子类中有什么关键类方法和类属性,在这一小节中进行介绍。

2401_82645688的博客 955

Java 细聊JVM类加载器

什么是JVM JVMJava Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。 JVM所处的位置 JVM是运行在操作系统之上的,它与硬件没有直接的交互,但是它可以通过 native 本地方法调用硬件接口 JVM体系结构 类加载器 负责加载 class 文件,...

cong____cong的博客 240
上一篇: Spring为啥不推荐使用@Autowired注解?
下一篇: 请收好这一封 KMP 算法 的信 - Java 和 c 实现
阿伦Java
博客等级 码龄5年 327粉丝 159原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值