0.什么是反射机制
Java的反射机制,意思是在运行状态中对于任意一个类都能得到他的所有属性和方法,但是前提是必须要能够得到该类的class对象
。事实上,上一节学的ClassLoader就是将.class
文件映射成JVM当中的class对象
(java.lang.Class)。当得到class对象后,我们便可以通过该class对象去实例化目标类,调用类的方法等。
1.如何获得Class对象
获得某个目标类的Class对象的方法主要包括如下三种
- 方法一:类名.class
public class ReflectTest { public static void main(String argvs[]){ Class myRuntime = java.lang.Runtime.class; System.out.println(myRuntime); } }
- 方法二:调用java.lang.Class的forName方法
public class ReflectTest { public static void main(String argvs[]) throws ClassNotFoundException { Class myRuntime = java.lang.Class.forName("java.lang.Runtime"); System.out.println(myRuntime); } }
- 方法三:通过classLoader加载类从而返回class对象
public class ReflectTest { public static void main(String argvs[]) throws ClassNotFoundException { ReflectTest test = new ReflectTest(); Class myRuntime = test.getClass().getClassLoader().loadClass("java.lang.Runtime"); System.out.println(myRuntime); } }
3.利用反射机制执行命令
通过上述操作可以获得某个想要类的class对象(java.lang.Class类)。java.lang.Class
类中包含了许多方法。以下对部分常用方法进行简单罗列。
函数名 | 解释 |
---|---|
getConstructor | 获取类构造方法(不包含私有方法) |
getDeclaredConstructor | 获取类构造方法(包含私有方法) |
getDeclaredConstructors | 获取类的所有构造方法,返回一个Constructor数组 |
getDeclaredMethods | 获取类所有的成员方法,返回一个Method数组 |
getDeclaredMethod | 获取类指定的成员方法 |
getDeclaredFields | 获取当前类的所有成员变量,返回一个Field数组 |
getDeclaredField | 获取指定成员变量 |
反正只要是java代码审计教程,基本都要讲个反射机制调用Runtime类的exec方法执行命令,以下为使用反射机制调用exec方法的代码:
import java.io.IOException; import java.lang.reflect.InvocationTargetException; public class ReflectTest { public static void main(String argvs[]) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, IOException { Class myRuntime = java.lang.Class.forName("java.lang.Runtime"); //获取Runtime类的Class对象 //获取构造方法 java.lang.reflect.Constructor myRuntimeConstructor = myRuntime.getDeclaredConstructor(); myRuntimeConstructor.setAccessible(true); //调用构造方法实例化一个Runtime对象 Object myRuntimeInstance = myRuntimeConstructor.newInstance(); //获取exec方法 java.lang.reflect.Method myExec = myRuntime.getMethod("exec", String.class); //在实例化的Runtime对象中调用exec方法 java.lang.Process process = (Process) myExec.invoke(myRuntimeInstance,"whoami"); //读取命令执行结果 java.io.InputStream in = process.getInputStream(); java.io.BufferedReader br=new java.io.BufferedReader( new java.io.InputStreamReader(in,"UTF-8")); System.out.println(br.readLine()); } }