开源 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 16targetSdkVersion 28}buildTypes {release {minifyEnabled trueproguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'// 添加这些配置crunchPngs falseshrinkResources false}}// 添加编译选项compileOptions {sourceCompatibility JavaVersion.VERSION_1_8targetCompatibility 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;}}
}