0x00 前言
JAVA安全系列文章主要为了回顾之前学过的java知识,构建自己的java知识体系,并实际地将java用起来,达到熟练掌握java编程,并能用java编写工具的目的。此系列文章需要读者具备一定java基础,不定时更新。相关详情可通过我的公众号文章进行查看:
反射部分文章内容,主要来自B站韩顺平老师JAVA基础课的反射讲解部分,链接:
https://www.bilibili.com/video/BV1fh411y7R8?p=711&vd_source=f50eede57052ba3346254570c978a2ee
本文为JAVA安全系列文章第六篇,反射机制内容第四篇,主要来敲代码练习反射的常用API。
类的结构信息包括类名、方法名、属性名、构造器、接口、参数类型等。故类的结构信息需要四个主要相关类来进行获取,来看看四个主要类都有哪些常用API来获取类的结构信息。
-
java.lang.Class类
getName:获取全类名
getSimpleName:获取简单类名
getFields:获取所有public修饰的属性,包含本类以及父类的
getDeclaredFields:获取本类中所有属性
getMethods:获取所有public修饰的方法,包含本类以及父类的
getDeclaredMethods:获取本类中所有方法
getConstructors:获取本类所有public修饰的构造器
getDeclaredConstructors:获取本类中所有构造器
getPackage:以Package形式返回包信息
getSuperClass:以Class形式返回父类信息
getInterfaces:以Class[]形式返回接口信息
getAnnotations:以Annotation[]形式返回注解信息
demo 段:
2.java.lang.reflect.Field类
getModifiers:以int形式返回修饰符
【说明:默认修饰符是0,public是1,private是2,protected是4,static是8,Final是16】,public(1) + static(8) = 9
getType:以Class形式返回类型
getName:返回属性名
demo 段:
3.java.lang.reflect.Method类
getModifiers:以int形式返回修饰符
【说明:默认修饰符是0,public是1,private是2,protected是4,static是8,Final是16】
getReturnType:以Class形式获取返回类型
getName:返回方法名
getParameterTypes:以Class[]返回参数类型数组
demo 段:
4.java.lang.reflect.Constructor类
getModifiers:以int形式返回修饰符
getName:返回构造器名(全类名)
getParameterTypes:以Class[]返回参数类型数组
demo 段:
0x02 通过反射创建对象
-
有两种方式:
(1)调用类中的public修饰的无参构造器
(2)调用类中的指定构造器
2.Class类相关方法
newInstance:调用类中的无参构造器,获取对应类的对象
getConstructor(Class...clazz):根据参数列表,获取对应的public构造器对象
getDecalaredConstructor(Class...clazz):根据参数列表,获取对应的所有构造器对象
3.Constructor类相关方法
setAccessible:暴破,为true 则表示关闭安全访问检查,暴力破坏封装性
newInstance(Object...obj):调用构造器
demo段:
0x03 通过反射访问类中的成员
-
访问属性
(1)根据属性名获取Field对象
Field f = class对象.getDeclaredField(属性名)
(2)暴破:f.setAccessible(true)
(3)访问
f.set(o,值) //设值,o表示对象
f.get(o)
(4)如果是静态属性,则set和get中的参数o可以写成null
demo段:
2.访问方法
(1)根据方法名和参数列表获取Method方法对象:
Method m = clazz.getDeclaredMethod(方法名,xx.class); //得到本类的所有方法
(2)获取对象:Object o = clazz.newInstance();
(3)暴破:m.setAccessible(true);
(4)访问:Object returnValue = m.invoke(o,实参列表); //o是对象
(5)如果是静态方法,在invoke的参数o,可以写成null!
demo段:
0x04 两道练习题— So easy
练习1:通过反射修改私有成员变量
-
定义PrivateTest类,有私有name属性,并且属性值为hellokitty
-
提供getName的公有方法
-
创建PrivateTest的类,利用Class类得到私有的name属性,修改私有的name属性值并调用getName()的方法打印name属性值
代码:
练习2:利用反射和File完成以下功能
-
利用Class类的forName方法得到File类的class对象
-
在控制台打印File类的所有构造器
-
通过newInstance的方法创建File对象,并创建E:mynew.txt文件
提示:创建文件的正常写法如下:
File file = new File("d:\aa.txt");//内存
file.createNewFile();//方法,才能真正创建文件
代码:
0x05 总结
本文通过大量demo段和两道小题来练习了常见ReflectionAPI的使用,掌握了如何通过反射机制获取类的结构信息,创建对象,操作成员变量和成员方法。再一次体会到反射机制的强大之处:突破访问权限限制。
此处引用一位师傅对Java反射机制的描述:
JAVA反射就是运行中我可以调用程序的所有类,属性和方法,公有的也好,私有的也罢,都对我没有用。
突破限制,这就是JAVA反射
反射机制内容到此告一段落了。下一篇,我们来学习ysoserial工具中的urlDNS 链。
原文始发于微信公众号(沃克学安全):JAVA安全|基础篇:反射机制之常见ReflectionAPI使用
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论