Java安全-类的动态加载

类的加载过程

先在方法区找class信息,有的话直接调用,没有的话则使用类加载器加载到方法区(静态成员放在静态区,非静态成功放在非静态区),静态代码块在类加载时自动执行代码,非静态的不执行;先父类后子类,先静态后非静态;静态方法和非静态方法都是被动调用,即不调用就不执行。

java 复制代码
public class LoadClassTest {
    public static void main(String[] args) {
        new Person();
		//静态代码块
		//构造代码块
		//无参Person
        new Person("a",22);
        //静态代码块
		//构造代码块
		//有参Person
        Person.staticAction();
        //静态代码块
        //静态方法
        Person.id=1;
        //静态代码块
        Class c=Person.class;
        //无结果
        动态加载
        Class.forName("Person");
        //静态代码块
        ClassLoader cl =ClassLoader.getSystemClassLoader();
        Class.forName("com.example.fastjson122.demos.web.Person",true,cl);//初始化
        //静态代码块
        ClassLoader cl =ClassLoader.getSystemClassLoader();
        Class.forName("com.example.fastjson122.demos.web.Person",false,cl);//不初始化
        //无结果
        c.newInstance();
        //静态代码块
		//构造代码块
		//无参Person
		Class<?>c=cl.loadClass("com.example.fastjson122.demos.web.Person");//不初始化的
        c.newInstance();
        //静态代码块
		//构造代码块
		//无参Person        
    }
}

类加载机制

1、类加载与反序列化

类加载的时候会执行代码

初始化:加载静态代码块

实例化:加载构造代码块、无参构造函数

2、动态类加载方法

Class.forname

初始化/不初始化

ClassLoader.loadClass不进行初始化

底层的原理,实现加载任意的类

ClassLoader(父类)->SecureClassLoader->URLClassLoader->AppClassLoader(继承关系)

(调用关系)loadClass->findClass(重写的方法)->defineClass(从字节码加载类)

java 复制代码
public class LoadClassTest {
    public LoadClassTest() {
    }

    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, MalformedURLException {
        ClassLoader cl =ClassLoader.getSystemClassLoader();
        URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{new URL("file:///C:\\JAVA\\")});
        URLClassLoader urlClassLoader=new URLClassLoader(new URL[]{new URL("http://localhost:8080/")});
        URLClassLoader urlClassLoader=new URLClassLoader(new URL[]{new URL("jar:http://localhost:8080/Test2.jar/")});   
        URLClassLoader urlClassLoader=new URLClassLoader(new URL[]{new URL("jar:file://D:\\tmp\\classes\\Test2.jar/")});
        Class<?> c = urlClassLoader.loadClass("Test2");
        c.newInstance();

        Method defineClassMethod = ClassLoader.class.getDeclaredMethod("defineClass",String.class,byte[].class,int.class,int.class);
        defineClassMethod.setAccessible(true);
        byte[] code= Files.readAllBytes(Paths.get("D:\\tmp\\classes\\Test2.class"));
        Class c=(Class) defineClassMethod.invoke(cl,"Test",code,0,code.length);
        c.newInstance();
    }
}

一下两个类是反序列化中常用的两个类都调用了defineClass

漏洞利用

URLClassLoader 任意类加载:file/http/jar

ClassLoder.defineClass字节码加载任意类 私有(好用,常用)

Unsafe.defineClass 字节码加载 public 类不能直接生成 Spring里可以直接生成

相关推荐
AC赳赳老秦几秒前
司法公开数据采集应用:OpenClaw 抓取裁判文书公开信息,批量整理同类参考案例
java·大数据·python·数据挖掘·数据分析·php·openclaw
笑小枫7 分钟前
用 Claude Code 推翻重写笑小枫网站
java·人工智能·spring boot·ai编程
霸道流氓气质20 分钟前
ApiPost 中配置自动获取 Token 并调用业务接口完整指南
java·服务器·数据库
独隅40 分钟前
IntelliJ IDEA 接入多种AI大模型插件终极指南(2026.1 企业合规版)
java·人工智能·intellij-idea
还是奇怪1 小时前
Simon Willison 用 DSPy 优化 Datasette Agent 提示词:提示工程正在变成可测试的软件工程
java·开发语言·软件工程
zfoo-framework1 小时前
1.ansible安装 2.虚拟机克隆
java
码上解惑2 小时前
从 Dify 工作流说起:常用节点怎么选、怎样组合?
java·人工智能·ai·agent·dify·智能体·spring ai
青山木2 小时前
Hot 100 --- 岛屿数量
java·数据结构·算法·leetcode·深度优先·广度优先
程序员-珍3 小时前
报错下载android sdk失败
android·java
糖果店的幽灵3 小时前
langgraph分支之 - 动态分支(Dynamic Branch)
java·前端·javascript·人工智能·langgraph