反射
一、獲取反射對(duì)象(反射入口)
Class ===>三種方法:
1.Class.forName()
2.XX.Class
3.對(duì)象.getClass
package com.fanshe.demoClass;
import com.fanshe.demoClass.demoClass;
public class fanshe {
public static void main(String[] args) throws ClassNotFoundException {
// 1.Class.forName(全類名)
Class<?> democlass = Class.forName("com.fanshe.demoClass.demoClass");
System.out.println(democlass);
// 2.類名.class
Class<?> democlass2 = com.fanshe.demoClass.demoClass.class;
System.out.println(democlass2);
// 3.對(duì)象.getclass
demoClass democlass3 = new demoClass();
Class<?> democlass4 = democlass3.getClass();
System.out.println(democlass4);
}
}
2.獲取方法
1.獲取所有公共方法(本類和父類所有符合訪問(wèn)修飾符的方法(static))
public static void demo2() throws ClassNotFoundException{
Class<?> demo = Class.forName("com.fanshe.demoClass.demoClass");
// 獲取所有公共方法(本類和父類所有符合訪問(wèn)修飾符的方法(static))
Method[] methods = demo.getMethods();
for(Method method:methods){
System.out.println(method);
}
}
2.獲取當(dāng)前類的所有接口
public static void demo3() throws ClassNotFoundException{
Class<?> demo = Class.forName("com.fanshe.demoClass.demoClass");
Class<?>[] interfaces = demo.getInterfaces();
for(Class<?> inter:interfaces){
System.out.println(inter);
}
}
3.獲取所有父類
// 獲取所有父類
public static void demo4() throws ClassNotFoundException{
Class<?> demo = Class.forName("com.fanshe.demoClass.demoClass");
Class<?> superclass = demo.getSuperclass();
System.out.println(superclass);
}
4.獲取所有構(gòu)造方法
Constructor<?>[] constructors = demo.getConstructors();
5.獲取所有公共屬性
Field[ ] fields = demo.getFields();
6.獲取當(dāng)前類都所有方法
Method[] methods = demo.getDeclaredMethods();
7.獲取當(dāng)前類所有屬性
Field[ ] DeclaredField= demo.getDeclaredField();
8.創(chuàng)建新實(shí)例
Object instance = demo.newInstance();
(fanshe)instance;
二、操作反射對(duì)象
1.獲取對(duì)象都實(shí)例,并操作對(duì)象
public static void demo5() throws ClassNotFoundException, IllegalAccessException, InstantiationException {
Class<?> demo = Class.forName("com.fanshe.demoClass.demoClass");
demoClass demos = (demoClass)demo.newInstance();
demos.setName("zs");
demos.setId(1);
System.out.println(demos.getName());
}
2.操作屬性
public static void demo6() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException {
Class<?> demo = Class.forName("com.fanshe.demoClass.demoClass");
demoClass demos = (demoClass)demo.newInstance();
Field id = demo.getDeclaredField("id");
// 訪問(wèn)private修飾的屬性則需要加下面的代碼,修改訪問(wèn)權(quán)限
id.setAccessible(true);
id.set(demos,1);
System.out.println(demos.getId());
}
3.其他
其他的和上面都差不多,只是使用的方法不同。
反序列化
一、java序列化與反序列化
1.概念
Java 序列化是指把 Java 對(duì)象轉(zhuǎn)換為字節(jié)序列的過(guò)程便于保存在內(nèi)存、文件、數(shù)據(jù)庫(kù)中,ObjectOutputStream類的 writeObject() 方法可以實(shí)現(xiàn)序列化。
Java 反序列化是指把字節(jié)序列恢復(fù)為 Java 對(duì)象的過(guò)程,ObjectInputStream 類的 readObject() 方法用于反序列化
2.必備條件
1??.使用此方法進(jìn)行序列化的對(duì)象必須實(shí)現(xiàn)Serializable接口,不然在進(jìn)行序列化時(shí)會(huì)拋出NotSerializableException異常。
2??.該類的所有屬性必須是可序列化的。
3.例子
package serlize;
import java.io.*;
public class serialzaTest {
private test objectFromDisk;
public static void main(String[] args) throws Exception {
test Test = new test();
Test.name="zs";
//創(chuàng)建一個(gè)包含對(duì)象進(jìn)行反序列化信息的”object”數(shù)據(jù)文件
FileOutputStream fos = new FileOutputStream("object");
ObjectOutputStream os = new ObjectOutputStream(fos);
//writeObject()方法將myObj對(duì)象寫(xiě)入object文件
os.writeObject(Test);
os.close();
//從文件中反序列化obj對(duì)象
FileInputStream fis = new FileInputStream("object");
ObjectInputStream ois = new ObjectInputStream(fis);
//恢復(fù)對(duì)象
test objectFromDisk = (test) ois.readObject();
System.out.println(objectFromDisk.name);
ois.close();
}
}
class test implements Serializable{
public String name;
}
上訴例子中,通過(guò)new一個(gè)新的tes對(duì)象,并且test對(duì)象是實(shí)現(xiàn)了Serializable接口的,然后通過(guò)writeObject方法序列化對(duì)象,然后存入object文件中,然后在通過(guò)readObject方法來(lái)反序列化對(duì)象,然后將其強(qiáng)轉(zhuǎn)為test對(duì)象,我們可以直接輸出反序列化后得到對(duì)象的name屬性,得到"zs"。
4.反序列化rcedemo
package serlize;
import java.io.*;
public class serialzaTest {
private test objectFromDisk;
public static void main(String[] args) throws Exception {
test Test = new test();
Test.name="zs";
//創(chuàng)建一個(gè)包含對(duì)象進(jìn)行反序列化信息的”object”數(shù)據(jù)文件
FileOutputStream fos = new FileOutputStream("object");
ObjectOutputStream os = new ObjectOutputStream(fos);
//writeObject()方法將myObj對(duì)象寫(xiě)入object文件
os.writeObject(Test);
os.close();
//從文件中反序列化obj對(duì)象
FileInputStream fis = new FileInputStream("object");
ObjectInputStream ois = new ObjectInputStream(fis);
//恢復(fù)對(duì)象
test objectFromDisk = (test) ois.readObject();
System.out.println(objectFromDisk);
ois.close();
}
}
class test implements Serializable{
public String name;
private void readObject (java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
Runtime.getRuntime().exec("open /System/Applications/Calculator.app/");
}
@Override
public String toString() {
return this.name;
}
}
因?yàn)榉残蛄谢瘯r(shí)會(huì)使用到readobject這個(gè)方法,這個(gè)方法不管我們寫(xiě)不寫(xiě)java都需要去調(diào)用,才能成功反序列化,那么我們重寫(xiě)這個(gè)方法就可以達(dá)到反序列化rce的效果。
