day1—java反射

getClass

Class.forName(“className”) 知道类名

Demo.class 加载类后

demo_reflect.getClass(); 实例对象获取class

getMethod

getMethod 获取类中方法 getMethod(“methodName”,参数类型的类)

invoke 用于传参 invoke(“实例对象或类”,”参数”)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package Main;

public class Demo {
public static void main(String[] args) throws Exception{
// get class
Demo_reflect demo_reflect = new Demo_reflect();
System.out.println(demo_reflect.getClass());
Class clazz = Class.forName("Main.Demo_reflect");
System.out.println(clazz);
System.out.println(Demo_reflect.class);

//get method
System.out.println(clazz.getMethod("getName").invoke(clazz.newInstance()));
clazz.getMethod("setName",String.class).invoke(clazz.newInstance(),"test");
}
}

//result
class Main.Demo_reflect
class Main.Demo_reflect
class Main.Demo_reflect
demo

Runtime.exec

通过源码我们可以看到,Runtime是一个私有方法,只能通过getRuntime来获取这个私有方法,而getRuntime又是静态的,所以我们只能直接通过类来调用getRuntime,从而获取一个Runtime对象

1
2
3
4
5
6
7
Class runtimeCls = Class.forName("java.lang.Runtime");
Method execMethod = runtimeCls.getMethod("exec",String.class);
Method getRuntimeMethod = runtimeCls.getMethod("getRuntime");
Object run = getRuntimeMethod.invoke(runtimeCls);
execMethod.invoke(run,"/System/Applications/Calculator.app/Contents/MacOS/Calculator");

runtimeCls.getMethod("exec", String.class).invoke(runtimeCls.getMethod("getRuntime").invoke(runtimeCls),"/System/Applications/Calculator.app/Contents/MacOS/Calculator");

image-20211011133420403

java命令执行方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//Runtime.getRuntime().exec()
InputStream in = Runtime.getRuntime().exec("whoami").getInputStream();
byte[] bytes = new byte[1024];
int readSize = 0;
OutputStream infoStream = new ByteOutputStream();
while ((readSize = in.read(bytes)) > 0){
infoStream.write(bytes, 0,readSize);
}

//ProcessBuilder().start()
InputStream in1 = new ProcessBuilder("id").start().getInputStream();
while ((readSize = in1.read(bytes)) > 0){
infoStream.write(bytes, 0,readSize);
}

//ProcessImpl
String[] cmds = new String[]{"whoami"};
Class piClaszz = Class.forName("java.lang.ProcessImpl");
Method piMethod = piClaszz.getDeclaredMethod("start",String[].class, Map.class, String.class, ProcessBuilder.Redirect[].class, boolean.class);
piMethod.setAccessible(true);
Process e = (Process) piMethod.invoke(null,cmds,null,".",null,true);
while ((readSize = e.getInputStream().read(bytes)) > 0){
infoStream.write(bytes, 0,readSize);
}

System.out.println(infoStream.toString());