利用ASM加密Jar包字符串

这篇博客介绍了如何利用ASM框架加密Jar包中的字符串,以解决Proguard无法混淆字符串的问题。ASM允许在类被加载到虚拟机前修改字节码,通过ASM可以创建和修改类,实现代码混淆和转换等任务。文章详细讲解了加密流程,包括定义加密方法、Main Class和ClassVistor,并强调理解Class文件字节码格式和ASM解析流程的重要性。
摘要由CSDN通过智能技术生成

ASM是一个JAVA字节码分析、创建和修改的开源应用框架。
它可以动态生成二进制格式的stub类或其它代理类,或者在类被JAVA虚拟机装入内存之前,动态修改类。

一般情况下,Class文件是通过javac编译器产生的,然后通过类加载器加载到虚拟机内,再通过执行引擎去执行。
现在我们可以通过ASM的API直接生成符合Java虚拟机规范的Class字节流,
从这个角度来看,ASM承担的工作与javac解释器的工作相似。

ASM可以从字节码的角度,分析、创建一个类,同时也可以修改一个已经被编译过的类文件。
因此,我们可以通过ASM来实现诸如代码生成、代码混淆、代码转换等等以字节码为操作目标的工作。

本篇博客就记录一下利用ASM来加密Jar中字符串的方法。
这么做的初衷是:
Proguard只能混淆代码,无法混淆代码中使用的字符串。
想要混淆字符串,可能要借助收费的DexGuard。
于是,可以利用ASM来直接加密Jar包。

P.S.:
我目前的公司,产品以SDK为主,输出为Jar包。
因此这里以加密Jar包为例。


关于ASM框架的详细内容就不再赘述了,直接上加密Jar的代码。
这里依赖的lib为asm-all-5.2.jar和commons-lang3-3.5.jar。

1、定义加密字符的方法

package com.encrypt.util;

/**
 * Created by zhangjian on 18-3-29
 */
public class Transform {
   
    /**
     * 将字符串编码成16进制数字,适用于所有字符(包括中文)
     */
    public static byte[] encode(byte[] bytes, String key) {
        int len = bytes.length;
        int keyLen = key.length();
        for (int i = 0; i < len; i++) {
            bytes[i] = (byte) (bytes[i] ^ key.charAt(i % keyLen));
        }

        return bytes;
    }

    /**
     * 将16进制数字解码成字符串,适用于所有字符(包括中文)
     */
    public static String decode(byte[] bytes, String key) {
        int len = bytes.length;
        int keyLen = key.length();
        for (int i = 0; i < len; i++) {
            bytes[i] = (byte) (bytes[i] ^ key.charAt(i % keyLen));
        }

        return new String(bytes);
    }
}

2、定义Main Class

/**
 * Created by zhangjian on 18-3-29
 */
public class Encrypt {
   
    //Transform.java对应class文件路径
    private static final String TRANSFORM_FILE = Transform.class.getName().replace(".", "/") + ".class";

    public static void main(String[] args) throws IOException {
        if (args == null || args.length < 1) {
            return;
        }

        //读取传入的待加密的Jar包路径
        String path = args[0];
        if (!path.endsWith(".jar")) {
            return;
        }

        //读取Transform.java对应的Java字节码
        byte b[] = readClass();

        //指定输入和输出文件
        int index = path.lastIndexOf(".jar");
        File jarIn = new File(path);
        File jarOut = new File(path.substring(0, index) + "obfused.jar");

        try {
            //开始处理Jar包
            processJar(jarIn, jarOut, Charset.forName("UTF-8"), Charset.forName("UTF-8"), b);
        } catch (IllegalArgumentException e) {
            if ("MALFORMED".equals(e.getMessage())) {
                processJar(jarIn, jarOut, Charset.forName("GBK"), Charset.forName("UTF-8"), b);
            } else {
                throw e;
            }
        }
    }

    private static byte[] readClass() {
        InputStream in;
        try {
            in = Transform.class.getClassL
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值