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();
本文来自博客园,作者:Jarwu,转载请注明原文链接:https://www.cnblogs.com/jarwu/p/17667357.html