起因是在学习java反序列化cc1的时候,很不理解那个通过反射对exec调用的那个过程,不太理解为啥这个能这么调用就有了今天这个篇文章
一、整个调用过程
先把代码贴在这里
Class c = Runtime.class;
Method getMethod = c.getMethod("getRuntime");
Runtime r = (Runtime) getMethod.invoke(null,null);
Method getexecMethod = c.getMethod("exec", String.class);
getexecMethod.invoke(r,"calc");
这几行代码就是为了反射调用我们的exec并执行calc
等价于Runtime.getRuntime().exec("calc");
我们先来看一下这个代码是调用到exec的
首先我们要理解一下类和对象的关系,学过java的都知道,只有实例化的类才算对象
我们用Class来修饰一个类,只有实例化过的类才能调用它的方法,然后才能执行这个实例的方法(非静态方法)
二、从直接原生的调用exec来分析调用过程
Runtime.getRuntime().exec("calc");
上面的代码是我们原生的调用exec的一句话
通过getRuntime(),然后调用它的exec方法
但是,为什么我们不能直接new一个Runtime,然后在调用exec,就像下面这样
我们可以看到报错了,我们跟进这个Runtime类看一下
这里的构造方法是私有的,我们不能从外部去调用它
但是我们为啥能用getRuntime()
就可以直接实例Runtime类呢
我们跟进一下getRuntime
这里的话我们可以看到,getRuntime方法返回了这个currentRuntime,这个东西又帮我们new了一个Runtime类
它帮我们实例了一个Runtime类,所以我们可以调用该实例的exec方法
这个getRuntime方法是个静态方法,我们可以不用实例,通过类名直接调用该方法
MyClass.myStaticMethod();
所以我们才有了最终的Runtime.getRuntime().exec("calc");
三、利用反射调用过程分析
我们可以想一下正常实例一个类的时候,整个过程是咋样的
找到该类
实例化该类
调用方法
执行方法
我们的反射的过程也又对应的函数,这里我们先说(和上面对应)
通过
类名.class
来获得该类通过
.newInstance()
来实例该类通过
.getMethod()
来获得该实例的方法通过
.invoke()
来执行该方法
这就是整个反射的过程,当然还有其他很多细节没用讲到,这里只讲解调用exec的过程
其他的具体请移步大佬博客
这里就很明白如何简单的用反射来实例一个类并调用方法执行方法了,下面我们来看一下如何调用这个exec
Class c = Runtime.class;
Method getMethod = c.getMethod("getRuntime");
Runtime r = (Runtime) getMethod.invoke(null,null);
Method getexecMethod = c.getMethod("exec", String.class);
getexecMethod.invoke(r,"calc");
这里我们再次将我们的代码放到这里
尝试用上面反射调用的过程来理解一下
获取该类
Class c = Runtime.class;
实例化该类,因为我们上面分析过这里我们是不能直接实例化该类,我们先要去调用getRuntime方法来实例化该类
Method getMethod = c.getMethod("getRuntime");
调用了该方法,我们要执行该方法,这里我们用.invoke()
Runtime r = (Runtime) getMethod.invoke(null,null);
因为我们这个getRuntime方法是没有参数的,所以参数都是null,因为这里是返回了我们实例化的Runtime类,所以我们得强转成Runtime
实例化完成之后就是调用方法
Method getexecMethod = c.getMethod("exec", String.class);
调用我们的exec方法,参数是String接下来就是我们执行方法的过程了,我们用invoke(),来执行该方法,我们第一个参数是我们的实例对象,第二个就是我们方法的参数。
这样整个反射调用exec的过程都很好理解啦
参考
https://drun1baby.top/2022/05/20/Java%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E5%9F%BA%E7%A1%80%E7%AF%87-02-Java%E5%8F%8D%E5%B0%84%E4%B8%8EURLDNS%E9%93%BE%E5%88%86%E6%9E%90/