【JavaSec】Java反射知识点补充

news2024/9/22 21:16:21

0x03反射-补充零散知识点

文章目录

  • 0x03反射-补充零散知识点
    • Runtime类
      • setAccessible(true)
      • 三种命令执行的方法
      • static变量赋值 前面学过 就不多说
      • final变量赋值
      • InDirect final间接赋值
      • static + final

向大佬致敬: https://drun1baby.top

  • Runtime类

Runtime 类中有 exec 方法,可以用来命令执行。

  • setAccessible(true)

一般情况下,我们使用反射机制不能对类的私有 private 字段进行操作,绕过私有权限的访问

  • 三种命令执行的方法

package IOStream;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;

public class FileStreamTest {
    public static void main(String[] args){
        InputStream inputStream = null;
        try {
            //命令执行方法1
//            inputStream = Runtime.getRuntime().exec("whoami").getInputStream();

            //命令执行方法2
//            inputStream = new ProcessBuilder("calc").start().getInputStream();

            //命令执行方法3 反射间接调用
            String[] cmds = new String[]{"calc"};
            Class clazz = Class.forName("java.lang.ProcessImpl");
            Method method = clazz.getDeclaredMethod("start", String[].class, Map.class, String.class, ProcessBuilder.Redirect[].class, boolean.class);
            method.setAccessible(true);
            Process e = (Process) method.invoke(null, cmds, null, ".", null, true);
            inputStream = e.getInputStream();


        } catch (ClassNotFoundException | NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        byte[] cache = new byte[1024];   //cache缓存
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        int readLen = 0;
        while(true){
            try {
                if (!((readLen = inputStream.read(cache)) != -1)) break;
            } catch (IOException e) {
                e.printStackTrace();
            }
            byteArrayOutputStream.write(cache, 0, readLen);
        }
        //输出上面exec命令执行的结果
        System.out.println(byteArrayOutputStream);
    }
}

try catch中的内容是自动生成的

直接赋值

FinalPerson:

package ReflectPlus.pojo;

public class FinalPerson {
    private final String name = "happySu";
    public final int age = 18;

    public void printInfo(){
        System.out.println(name +" " + age);
    }
}

FinalReflect:

package ReflectPlus.Service;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class FinalReflection {
    public static void main(String[] args){
        try{
            //直接引入包的位置  不要再加src了
            Class c = Class.forName("ReflectPlus.pojo.FinalPerson");
            Object m = c.newInstance();
            Method printMethod = c.getDeclaredMethod("printInfo");
            printMethod.invoke(m);

            Field nameField = c.getDeclaredField("name");
            Field ageField = c.getDeclaredField("age");

            nameField.setAccessible(true);
            ageField.setAccessible(true);
            System.out.println("================");
            nameField.set(m,"111");
            ageField.set(m,12);

            printMethod.invoke(m);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

但是根本无法修改成功 永远18!

image-20240820100600963

  • InDirect final间接赋值

Person:

package ReflectPlus.pojo;

public class InDirectPerson {
    private final StringBuilder sex = new StringBuilder("male");
    public final int age = (null != null ? 18 : 18);

    //构造函数方法赋值
    private final String name;
    public InDirectPerson(){
        name = "happy";
    }
    public void printInfo(){
        System.out.println(name + " " + age + " " + sex);
    }
}

Reflect:

package ReflectPlus.Service;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class InDirectReflect {
    public static void main(String[] args){
        try{
            //调用
            Class c = Class.forName("ReflectPlus.pojo.InDirectPerson");
            Object m = c.newInstance();
            Method printMethod = c.getDeclaredMethod("printInfo");
            printMethod.invoke(m);

            System.out.println("=================");

            //修改
            Field nameField = c.getDeclaredField("name");
            Field ageField = c.getDeclaredField("age");
            Field sexField = c.getDeclaredField("sex");

            nameField.setAccessible(true);
            ageField.setAccessible(true);
            sexField.setAccessible(true);
            nameField.set(m, "newhappy");
            ageField.set(m,180);
            sexField.set(m,new StringBuilder("female"));
            printMethod.invoke(m);

        }catch(Exception e){
            e.printStackTrace();
        }

    }

}

image-20240820103054529

直接成功

一点点想法:

这样看来能否修改成功的关键 不在于我们Reflect类是怎么写怎么构造的,而是Person类本身的情况

  • static + final

Person:

package ReflectPlus.pojo;

public class StaticFinalPerson {
    static final StringBuilder name = new StringBuilder("happySu");

    public void printInfo(){
        System.out.println(name);
    }


}

Reflect:

package ReflectPlus.Service;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class StaticFinalReflect {
    public static void main(String[] args){
        try{
            //调用
            Class c = Class.forName("ReflectPlus.pojo.StaticFinalPerson");
            Object m = c.newInstance();
            Method printMethod = c.getDeclaredMethod("printInfo");
            printMethod.invoke(m);

            //修改
            Field nameField = c.getDeclaredField("name");
            nameField.setAccessible(true);
            Field nameModifyField = nameField.getClass().getDeclaredField("modifiers");
            nameModifyField.setAccessible(true);
            nameModifyField.setInt(nameField, nameField.getModifiers() & ~Modifier.FINAL);

            nameField.set(m, new StringBuilder("newhappy"));

            nameModifyField.setInt(nameField, nameField.getModifiers() & ~Modifier.FINAL);
            printMethod.invoke(m);


        }catch(Exception e){
            e.printStackTrace();
        }

    }

}

在原始情况下 是无法利用的

image-20240820105246850

报错解决

image-20240820110100985

看到无法调用private的变量 发现修改的时候粗心了

成功

image-20240820110154124

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2055335.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JAVA itextpdf 段落自动分页指定固定行距打印

JAVA itextpdf 段落自动分页指定固定行距打印 前言:公司有个需求,打印的合同模板左上角要加上logo的图标。但是itext pdf 自动分页会按照默认的顶部高分页打印内容的,导致从第二页开始logo图标就会把合同的内容给覆盖掉了。然后尝试了挺多方法…

Electron31-ViteAdmin桌面端后台|vite5.x+electron31+element-plus管理系统Exe

原创自研Vue3Electron31ElementPlus桌面端轻量级后台管理Exe系统。 基于最新前端技术栈Vite5.x、Vue3、Electron31、ElementPlus、Vue-I18n、Echarts实战开发桌面端高颜值后台管理模板。内置4种布局模板,支持i18n国际化、动态权限路由,实现了表格、表单、…

基于Spring Boot的大学校园生活信息平台的设计与实现pf

TOC springboot523基于Spring Boot的大学校园生活信息平台的设计与实现pf 绪论 1.1 研究背景 当前社会各行业领域竞争压力非常大,随着当前时代的信息化,科学化发展,让社会各行业领域都争相使用新的信息技术,对行业内的各种相关…

记录阿里云服务器购买和域名绑定解析的流程

购买阿里云域名和服务器 因为App备案的原因,需要购买域名和服务器,这篇文章介绍在阿里云上购买相关服务的流程。 注册阿里云的流程比较简单这里不再赘述了。请参考我之前写的 阿里云账号注册详细教程 购买顺序:一般是先购买阿里云服务器&…

【乐吾乐大屏可视化组态编辑器】事件交互-场景交互

场景交互 在线使用:https://v.le5le.com/ 乐吾乐大屏可视化可以实现大屏页面与内嵌2d/3d场景相互通信,底层原理是利用了iframe通过postMessage发送消息。 下面以2d场景为例,实现步骤如下: 1. 首先配置场景2(被嵌入…

Postman接口测试项目实战

第 1 章 什么是接口测试 1.1、为什么要进行接口测试 目前除了特别Low的公司外,开发都是前后端分离的,就是说前端有前端的工程师进行编码,后端有后端的工程师进行编码,前后端进行数据基本都是通过接口进行交互的。 1.2、接口测…

ant design 的 tree 如何作为角色中的权限选择之一

这种功能如何弄呢&#xff1f; 编辑的时候要让权限能选中哦。 <ProForm.Item name"permissions" label{intl.formatMessage({ id: permission_choose })}><Spin spinning{loading}><TreecheckableonExpand{onExpand}expandedKeys{expandedKeys}auto…

StringJoiner以及字符串小练习

概述 String Joiner跟String Builder一样&#xff0c;亦可以看成是一个容器&#xff0c;创建之后iu里面的内容是可变的 作用 提高字符串的操作效率&#xff0c;而且代码编写特别简洁&#xff0c;但是目前市场上很少有人用 JDK8 package stringdemo;import java.util.String…

iTOP-3A5000开发板流畅运行国产系统外加机箱就是一台电脑主机

性能强 采用全国产龙芯3A5000处理器&#xff0c;基于龙芯自主指令系统 (LoongArch)的LA464微结构&#xff0c;并进一步提升频率&#xff0c;降低功耗&#xff0c;优化性能。 桥片 采用龙芯 7A2000&#xff0c;支持PCIE 3.0、USB 3.0和 SATA 3.0.显示接口2 路、HDMI 和1路 VGA&a…

插入数据时,出现存在重复数据异常,捕获异常的信息

Cause: java.sql.SQLIntegrityConstraintViolationException: Duplicate entry xiaomi111-啊啊啊啊 for key edu_class.institution_account 执行插入操作的时候抛出这个异常 怎么捕获这个异常 可以判断 e instanceof 某个具体的异常 然后再进像下面操作&#xff0c;打印出来…

重生奇迹MU:‌重塑经典,‌再创辉煌

在浩瀚的游戏宇宙中&#xff0c;‌有一颗璀璨的星辰&#xff0c;‌它承载着无数玩家的青春回忆与梦想&#xff0c;‌那就是——重生奇迹MU‌。‌作为一款历经岁月洗礼的经典网游&#xff0c;重生奇迹MU不仅见证了游戏行业的蓬勃发展&#xff0c;‌更以其独特的魅力&#xff0c;…

倒计时:可添加可删除的倒计时函数

<!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>倒计时</title> </head><body>…

关于医疗器械维修行业的一些思考

在当今医疗体系中&#xff0c;医疗器械维修行业扮演着不可或缺的角色。作为一名长期关注这一领域的人士&#xff0c;我对其有着一些个人的看法。 首先&#xff0c;医疗器械维修行业的重要性不言而喻。先进的医疗器械是现代医疗诊断和治疗的重要工具&#xff0c;而确保这些设备…

计算机组成原理(3):存储系统

1 存储器概述 主存储器其实就是内存&#xff01; 1.1 存储器的层次结构 ​ 存储器的三大评判指标&#xff1a;速度、容量、价格 ​ 使用任意一种存储器&#xff0c;都无法满足用户对存储器 高速、大容量、低价格 的需求&#xff0c;所以采用 多级结构 形成对应的 “存储体系“。…

从零开始学习网络安全渗透测试之信息收集篇——(二)WEB前端JS架构框架识别泄漏提取API接口枚举FUZZ爬虫插件项目

0、什么是JS渗透测试? 在Javascript中也存在变量和函数&#xff0c;当存在可控变量及函数调用即可参数漏洞JS开发的WEB应用和PHP&#xff0c;JAVA,NET等区别在于即没有源代码&#xff0c;也可以通过浏览器的查看源代码获取真实的点。获取URL&#xff0c;获取JS敏感信息&#…

mkv怎么改成mp4?3种mkv转mp4格式方法的介绍

mkv怎么改成mp4&#xff1f;将MKV格式视频转换为MP4格式&#xff0c;能显著提升兼容性&#xff0c;让视频在更多设备、平台上流畅播放。无论是智能手机、平板电脑、智能电视还是网页浏览器&#xff0c;MP4格式都具备广泛的支持&#xff0c;从而扩大视频的传播范围和受众群体。这…

Android Studio open 一个项目覆盖了当前项目

在新电脑上&#xff0c;想在Android studio 同时打开几个项目,出现了打开新项目会覆盖当前项目的问题&#xff0c; 修复方法如下&#xff1a; File >Settings>System Settings> 按需选择即可&#xff0c;如Ask

建造者模式 和 外观模式

这两种模式很像, 都是将一个复杂的流程统一用一个方法进行包装, 方便外界使用. 建造者模式更像是 外观模式的一种特里, 只对一个类的复杂初始化流程进行包装 建造者模式 简介: 就是一个类的构造方法可能很复杂, 由于系统的限制等原因, 可能很多初始化逻辑不能放在构造函数里,…

微信答题小程序产品研发-数据库与数据表设计

设计答题小程序的数据库和数据表时&#xff0c;我充分考虑了数据的完整性、一致性、安全性和查询效率。 然后&#xff0c;我整理一份关于答题小程序的数据库设计方案。 1. 数据库设计原则 &#xff08;1&#xff09;规范化&#xff1a;确保数据表的设计遵循数据库规范化原则&…

想要在本地生活服务平台赚钱?赶紧了解这些秘籍!

当前&#xff0c;由于本地生活的市场前景不断展现和各大官方平台在本地生活服务商申请、考核方面等多方面要求的持续收紧&#xff0c;本地生活服务平台的搭建逐渐成为了许多创业者首选入局途径&#xff0c;与之相关的本地生活服务平台的盈利点更是因此成为了他们最关心的话题。…