class字节码减去5加密解密作业实现实操

class字节码减去5加密解密作业实现实操

自定义一个 Classloader,加载一个 Hello.xlass 文件,执行 main方法,此文件内容是一个 HelloByteCode.class 文件所有字节(x=255-x)处理后的文件。加密解密的原理很简单: 加密解密的一种简单方式

(一)HelloByteCode.class 反编译的内容

package demo.jvm0104;

public class HelloByteCode {
    public HelloByteCode() {
    }

    public static void main(String[] var0) {
        new HelloByteCode();
        System.out.println("Hello World[你好,世界]!");
    }
}

(二)具体实现

package org.geekbang.a_jvm.类加载器;

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

/**
 * @author 起凤
 * @description: TODO
 * @date 2022/3/6
 */
public class XlassLoader extends ClassLoader {
    private static final int X = 255;

    private String fullPath;
    private String fileNameWithSuffix;
    private Boolean needDecode = false;

    public XlassLoader() {
    }

    public XlassLoader(String fullPath, String fileNameWithSuffix) {
        this.fileNameWithSuffix = fileNameWithSuffix;
        this.fullPath = fullPath;
    }


    public void setFullPath(String fullPath) {
        this.fullPath = fullPath;
    }

    public void setNeedDecode(Boolean needDecode) {
        this.needDecode = needDecode;
    }

    @Override
    protected Class<?> findClass(String name) {
        byte[] byteArray;
        Class<?> clazz = null;
        try (InputStream inputStream = new FileInputStream(fullPath)) {
            int length = inputStream.available();
            byteArray = new byte[length];
            inputStream.read(byteArray);
            if (needDecode) {
                byteArray = decode(byteArray, length);
            }
            clazz = defineClass(name, byteArray, 0, byteArray.length);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return clazz;
    }

    public void createEncodeFile(String prefix, String suffix, String path) throws IOException {
        File hello = this.createFile("Hello", ".xlass", path);

        try (FileInputStream fin = new FileInputStream(path + fileNameWithSuffix);
             FileOutputStream fos = new FileOutputStream(hello)) {
            ///hello.deleteOnExit();
            ///int length = fin.available();
            byte[] byteArray = new byte[64];
            int hasRead = 0;
            while ((hasRead = fin.read(byteArray)) > 0) {
                // 编码 255-byte
                byte[] bytes = encode(byteArray, hasRead);
                fos.write(bytes, 0, hasRead);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public File createFile(String prefix, String suffix, String path) throws IOException {
        File file = new File(path + prefix + suffix);
        if (file.exists()) {
            file.delete();
        }
        /// File newFile = File.createTempFile(prefix, suffix, new File(path));// 创建临时文件,前缀+随机数+后缀
        file.createNewFile();
        return file;
    }

    public byte[] encode(byte[] bytes, int length) {
        byte[] newBytes = new byte[length];
        for (int i = 0; i < length; i++) {
            newBytes[i] = (byte) (X - bytes[i]);
        }
        return newBytes;
    }

    public byte[] decode(byte[] bytes, int length) {
        byte[] newBytes = new byte[length];
        for (int i = 0; i < length; i++) {
            newBytes[i] = (byte) (X - bytes[i]);
        }
        return newBytes;
    }

    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, IOException {
        String fullPath = "C:/Users/起凤/Desktop/temp/demo/jvm0104/HelloByteCode.class";
        String path = "C:/Users/起凤/Desktop/temp/demo/jvm0104/";
        String fileNameWithSuffix = "HelloByteCode.class";
        String prefix = "Hello";
        String suffix = ".xlass";
        String signature = "demo.jvm0104.HelloByteCode";


        XlassLoader xlassLoader = new XlassLoader(fullPath, fileNameWithSuffix);
        Class<?> clazz = xlassLoader.loadClass(signature);
        Method main = clazz.getMethod("main", String[].class);
        main.invoke(null, (Object) null);
        // clazz.newInstance();

        System.out.println("======================= 分割线 ======================");

        // 将HelloByteCode.class编码生成 Hello.xlass,然后用自定义类加载器解码加载执行main方法
        xlassLoader.createEncodeFile(prefix, suffix, path);
        String fullPath1 = "C:/Users/起凤/Desktop/temp/demo/jvm0104/Hello.xlass";
        XlassLoader loader = new XlassLoader();
        loader.setFullPath(fullPath1);
        loader.setNeedDecode(true);
        Class<?> helloClass = loader.loadClass(signature);
        main = helloClass.getMethod("main", String[].class);
        main.invoke(null, (Object) null);
    }
}

(三)测试结果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值