开源 java android app 开发(十七)封库--混淆源码

文章的目的为了记录使用java 进行android app 开发学习的经历。本职为嵌入式软件开发,公司安排开发app,临时学习,完成app的开发。开发流程和要点有些记忆模糊,赶紧记录,防止忘记。

相关链接:

开源 java android app 开发(一)开发环境的搭建-CSDN博客

开源 java android app 开发(二)工程文件结构-CSDN博客

开源 java android app 开发(三)GUI界面布局和常用组件-CSDN博客

开源 java android app 开发(四)GUI界面重要组件-CSDN博客

开源 java android app 开发(五)文件和数据库存储-CSDN博客

开源 java android app 开发(六)多媒体使用-CSDN博客

开源 java android app 开发(七)通讯之Tcp和Http-CSDN博客

开源 java android app 开发(八)通讯之Mqtt和Ble-CSDN博客

开源 java android app 开发(九)后台之线程和服务-CSDN博客

开源 java android app 开发(十)广播机制-CSDN博客

开源 java android app 开发(十一)调试、发布-CSDN博客

开源 java android app 开发(十二)封库.aar-CSDN博客

开源 java android app 开发(十三)自定义绘图控件--游戏摇杆

开源 java android app 开发(十四)自定义绘图控件--波形图

开源 java android app 开发(十五)自定义绘图控件--仪表盘

开源 java android app 开发(十六)自定义绘图控件--圆环

推荐链接:

开源C# .net mvc 开发(一)WEB搭建_c#部署web程序-CSDN博客

开源 C# .net mvc 开发(二)网站快速搭建_c#网站开发-CSDN博客

开源 C# .net mvc 开发(三)WEB内外网访问(VS发布、IIS配置网站、花生壳外网穿刺访问)_c# mvc 域名下不可訪問內網,內網下可以訪問域名-CSDN博客

开源 C# .net mvc 开发(四)工程结构、页面提交以及显示_c#工程结构-CSDN博客

开源 C# .net mvc 开发(五)常用代码快速开发_c# mvc开发-CSDN博客

本章节主要内容是:前面有讲过怎么封库为aar,但是在应用中发现,aar封装以后在点击调用的函数定义,实际可以看到封库的源码,对于代码的保护太不友好。这里主要介绍,如何讲代码封为aar以后,怎么进行混淆,防止代码被反向破解。

1.aar封装库的解析效果

2.aar封装库混淆的办法

3.aar混淆的效果演示

一、aar封装库的解析效果

如果参照十二章封库很容易得到以下的效果,在Mainactiviy.java可以使用mylib-debug.aar这个库的

DataProcessor类。

但是当使用鼠标点击类以后,android studio 会将整个类显示出来,想要的类加密混淆的效果并没有出现

二、aar封装库混淆的办法

造成封装库mylib-debug.aar没有混淆成功的原因是,在应用项目中引用的不是Release AAR。

要生成Release AAR需要有几个地方的修改。

1.检查 Library 模块的 build.gradle

确认您的 mylibrary/build.gradle 文件配置:

检查 Library 模块的 build.gradle

确认您的 mylibrary/build.gradle 文件配置:

复制代码
apply plugin: 'com.android.library'

android {
    compileSdkVersion 28 // 或者 29,确保与您的环境匹配
    
    defaultConfig {
        minSdkVersion 16
        targetSdkVersion 28
    }
    
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            
            // 添加这些配置
            crunchPngs false
            shrinkResources false
        }
    }
    
    // 添加编译选项
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

2.简化混淆规则

暂时使用一个非常简单的 proguard-rules.pro 来测试:

复制代码
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
#   http://developer.android.com/guide/developing/tools/proguard.html

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
#   public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

# 基本保留规则
-keepattributes Exceptions, InnerClasses, Signature, Deprecated, SourceFile, LineNumberTable

# 保留所有公共类和方法(测试阶段)
-keep public class * {
    public protected *;
}

# 忽略所有警告
-ignorewarnings
-dontwarn **

3.点击右边栏上的Gradle->mylib->other->assembleRelease,assembleRelease需要双击或右键执行

最后生成mylib-release.aar,将生成的mylib-release.aar替换mylib-debug.aar

三、aar混淆的效果演示

再次使用鼠标点击DataProcessor类以后,DataProcessor中除了public函数,其余的private都进行了处理,混淆了源码,实现了加密的目的

DataProcessor中所有的私有变量和函数已经被替换掉

复制代码
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package com.example.mylib;

public class DataProcessor {
    public static final byte[] a = new byte[]{1, 22, 116, 37, 54, -107, 51, -95, 119, -126, 34, 51, 68, 85, 0, 0, 0, 7, 0, -97, 0, 0};
    public static final byte[] b = new byte[22];
    public static final byte[] c = new byte[]{-112, -27, 75, 29, 125, 58, -23, -52, 97, -98, 92, -19};
    public static final byte[] d = new byte[]{120, -7, -28, 71, -22, -84, -47, -97, 84, 52, -39, -69, -103, 9, 37, -52, 60, -3, 114, -92, -11, 86};
    public static final byte[] e = new byte[]{79, -50, 97, -20, 99, 35, -111, 45, -16, -15, -56, -114, -45, 88, -94, 62, -88, 103, -79, 118, 50, 18};
    public static final byte[] f = new byte[]{90, -33, -30, -112, 28, -90, -80, 67, 124, 79, -50, 97, -20, 99, 35, -111, 45, -16, -15, -56, -114, -45};

    public DataProcessor() {
    }

    public byte[] generateProcessedData(byte[] var1, byte var2, byte[] var3) {
        if (var1 != null && var1.length == 4) {
            if (var3 != null && var3.length == 5) {
                byte[] var10000 = a;
                byte[] var6 = b;
                int var4 = var10000.length;
                System.arraycopy(var10000, 0, var6, 0, var4);

                int var7;
                for(var7 = 0; var7 < 4; ++var7) {
                    b[var7 + 2] = var1[var7];
                }

                var10000 = b;
                var10000[8] = var2;
                var10000[9] = 35;
                var10000 = var6 = new byte[4];
                var10000[0] = 18;
                var10000[1] = 52;
                var10000[2] = 86;
                var10000[3] = 120;

                int var8;
                for(var8 = 0; var8 < 4; ++var8) {
                    b[var8 + 10] = var6[var8];
                }

                for(var7 = 0; var7 < 5; ++var7) {
                    byte var9 = var3[var7];
                    if (var7 >= 0 && var7 <= 4) {
                        b[var7 + 14] = var9;
                    }
                }

                b[19] = 0;

                for(var7 = 0; var7 < 11; ++var7) {
                    var10000 = var1 = b;
                    var10000[19] += var1[var7 + 8];
                }

                byte[] var10;
                for(var7 = 0; var7 < (var1 = c).length; ++var7) {
                    (var10 = b)[var7 + 8] = (byte)(var10[var7 + 8] ^ var1[var7]);
                }

                var10000 = var6 = new byte[17];
                System.arraycopy(b, 1, var6, 0, 5);
                System.arraycopy(b, 8, var6, 5, 12);
                var8 = 0;
                int var11 = var10000.length;

                int var12;
                for(var12 = 65535; var8 < var11; ++var8) {
                    var12 ^= var6[var8] & 255;

                    for(var4 = 0; var4 < 8; ++var4) {
                        if ((var12 & 1) != 0) {
                            var12 = var12 >> 1 ^ 'ꀁ';
                        } else {
                            var12 >>= 1;
                        }
                    }
                }

                var7 = var12 & '\uffff';
                var10000 = var1 = b;
                var1[20] = (byte)(var7 >> 8);
                var10000[21] = (byte)(var7 & 255);

                for(var7 = 0; var7 < var1.length; ++var7) {
                    var10 = b;
                    byte var13 = var1[var7];
                    byte var14 = 0;

                    for(int var5 = 0; var5 < 8; ++var5) {
                        var14 = (byte)(var14 << 1 | var13 & 1);
                        var13 = (byte)(var13 >> 1);
                    }

                    var10[var7] = var14;
                }

                switch(37) {
                case 37:
                    var6 = d;
                    break;
                case 38:
                    var6 = e;
                    break;
                case 39:
                    var6 = f;
                    break;
                default:
                    return (byte[])b.clone();
                }

                for(var8 = 0; var8 < var6.length; ++var8) {
                    var10000 = b;
                    var10000[var8] ^= var6[var8];
                }

                return (byte[])b.clone();
            } else {
                throw new IllegalArgumentException("数据字段必须为5字节");
            }
        } else {
            throw new IllegalArgumentException("地址数据必须为4字节");
        }
    }

    public boolean validateReceivedData(byte[] var1) {
        if (var1 != null && var1.length == 14) {
            if (var1[2] == -96 && var1[3] == 35) {
                byte var3 = 0;

                for(int var2 = 2; var2 < 13; ++var2) {
                    var3 += var1[var2];
                }

                return var3 == var1[13];
            } else {
                return false;
            }
        } else {
            return false;
        }
    }
}
相关推荐
海梨花2 小时前
关于Java的几个小问题
java·面试
vx_dmxq2112 小时前
免费领源码-Spring boot的物流管理系统 |可做计算机毕设Java、Python、PHP、小程序APP、C#、爬虫大数据、单片机、文案
java·大数据·python·jupyter·课程设计
2501_916008893 小时前
JavaScript调试工具有哪些?常见问题与常用调试工具推荐
android·开发语言·javascript·小程序·uni-app·ecmascript·iphone
zero13_小葵司3 小时前
在不同开发语言与场景下设计模式的使用
java·开发语言·javascript·设计模式·策略模式
梁萌3 小时前
java实现移动云mas短信发送
java·短信·移动·mas
PH = 73 小时前
Spring AI整合聊天模型DeepSeek
java·spring boot·后端
珹洺3 小时前
Java-Spring入门指南(十三)SpringMVC基本概念与核心流程详解
java·开发语言·spring
ccccczy_3 小时前
SpringCloudGateway:像城市交通指挥系统一样的微服务网关
java·springcloud·微服务网关·api网关·springcloudgateway
2501_929382654 小时前
AdGuard解锁订阅版高级版 安卓广告拦截器APP v4.11.63 / 4.13.7 Nightly MOD
android