日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > c/c++ >内容正文

c/c++

c++ 反射_Java代码审计基础之反射

發(fā)布時(shí)間:2024/8/5 c/c++ 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c++ 反射_Java代码审计基础之反射 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

先來(lái)一段反射的概念:

在程序運(yùn)行的時(shí)候動(dòng)態(tài)裝載類(lèi),查看類(lèi)的信息,生成對(duì)象,或操作生成對(duì)象。
類(lèi)在運(yùn)行的時(shí)候,可以得到該類(lèi)的信息,并且可以動(dòng)態(tài)的修改這些信息

反射類(lèi)的首要操作 - 獲取類(lèi)

獲取類(lèi)有 三種 方法:

假設(shè)類(lèi)名為 Cat

(1)直接根據(jù)類(lèi)名獲取類(lèi)

Class a = Cat.class;

(2)通過(guò)Class.forName 獲取類(lèi),需要打全指定類(lèi)的路徑

Class a = Class.forName("org.xiaopan.test.Cat");

注意:

Class.forName 需要一個(gè)異常處理。不然編輯器無(wú)法通過(guò)。

(3)通過(guò)實(shí)例化的方式獲取類(lèi)

Class a = (new Cat()).getClass();

反射構(gòu)造方法

吾有一類(lèi),曰:

class Cat{ //構(gòu)造方法,形參為空 public Cat(){ System.out.println("Cat->nullCat"); } //構(gòu)造方法,形參為 一個(gè)String類(lèi)型 public Cat(String a){ System.out.println("Cat->aCat,a=" + a); } //私有構(gòu)造方法,形參為 一個(gè)String類(lèi)型 和 一個(gè)Integer類(lèi)型 private Cat(String a,Integer b){ System.out.println("Cat->abCat,a=" + a + "b=" + b.toString()); } //構(gòu)造方法,形參為 一個(gè)String數(shù)組類(lèi)型 和 一個(gè)Map類(lèi)型 public Cat(String[] aa,Map bb){ System.out.println("Cat->aabbCat"); System.out.println("aa=" + Arrays.toString(aa)); System.out.println("bb=" + bb); }}

無(wú)參構(gòu)造方法調(diào)用

try{ //獲取到類(lèi) Class a = Cat.class; //通過(guò)反射獲取到指定類(lèi)下的構(gòu)造方法 //要獲取的構(gòu)造方法為: //public Cat() //由于該構(gòu)造方法無(wú)參數(shù),所以我們傳入一個(gè) null 即可,也可以不傳 Constructor constructor1 = a.getConstructor(null); //實(shí)例化類(lèi) constructor1.newInstance(null);}catch (Exception e){ System.out.println(e);}

輸出:

注意:

getConstructor 需要加一個(gè)異常處理。

一個(gè)參數(shù)的構(gòu)造方法調(diào)用

try{ //獲取到類(lèi) Class a = Cat.class; //通過(guò)反射獲取到指定類(lèi)下的構(gòu)造方法 //要獲取的構(gòu)造方法為: //public Cat(String a) //由于該構(gòu)造方法有一 String類(lèi)型 參數(shù) //在進(jìn)行 getConstructor 反射時(shí),就需要指定傳參類(lèi)型為 String.class Constructor constructor1 = a.getConstructor(String.class); //在實(shí)例化時(shí),進(jìn)行傳參 constructor1.newInstance("testvalue");}catch (Exception e){ System.out.println(e);}

輸出:

多個(gè)參數(shù)的私有構(gòu)造方法調(diào)用

注意,這里調(diào)用的構(gòu)造方法是私有的哦~

try{ //獲取到類(lèi) Class a = Class.forName("org.xiaopan.test.Cat"); //通過(guò)反射獲取到指定類(lèi)下的構(gòu)造方法 //要獲取的 私有 構(gòu)造方法為: //private Cat(String a,Integer b) // //由于是 私有 方法,獲取私有方法的函數(shù)為 getDeclaredConstructor //由于有兩個(gè)參數(shù),所以需要在 getDeclaredConstructor 傳入對(duì)應(yīng)的參數(shù)類(lèi)型 Constructor c = a.getDeclaredConstructor(String.class, Integer.class); //設(shè)置強(qiáng)制反射 c.setAccessible(true); //構(gòu)造函數(shù)實(shí)例化,并傳參 //這里有個(gè)注意點(diǎn),看下文的注意 c.newInstance(new Object[]{"abcd",123456});}catch (Exception e){ System.out.println(e);}

輸出:

注意:

參考了大佬的文章(參考文章在本文末尾 Referer 中),文章說(shuō) jdk1.4和 jdk1.5 處理調(diào)用的方法有區(qū)別

jdk1.4中,數(shù)組每個(gè)元素對(duì)應(yīng)一個(gè)參數(shù)

jdk1.5中,整個(gè)數(shù)組是一個(gè)參數(shù),用一個(gè)對(duì)象包起來(lái)

所以我們調(diào)用的傳參的時(shí)候,需要使用這種格式:

c.newInstance(new Object[]{"abcd",123456});//即new Object[]{"abcd",123456} 的格式,用一個(gè)對(duì)象包裹起來(lái)

形參為數(shù)組和Map類(lèi)型的構(gòu)造方法調(diào)用

字符串?dāng)?shù)組

創(chuàng)建格式:

String[] a = {"abc", "def"};

Map:

java中的map,可以理解為“可自定義鍵值的數(shù)組”

形參為數(shù)組和Map類(lèi)型的構(gòu)造方法調(diào)用:

try{ //獲取類(lèi) Class a = (new Cat()).getClass(); //調(diào)用的構(gòu)造方法為: //public Cat(String[] aa,Map bb) //照常打 xxx.class 即可。java 萬(wàn)物皆對(duì)象 Constructor c = a.getConstructor(String[].class, Map.class); //創(chuàng)建一個(gè)map Map m = new HashMap(); m.put("a_key","a_value"); //實(shí)例化構(gòu)造函數(shù),注意要用 Object包裹的形式 //new String[]{} 是當(dāng)場(chǎng)初始化字符串?dāng)?shù)組,當(dāng)場(chǎng)賦值 c.newInstance(new Object[]{new String[]{"a","b","c"}, m});}catch (Exception e){ System.out.println(e);}

輸出:

反射方法

簡(jiǎn)介:

反射方法和上文的反射構(gòu)造方法差不多,如果是私有的話(huà)也是要設(shè)置強(qiáng)行調(diào)用,并且獲取方法的函數(shù)為 getDeclaredxxxx

吾有一類(lèi):

class Cat{ public void a(){ System.out.println("a invoke"); } public String[] b(String[] b){ return b; } public static void c(){ System.out.println("cccccc"); }}

反射無(wú)參數(shù)方法

try{ //獲取類(lèi) Class a = Class.forName("org.xiaopan.test.Cat"); //先實(shí)例化,后面調(diào)用方法的時(shí)候需要使用實(shí)例化好的類(lèi) //注意,實(shí)例化之后返回的類(lèi)型就是對(duì)于的類(lèi),做好類(lèi)型轉(zhuǎn)換 Cat cat =(Cat) a.newInstance(); //調(diào)用的方法為: //public void a() // //獲取方法,需要指定要獲取的方法名 Method m = a.getMethod("a", null); //調(diào)用方法,調(diào)用方法時(shí),用 上一步代碼中獲取到的方法進(jìn)行 invoke 調(diào)用操作 //而invoke方法中,第一個(gè)參數(shù)是實(shí)例化好的類(lèi) //第二個(gè)參數(shù)就是需要傳入的參數(shù) m.invoke(cat,null);}catch (Exception e){ System.out.println(e);}

輸出:

反射有參數(shù)有返回值方法

try{ //獲取類(lèi) Class a = Class.forName("org.xiaopan.test.Cat"); //先實(shí)例化,后面調(diào)用方法的時(shí)候需要使用實(shí)例化好的類(lèi) //注意,實(shí)例化之后返回的類(lèi)型就是對(duì)于的類(lèi),做好類(lèi)型轉(zhuǎn)換 Cat cat =(Cat) a.newInstance(); //調(diào)用的方法為: //public String[] b(String[] b) // //獲取方法,需要指定要獲取的方法名 Method m = a.getMethod("b",String[].class); //調(diào)用方法,調(diào)用方法時(shí),用 上一步代碼中獲取到的方法進(jìn)行 invoke 調(diào)用操作 //調(diào)用時(shí),如果參數(shù)是字符串?dāng)?shù)組,或者兩個(gè)以上的參數(shù) //最好使用 new Object[]{} 的形式傳入 //兼容性好 //由于有返回值,我們?cè)谡{(diào)用的時(shí)候也需要進(jìn)行接收 //接受類(lèi)型就看調(diào)用的類(lèi)返回的類(lèi)型了 String[] strs = (String[]) m.invoke(cat, new Object[]{new String[]{"str1","str2","str3"}}); //打印數(shù)組: //for each打印數(shù)組,先指定抽出來(lái)的元素類(lèi)型 //然后以冒號(hào) : 分隔,左邊是抽出元素變量名,右邊是原數(shù)組 for (String str:strs){ System.out.println(str); }}catch (Exception e){ System.out.println(e);}

輸出:

反射靜態(tài)方法

由于靜態(tài)方法不需要實(shí)例化類(lèi),所以在 getMethod 的時(shí)候,直接傳個(gè) null 即可。也不需要 newInstance 類(lèi)了。

try{ //獲取類(lèi) Class a = Class.forName("org.xiaopan.test.Cat"); //調(diào)用的方法為: //public static void c() // //獲取方法 Method m = a.getMethod("c"); //由于是靜態(tài)方法。直接調(diào)用,類(lèi)對(duì)象中傳入null即可 m.invoke(null);}catch (Exception e){ System.out.println(e);}

輸出:

反射屬性

反射屬性也大同小異

吾有一類(lèi):

class Cat{ public String name = "maomao"; //公共 String類(lèi)型 屬性 public static Boolean sex = true; //公共 靜態(tài) String類(lèi)型 屬性 private Integer age = 10; //私有 Integer類(lèi)型 屬性}

反射公共屬性

try{ //獲取類(lèi) Class a = Class.forName("org.xiaopan.test.Cat"); //先實(shí)例化,后面獲取屬性的時(shí)候需要使用實(shí)例化好的類(lèi) Cat cat = (Cat) a.newInstance(); //屬性: //public String name = "maomao"; // //獲取屬性 Field m = a.getField("name"); //獲取屬性值 //需要傳入實(shí)例化類(lèi)作為對(duì)象 String name = (String) m.get(cat); System.out.println(name);}catch (Exception e){ System.out.println(e);}

輸出:

反射公共靜態(tài)屬性

靜態(tài)屬性也一樣,不需要實(shí)例化即可調(diào)用:

try{ //獲取類(lèi) Class a = Class.forName("org.xiaopan.test.Cat"); //屬性: //public static Boolean sex = true; // //獲取屬性 Field m = a.getField("sex"); //獲取屬性值,靜態(tài)屬性不需要實(shí)例化類(lèi),直接傳入null作為類(lèi)對(duì)象即可 Boolean b = (Boolean) m.get(null); System.out.println(b); //設(shè)置屬性值 m.set(null,false); b = (Boolean) m.get(null); System.out.println(b);}catch (Exception e){ System.out.println(e);}

輸出:

反射私有屬性

私有屬性也一樣,需要暴力反射

try{ //獲取類(lèi) Class a = Class.forName("org.xiaopan.test.Cat"); //先實(shí)例化,后面獲取屬性的時(shí)候需要使用實(shí)例化好的類(lèi) Cat cat = (Cat) a.newInstance(); //屬性: //private Integer age = 10; // //獲取私有屬性 Field m = a.getDeclaredField("age"); //設(shè)置強(qiáng)制反射 m.setAccessible(true); //獲取屬性值 Integer age = (Integer) m.get(cat); //注意輸出的時(shí)候要將非String類(lèi)型 toString 哦,規(guī)范一點(diǎn) System.out.println(age.toString());}catch (Exception e){ System.out.println(e);}

輸出:

引用包錯(cuò)誤的報(bào)錯(cuò):

用IDEA寫(xiě)代碼的時(shí)候,可以會(huì)遇到奇怪報(bào)錯(cuò),如:

代碼本來(lái)就沒(méi)問(wèn)題,但還是報(bào)錯(cuò)了:

這個(gè)時(shí)候可以看看代碼最上面,看看IDEA是不是自動(dòng)引入了錯(cuò)誤的包:

發(fā)現(xiàn)有引用錯(cuò)誤的包,將其刪掉即可,然后再重新在 Method上進(jìn)行修復(fù):

Runtime.getRuntime.exec 反射

了解 Runtime.getRuntime.exec

Runtime.getRuntime.exec 是Java中執(zhí)行系統(tǒng)命令的方法

簡(jiǎn)單使用如下:

byte[] a = new byte[1024];Process cmd = Runtime.getRuntime().exec("whoami");InputStream input = cmd.getInputStream();input.read(a);String res = new String(a);System.out.println(res);

我們來(lái)一一分析下,重點(diǎn)就兩大塊:Process 和 InputStream

Process cmd = Runtime.getRuntime().exec(“whoami”)

首先先看看 Runtime.getRuntime().exec 是什么東西,返回值類(lèi)型是什么樣的:

在手冊(cè)上查看描述:

可知 exec 函數(shù)就是執(zhí)行系統(tǒng)命令用的

在去看看源碼做二次確認(rèn)

返回類(lèi)型是 Process 類(lèi)型,所以我們調(diào)用的時(shí)候用 Process 類(lèi)型接收返回值

Process類(lèi)提供進(jìn)程輸入、輸出等進(jìn)程方法。粗淺的說(shuō)就是一個(gè)進(jìn)程類(lèi)

通過(guò)文檔可以得知,我調(diào)用的這個(gè)exec方法需要一個(gè)String類(lèi)型的參數(shù),即要執(zhí)行的系統(tǒng)命令

InputStream input = cmd.getInputStream()

其中:

InputStream ? ?輸入流,即數(shù)據(jù)流入,讀入數(shù)據(jù)

OutputStream 輸出流,即數(shù)據(jù)輸出,寫(xiě)入數(shù)據(jù)

該代碼讀取上一步 Process 類(lèi)型的數(shù)據(jù)流

input.read(a);

在上一步調(diào)用getInputStream后,可執(zhí)行 read 函數(shù)。

將當(dāng)前的數(shù)據(jù)流讀取出來(lái),寫(xiě)入到一個(gè) byte[]類(lèi)型的變量里。

String res = new String(a);

將byte類(lèi)型轉(zhuǎn)換成字符串。以便后面打印輸出

這就是一個(gè)簡(jiǎn)單的 Java 命令執(zhí)行并回顯結(jié)果。

我們可以看到主要調(diào)用了 Runtime.getRuntime().exec

那么我們要如何通過(guò)反射的方式進(jìn)行調(diào)用呢?

反射調(diào)用 Runtime.getRuntime().exec

第一種方式,通過(guò)強(qiáng)行反射私有構(gòu)造方法,用 Runtime 實(shí)例化進(jìn)行反射

這里有一個(gè)小坑,Runtime的構(gòu)造函數(shù)是私有的:

所以我們要強(qiáng)制反射私有構(gòu)造方法,而且不能直接 newInstance Class:

錯(cuò)誤寫(xiě)法:

直接用Class來(lái)進(jìn)行實(shí)例化

Class runtime = Class.forName("java.lang.Runtime");runtime.newInstance();

會(huì)報(bào)錯(cuò):

java.lang.IllegalAccessException: Class org.xiaopan.test.Main can not access a member of class java.lang.Runtime with modifiers “private”

正確寫(xiě)法:

先強(qiáng)制反射Runtime的構(gòu)造方法,再實(shí)例化構(gòu)造方法。

Class runtime = Class.forName("java.lang.Runtime");Constructor c = runtime.getDeclaredConstructor();c.setAccessible(true);c.newInstance();

反射調(diào)用Runtime.gettime.exec

byte[] a = new byte[1024];try{ //獲取Runtime類(lèi) Class runtime = Class.forName("java.lang.Runtime"); //獲取Runtime類(lèi)構(gòu)造方法 Constructor c_runtime = runtime.getDeclaredConstructor(); //設(shè)置強(qiáng)制反射 c_runtime.setAccessible(true); //Runtime類(lèi)的構(gòu)造方法 實(shí)例化 //由于 Runtime類(lèi)構(gòu)造方法返回類(lèi)型為 Runtime類(lèi),所以需要使用 Runtime 類(lèi)型變量進(jìn)行接收 Runtime r = (Runtime) c_runtime.newInstance(); //獲取 Runtime類(lèi)的方法 exec Method m = runtime.getMethod("exec", String.class); //調(diào)用 exec 方法,傳入對(duì)象為 Runtime類(lèi)的構(gòu)造方法實(shí)例化 //由于 exec 方法返回的是 Process 類(lèi)型數(shù)據(jù),所以需要使用 Process 類(lèi)型變量進(jìn)行接收 Process p = (Process) m.invoke(r,"whoami"); //讀入數(shù)據(jù)流,讀入到 byte[] 類(lèi)型的變量中 p.getInputStream().read(a); System.out.println(new String(a));}catch (Exception e){ System.out.println(e);}

成功輸出:

第二種方式,不進(jìn)行 Runtime實(shí)例化,直接通過(guò)getRuntime進(jìn)行反射

注意點(diǎn):

發(fā)現(xiàn)盲點(diǎn):在本節(jié)一開(kāi)頭,調(diào)用系統(tǒng)命令函數(shù) exec 的形式如下:

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

我們?nèi)ピ创a翻翻 getRuntime()是個(gè)什么函數(shù)

我們可以發(fā)現(xiàn),getRuntime就是為了返回 Runtime類(lèi) 實(shí)例的,感覺(jué)應(yīng)該是一個(gè) 單例模式

我們遵守源碼的規(guī)則,直接調(diào)用 getRuntime,拿到 Runtime類(lèi)實(shí)例

注意點(diǎn):

由于 getRuntime方法 返回的是 Runtime類(lèi)實(shí)例,所以反射的時(shí)候需要顯示類(lèi)型轉(zhuǎn)換。

代碼如下:

byte[] a = new byte[1024];try{ //獲取 Runtime 類(lèi) Class runtime = Class.forName("java.lang.Runtime"); //獲取getRuntime方法 Method m = runtime.getMethod("getRuntime"); //調(diào)用getRuntime方法,并用 Runtime類(lèi) 類(lèi)型進(jìn)行接收,顯式轉(zhuǎn)換成 Runtime類(lèi) //調(diào)用的時(shí)候,在上文查看源碼時(shí),發(fā)現(xiàn)是不需要傳入?yún)?shù)的 //不需傳入?yún)?shù),我們直接傳一個(gè) null 進(jìn)去即可 Runtime r = (Runtime) m.invoke(null); //由于上一個(gè)代碼中調(diào)用 getRuntime 方法,返回了 Runtime類(lèi) //我們直接就可以調(diào)用底下的 exec 方法了 Process p = r.exec("ifconfig"); //數(shù)據(jù)輸入流,讀入數(shù)據(jù) InputStream res = p.getInputStream(); res.read(a); System.out.println(new String(a));}catch (Exception e){ System.out.println(e);}

成功輸出:

Referer:

java手冊(cè):

https://www.oracle.com/cn/java/technologies/java-se-api-doc.html

大佬文章:

https://blog.csdn.net/ju_362204801/article/details/90578678

精彩推薦

總結(jié)

以上是生活随笔為你收集整理的c++ 反射_Java代码审计基础之反射的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 午夜精品久久久久久久四虎美女版 | 色一情一乱一伦一区二区三区 | 毛片毛片毛片毛片毛片毛片毛片毛片 | 激情91视频| 国产精品久久久久久久久 | 香港一级纯黄大片 | 梦梦电影免费高清在线观看 | 国产乱子伦精品视频 | 韩国午夜激情 | 好吊操精品视频 | 一区二区自拍偷拍 | 国产成人愉拍精品久久 | 91精品久久久久久粉嫩 | 老熟妻内射精品一区 | 成人福利免费视频 | 中国在线观看视频高清免费 | 亚洲一区二区观看播放 | 97人妻人人澡人人爽人人精品 | 国产中文久久 | 精品少妇人妻AV无码专区在线 | 91精品视频在线免费观看 | av大片在线播放 | 精品日本一区二区 | 狠狠操2019 | 国产精品美女久久久久 | 久久噜噜噜 | 国产男男一区二区三区 | 日本一区二区视频在线 | 91精品国产一区二区无码 | 婷婷的五月天 | 日韩一区2区 | 大尺度做爰呻吟舌吻网站 | 日韩中文字幕二区 | 午夜男人天堂 | 一区二区不卡 | xvideos永久免费入口 | 色撸撸在线观看 | 国产丝袜在线视频 | 午夜精品视频在线观看 | 女人十八毛片嫩草av | 成人看片 | 亚洲欧美强伦一区二区 | 亚洲一区二区三区三州 | 操你妹影院 | 六月丁香综合网 | 丁香花在线影院观看在线播放 | 国产精品电影网站 | 免费av国产 | 婷色| 丝袜在线一区 | www.亚洲激情 | 永久免费看片在线播放 | 日本黄色免费大片 | 日本少妇xx | 欧美色啪| 天天操天天干天天爽 | 国产妇女视频 | 91欧美成人 | 亚洲精品高清在线观看 | 国产精品人人做人人爽 | 免费网站污 | 伊人自拍 | 欧美资源网| 懂色av一区二区三区免费观看 | 国产婷婷综合 | 一级aa毛片| 激情三区 | 开元在线观看视频国语 | 性感美女一级片 | 年下总裁被打光屁股sp | 91超碰在线观看 | 污视频在线网站 | 亚洲va视频 | 一区二区视频在线看 | 九九综合视频 | 久久精品第一页 | 日韩成人在线一区 | xxx日本黄色 | 久久男人的天堂 | 午夜片在线观看 | 黄色片在线观看视频 | 国产又粗又黄又爽又硬的视频 | 亚洲成人精品网 | 亚洲欧洲天堂 | 天天草天天摸 | 亚洲热在线视频 | 久久久久人妻精品一区二区三区 | 成人在线网址 | 毛片av在线播放 | 国语对白少妇spa私密按摩 | 91精品黄色 | 日日日网站 | 裸体的日本在线观看 | 久久久久99人妻一区二区三区 | 成人av免费播放 | 国产91白丝在一线播放 | 国产情侣小视频 | 亚洲精品国产精品乱码不99 | 肉丝肉足丝袜一区二区三区 |