获取Runtime类对象的相关代码分析
本文参考P佬的java安全漫谈
很重要的知识点
invoke
的作用是执行方法,它的第一个参数是
- 如果这个方法是一个普通方法,那么第一个参数是类对象
- 如果这个方法是一个静态方法,那么第一个参数是类
getMethod和invoke
这里对getMethod
和invoke
进行分析
getMethod
的作用是通过反射获取一个类的某个特定的公有方法
。Java支持类的重载,我们不能仅通过函数名来确定一个函数。所以,在调用 getMethod 的时候,我们需要 传给他你需要获取的函数的参数类型列表
。
Runtime.exec有6个重载
我们使用第一个
getMethod("exec",String.class)
来获取Runtime.exec
方法
invoke
的作用是执行方法,它的第一个参数是
- 如果这个方法是一个普通方法,那么第一个参数是类对象
- 如果这个方法是一个静态方法,那么第一个参数是类
exec是一个普通方法
,所以最终第一个参数是类对象
获取Runtime类对象
但是我们怎么获取Runtime的一个类对象呢?
根据上面的分析,我们可以通过getRuntime()
方法获取一个Runtime
类对象
而调用getRuntime
需要用到getMethod
方法,得到Method之后,进行invoke调用
但是这个getRuntime方法是静态方法
,invoke()
中的参数是类
,而不是类对象
所以下文中invoke里面的是clazz
,是一个类
//获取Runtime类
Class clazz = Class.forName("java.lang.Runtime");
//获取getRuntime方法
Method getRunimeMethod = clazz.getMethod("getRuntime");
//通过调用getRuntime获取Runtime类对象
Object runtime = getRunimeMethod.invoke(clazz);
然后最终exec
去用invoke
的时候,用的是Runtime类对象
Method execMethod = clazz.getMethod("exec", String.class);
execMethod.invoke(runtime, "calc.exe");
调用计算器全部的代码
//获取Runtime类
Class clazz = Class.forName("java.lang.Runtime");
//获取getRuntime方法
Method getRunimeMethod = clazz.getMethod("getRuntime");
//通过调用getRuntime获取Runtime类对象
Object runtime = getRunimeMethod.invoke(clazz);
//获取exec方法
Method execMethod = clazz.getMethod("exec", String.class);
//invoke执行方法
execMethod.invoke(runtime, "calc");
执行结果
另一种写法
Class clazz = Class.forName("java.lang.Runtime");
clazz.getMethod("exec",String.class).invoke(clazz.getMethod("getRuntime").invoke(clazz),"calc");
注意上面这个代码,其实是5行代码的简写
第二行可以分为clazz.getMethod("exec",String.class)
和invoke(clazz.getMethod("getRuntime").invoke(clazz),"calc");
前者是获取exec方法
后者是invoke里面的参数,因为exec
是一个普通方法,不是静态方法,所以invoke的第一个参数需要是一个Runtime类对象
clazz.getMethod("getRuntime").invoke(clazz)
就是一个Runtime类对象
,是通过调用getRuntime方法来获取一个Runtime类对象,因为getRuntime是一个静态方法,invoke的第一个参数是类而不是类对象