JAVA反序列化-代码基础

与Java反序列化的主要三个知识点代码

0x01 反射

// 正常创建
Person person =new Person();
Class c = person.getClass();
// forName获取
//Class c = Class.forName("sun.refletc.xxx");


// 获取不同的构造函数。参数类型
Constructor pConstructor = c.getConstructor(String.class,int.class);  
// 进行实例化操作。参数
Person p = (Person) pConstructor.newInstance("aas",22);




// 属性操作
// 获取类中定义的属性,declared可以所有属性
Field nameF = c.getDeclaredField("age");  
// 如果是私有属性,需要给权限
nameF.setAccessible(true);
// 设置某实例的属性值。实例,参数值
nameF.set(p,23);

// 函数操作
// 获取类中的方法,declared可以所有函数。方法名,参数类型
Method actionMethod = c.getDeclaredMethod("action",String.class);
// 如果是私有函数,需要给权限
actionMethod.setAccessible(true);
// 调用函数。实例,参数值
actionMethod.invoke(p,"sdffffff");

Runtime 进行序列化时的反射调用

Class c = Runtime.class;
Method getRuntime = c.getDeclaredMethod("getRuntime",null);
Runtime r = (Runtime) getRuntime.invoke(null,null);
Method exec = c.getDeclaredMethod("exec", String.class);
exec.invoke(r,"wt");

0x02 动态代理

主要逻辑

// 实例化自定义的invocationHandler
InvocationHandler invocationHandler = new UserInvocationHandler(user);


// 生成代理,要代理的接口、要做的事、classloader  。classloader(固定写法),interfaces数组,自定义的invocationHandler
IUser userProxy =  (IUser) Proxy.newProxyInstance(user.getClass().getClassLoader(), user.getClass().getInterfaces(),invocationHandler);
// class数组写法
IUser userProxy =  (IUser) Proxy.newProxyInstance(user.getClass().getClassLoader(), new Class[]{IUser.class} ,invocationHandler);


// 调用函数
userProxy.create();

上面自定义的UserInvocationHandler写法

public class UserInvocationHandler implements InvocationHandler {
    IUser user;

    public UserInvocationHandler() {
    }

    public UserInvocationHandler(IUser user) {
        this.user = user;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        System.out.println("调用了"+method.getName());
        method.invoke(user, args);
        return null;
    }
}

0x03 类的动态加载

通过URLClassLoader加载

// file
//URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{new URL("file:///D:\\tmp\\classes\\")})
// http
URLClassLoader urlClassLoader = new URLClassLoader(new URL[]{new URL("http://127.0.0.1/")});
Class<?> test = urlClassLoader.loadClass("Test");
test.newInstance();

通过ClassLoader.defineClass加载

// classload加载器
ClassLoader cl = ClassLoader.getSystemClassLoader();
// 获取defineClass方法
Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass",String.class, byte[].class, int.class, int.class);
// 权限
defineClass.setAccessible(true);
// 获取代码字节
byte[] code = Files.readAllBytes(Paths.get("D:\\tmp\\classes\\Test.class"));
// 执行,生成一个类
Class c = (Class)defineClass.invoke(cl, "Test", code, 0, code.length);
// 实例化
c.newInstance();

通过Unsafe.defineClass加载

// classload加载器
ClassLoader cl = ClassLoader.getSystemClassLoader();
Class c = Unsafe.class;
Field theUnsafeField = c.getDeclaredField("theUnsafe");
theUnsafeField.setAccessible(true);
Unsafe unsafe = (Unsafe) theUnsafeField.get(null);
// 获取代码字节
byte[] code = Files.readAllBytes(Paths.get("D:\\tmp\\classes\\Test.class"));
Class c2 =  unsafe.defineClass(cl, "Test", code, 0, code.length);
c2.newInstance();
posted @ 2023-08-30 15:19  Jarwu  阅读(28)  评论(0编辑  收藏  举报