JAVA审计——第一周目
JAVA基础
https://www.liaoxuefeng.com/wiki/1252599548343744/1260451488854880
Tips:
- 反射的一大目的就是绕过某些沙盒。
- ClassLoader ***
类加载模式
-
classloader的层级关系
java依赖JVM的开发语言,java程序运行过程:
java程序–>编译成class文件–>调用hava.lang.ClassLoader加载类字节码–>ClassLoader调用JVM中native方法定义java.lang.Class实例–>运行成功
层级关系:
Bootstrap ClassLoader(引导类加载器)
、Extension ClassLoader(扩展类加载器)
、App ClassLoader(系统类加载器)
,AppClassLoader
是默认的类加载器,如果类加载时我们不指定类加载器的情况下,默认会使用AppClassLoader
加载类,ClassLoader.getSystemClassLoader()
返回的系统类加载器也是AppClassLoader
。 -
双亲委派机制
参考文档:https://blog.csdn.net/codeyanbao/article/details/82875064
- 类加载机制
参考文档:https://www.cnblogs.com/xdouby/p/5829423.html
https://www.cnblogs.com/aspirant/p/7200523.html
类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个这个类的java.lang.Class对象,用来封装类在方法区类的对象。
利用反射创建对象
参考文档:https://blog.csdn.net/huidev/article/details/103335969
参考视频:【韩顺平讲Java】Java反射专题 -反射 反射机制 类加载 reflection Class 类结构 等_哔哩哔哩_bilibili
p神的java安全漫谈反射篇写道:反射中极为重要的几个方法:
- forName:获取类的方法
- newInstance:实例化对象的方法
- getMethod:获取函数对象的方法
- invoke:执行函数的方法
个人理解而言:反射就是把方法看成了对象,我们在代码中对对象的调用手法对于反射来说同样适用于方法的调用.
根据这四个方法写一个简单的反射例子
首先创建一个配置文件re.properties指定相关信息
classfullpath=com.refect1.refection
method=hi
创建实体类refection.java
package com.refect1;
public class refection {
private String name = "reflection";
public void hi(){
System.out.println("hi"+"."+name);
}
}
引出反射ReflectionQuestion.java
package com.refect1.reflection.question;
import com.refect1.refection;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;
public class ReflectionQuestion {
public static void main(String[] args) throws IOException, ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
//最传统的方法是new对象,然后调用方法
refection refection = new refection();
refection.hi();
/***
* 1. 使用properties读取配置文件
* 2. 加载类 Class.forName()
* 3. 获取对象实例 newInstance()
* 4. 通过方法对象来实现调用 getMethod()
* 5. 执行 invoke()
*
*/
//1.使用properties读取配置文件
Properties properties = new Properties();
properties.load(new FileInputStream("src\\re.properties"));
String classfullpath = properties.get("classfullpath").toString();
String methodName = properties.get("method").toString();
System.out.println(classfullpath);
System.out.println(methodName);
//2,使用反射机制解决创建对象
//2.1 加载类 Class.forName() Class是一个类,名字就叫class,返回一个Class类型的对象.通过aclass加载类classfullpath=com.refect1.Cat的对象实例
Class aclass = Class.forName(classfullpath);
//3.通过aclass加载类classfullpath=com.refect1.Cat的对象实例
Object obj = aclass.newInstance();
//4、运行类型。通过aclass得到加载的类com.refect1.Cat的methodName的方法(配置是文件中method对应的类对象)
System.out.println("obj的类型="+obj.getClass());
//在反射中,可以把方法视为对象
//method:通过方法对象来实现调用
Method method1 = aclass.getMethod(methodName);
method1.invoke(obj);//反射机制的顺序: 方法.invoke(对象)
}
}
对于传统方法来讲,获取方法的方式是new对象,然后调用.
使用反射来获取对象可以遵循五个步骤
/*** * 1. 使用properties读取配置文件 * 2. 加载类 Class.forName() * 3. 获取对象实例 newInstance() * 4. 通过方法对象来实现调用 getMethod() * 5. 执行 invoke() */
1. 使用properties读取配置文件
使用步骤:
- 创建Properties对象
- 利用load方法读取配置文件
- 利用 properties.get()查询属性文件的内容
2. 加载类 Class.forName()
现在读取到文件中的加载类classfullpath=com.refect1.refection
了,然后调用Class.forName()获取这个类中的所有方法.(classfullpath在配置文件中写到了)
Class aclass = Class.forName(classfullpath);
3. 获取对象实例 newInstance()
获取方法之后,对方法进行实例化.通过aclass加载类classfullpath=com.refect1.refection的对象实例.
Object obj = aclass.newInstance();
4. 通过方法对象来实现调用 getMethod()
通过aclass得到加载的类com.refect1.refection的methodName的方法(配置是文件中method对应的类对象)
System.out.println("obj的类型="+obj.getClass());
5.执行 invoke()
https://www.bilibili.com/video/BV1g84y1F7df?p=3)
反射学习
p神的java安全漫谈反射篇写道:反射中极为重要的几个方法:
- forName:获取类的方法
- newInstance:实例化对象的方法
- getMethod:获取函数对象的方法
- invoke:执行函数的方法
个人理解而言:反射就是把方法看成了对象,我们在代码中对对象的调用手法对于反射来说同样适用于方法的调用.
根据这四个方法写一个简单的反射例子
首先创建一个配置文件re.properties指定相关信息
classfullpath=com.refect1.refection
method=hi
创建实体类refection.java
package com.refect1;
public class refection {
private String name = "reflection";
public void hi(){
System.out.println("hi"+"."+name);
}
}
引出反射ReflectionQuestion.java
package com.refect1.reflection.question;
import com.refect1.refection;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;
public class ReflectionQuestion {
public static void main(String[] args) throws IOException, ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
//最传统的方法是new对象,然后调用方法
refection refection = new refection();
refection.hi();
/***
* 1. 使用properties读取配置文件
* 2. 加载类 Class.forName()
* 3. 获取对象实例 newInstance()
* 4. 通过方法对象来实现调用 getMethod()
* 5. 执行 invoke()
*
*/
//1.使用properties读取配置文件
Properties properties = new Properties();
properties.load(new FileInputStream("src\\re.properties"));
String classfullpath = properties.get("classfullpath").toString();
String methodName = properties.get("method").toString();
System.out.println(classfullpath);
System.out.println(methodName);
//2,使用反射机制解决创建对象
//2.1 加载类 Class.forName() Class是一个类,名字就叫class,返回一个Class类型的对象.通过aclass加载类classfullpath=com.refect1.Cat的对象实例
Class aclass = Class.forName(classfullpath);
//3.通过aclass加载类classfullpath=com.refect1.Cat的对象实例
Object obj = aclass.newInstance();
//4、运行类型。通过aclass得到加载的类com.refect1.Cat的methodName的方法(配置是文件中method对应的类对象)
System.out.println("obj的类型="+obj.getClass());
//在反射中,可以把方法视为对象
//method:通过方法对象来实现调用
Method method1 = aclass.getMethod(methodName);
method1.invoke(obj);//反射机制的顺序: 方法.invoke(对象)
}
}
对于传统方法来讲,获取方法的方式是new对象,然后调用.
使用反射来获取对象可以遵循五个步骤
/*** * 1. 使用properties读取配置文件 * 2. 加载类 Class.forName() * 3. 获取对象实例 newInstance() * 4. 通过方法对象来实现调用 getMethod() * 5. 执行 invoke() */
1. 使用properties读取配置文件
使用步骤:
- 创建Properties对象
- 利用load方法读取配置文件
- 利用 properties.get()查询属性文件的内容
2. 加载类 Class.forName()
现在读取到文件中的加载类classfullpath=com.refect1.refection
了,然后调用Class.forName()获取这个类中的所有方法.(classfullpath在配置文件中写到了)
Class aclass = Class.forName(classfullpath);
3. 获取对象实例 newInstance()
获取方法之后,对方法进行实例化.通过aclass加载类classfullpath=com.refect1.refection的对象实例.
Object obj = aclass.newInstance();
4. 通过方法对象来实现调用 getMethod()
通过aclass得到加载的类com.refect1.refection的methodName的方法(配置是文件中method对应的类对象)
System.out.println("obj的类型="+obj.getClass());
5.执行 invoke()
参考文档:https://blog.csdn.net/huidev/article/details/103335969
参考视频:【韩顺平讲Java】Java反射专题 -反射 反射机制 类加载 reflection Class 类结构 等_哔哩哔哩_bilibili
序列化反序列化
- 序列化:把对象转化为可传输的字节序列过程称为序列化
- 反序列化:把字节序列还原为对象的过程称为反序列化
动态代理
代理模式:1.接口(抽象对象) 2.真实对象 3.代理对象
[JAVA动态代理 - 简书 (jianshu.com)
proxy
InvocationHandler
动态代理底层实现的原理
- 通过实现InvocationHandler接口创建自己的调用处理器。
- 通过Proxy类指定ClassLoader(类加载器)对象和一组interface(接口)来创建动态类
- 通过反射机制获取到动态代理类的构造函数
- 通过构造函数创建动态代理实例,构造是调用处理器对象作为参数被传入