Xi4or0uji's blog

反射

字数统计: 801阅读时长: 4 min
2019/05/07 Share

前言

前段时间的国赛考到了这个东西,肉鸡就来总结一下了

reflection in PHP

在php运行的时候,反射可以对类、接口、函数、方法或扩展进行反向工程,此外,还可以取出函数、类和方法中的文档注释。

简单的demo

下面放一个简单的demo,简单看一下反射是怎样实现的

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
27
28
<?php
class test{
private $test = "Ariel";
private $value = "Xi4or0uji";
private function get(){
$this -> test = "Ariel";
return $this->test;
}
private function hello(){
return " hello world";
}
}
$test = new test();
//获得方法的返回值
$ref = new ReflectionClass($test);
$method = $ref->getMethod("hello");
//setAccessible可以执行私有或保护方法
$method -> setAccessible(true);
print $method -> invoke($test)."<br>";

//获得成员变量的名和值
$reflect = new ReflectionClass($test);
$props = $reflect->getProperties(ReflectionProperty::IS_PUBLIC | ReflectionProperty::IS_PRIVATE | ReflectionProperty::IS_PROTECTED);
foreach ($props as $prop){
$prop->setAccessible(true);
print $prop->getName()."<br>";
print $prop->getValue($test)."<br>";
}

回显

1
2
3
4
5
hello world
test
Ariel
value
Xi4or0uji

CTF题目

上次的国赛题就有这题,具体可以看https://xi4or0uji.github.io/2019/04/22/2019-4-22-2019-%E5%85%A8%E5%9B%BD%E5%A4%A7%E5%AD%A6%E7%94%9F%E4%BF%A1%E6%81%AF%E5%AE%89%E5%85%A8%E7%AB%9E%E8%B5%9B-writeup/#more

reflection in JAVA

java的反射跟php的反射很相似,想解剖一个类,先要获取到这个类的字节码文件对象,使用的是Class类中的方法,因此我们要先获取到每一个字节码文件对应的Class类型的对象

简单的demo

下面还是一个简单的demo去说明怎么调用

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
27
28
29
30
31
32
33
//Member.java文件
package com.company;

public class Member {
public void show(String s){
System.out.println("hello " + s);
}
}

//Test.java文件
package com.company;
import java.lang.reflect.Method;

public class Test {
public static void main(String[] args) throws Exception{
// 获取Class对象
Class stuClass = Class.forName("com.company.Member");
// 获得所有公有方法
System.out.println("get public function");
stuClass.getMethods();
Method[] methodArray = stuClass.getMethods();
for (Method m : methodArray){
System.out.println(m);
}
// 通过反射调用Student下的show方法
Method m = stuClass.getMethod("show", String.class);
System.out.println(m);
//实例化一个Student对象
Object obj = stuClass.getConstructor().newInstance();
m.invoke(obj, "Ariel");
}

}

然后我们就能看到成功调用了

反射调出计算器

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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
package com.company;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.lang.reflect.Method;

public class ReflectionTest implements Serializable {

private Integer n;

public ReflectionTest(Integer n){
this.n = n;
}

public String int2string(Integer n){
System.out.println("here");
return Integer.toString(n);
}

private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException{
in.defaultReadObject();
try{
Method method = java.lang.Runtime.class.getMethod("exec", String.class);
Object result = method.invoke(Runtime.getRuntime(), "calc.exe");
}catch (Exception e){
e.printStackTrace();
}
}

public static void main(String[] args){
ReflectionTest x = new ReflectionTest(12);
operation.ser(x);
operation.deser();
}
}

class operation {
public static void ser(Object obj){
//序列化操作写数据
try{
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("Object.obj"));
oos.writeObject(obj);
oos.flush();
oos.close();
}catch (FileNotFoundException e){
e.printStackTrace();
}catch (IOException e){
e.printStackTrace();
}
}

public static void deser(){
//反序列化读数据
try{
File file = new File("Object.obj");
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
Object x = ois.readObject();
System.out.println(x);
ois.close();
}catch (FileNotFoundException e){
e.printStackTrace();
}catch (Exception e){
e.printStackTrace();
}
}
}

参考

https://www.php.net/manual/zh/intro.reflection.php
https://aluvion.github.io/2019/04/25/%E5%8F%8D%E5%B0%84/
http://pupiles.com/java_unserialize2.html

CATALOG
  1. 1. 前言
  2. 2. reflection in PHP
    1. 2.1. 简单的demo
    2. 2.2. CTF题目
  3. 3. reflection in JAVA
    1. 3.1. 简单的demo
    2. 3.2. 反射调出计算器
  4. 4. 参考