Android制作AAR包并混淆后加载调用
学更好的别人,
做更好的自己。
——《微卡智享》
本文长度为4389字,预计阅读12分钟
前言
最近准备做新版本产品研发,部分相关算法原来用的Webapi调用返回,考虑到速度问题,需要在Andriod端实现, 就想到了制作AAR包加代码混淆的方法,以前主要没有用过,所以这次就做个Demo来技术验证。
实现效果
上图中可以看到,制作了一个TAAR的包,打开后里面可以看到MathFun的类和类下公开的Add方法。
在新的工程中直接引入AAR包,调用里面的实现方法后,在虚拟机中直接显示了出来。
代码实现
微卡智享
制作AAR包
1.创建新的项目
新建一个Android Project,选择No Activity
2.创建外部调用类
在包下创建一个MathFun的类,里面写了一个Add的静态方法可以让外部调用,实现时又调用了MathMinify.Plus的方法,下一部就说明为啥这样处理。
3.创建实现类
创建了一个Minify的Package名,然后在下面创建了MathMinify的类,里面的Plus很简单,就是两个数字相加。
重点:多这一步的原因是为了后面的代码混淆,主要这里测试好多次,如果都放在相同的包名下,保持MathFun的类不混淆,在外部看到的AAR包时里面是没有方法的,如果都不混淆那MathMinify也会在AAR包中看到,所以最终采用的新建了一个包将MathMinify的类放到新的包下后解决。
4.修改Gradle配置
修改build.gradle配置,将plugins中的application改为library,然后将defaultConfig下面的applicationId屏蔽。做完这一步,AAR包就可以生成了,非常简单。
5.代码混淆
同样的刚才的build.gradle文件中,将minifyEnabled改为true即可混淆,下面的zipAlignEnabled可加可不加。
接下来就是修改混淆规则了,在proguard-rules.pro中加入了下面这句,将taar包下面所有的类全部都不混淆
-keep class com.example.taar.**{*;}
从图中可以看到,我们改的是release版本的代码混淆,所以Build Variants中改也将Debug改为Release.
6.编译AAR包
点击Build--Make Module 'TAAR.app'生成AAR包
app-build-outputs-aar下即可看到生成的release.arr的包,这样AAR包就制作完成了。
调用AAR包
1.创建新的Project拷贝AAR包
新建了一个名叫Demo的工程
将刚才创建好的AAR包拷冂到Demo工程下的libs目录中,并改为名TAAR.aar
2.配置build.gradle
打开build.gradle,然后加入repositories配置和compile,在Compile中name就是AAR包的名字,ext设置为aar,设置好后重新Rebuild Project一下。
repositories {flatDir {dirs 'libs'}
}dependencies {compile(name: 'TAAR', ext: 'aar')}
3.调用函数
在MainActivity中引入包名,即可直接调用包中的方法了。
import com.example.taar.MathFun
通过Project里查看TAAR.aar包,classes.jar中也可以直接看到包中的方法。
实现效果
代码混淆基本规则
01
混淆配置
通过配置proguard-rules.pro文件,对生成的apk和jar进行加密,在build.gradle 来开启混淆功能。
buildTypes {release { minifyEnabled true // 混淆 zipAlignEnabled true // Zipalign优化 shrinkResources true // 移除无用的resource文件 proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' // 加载默认混淆配置文件signingConfig signingConfigs.relealse // 签名}}
02
混淆规则
混淆会用无意义的短变量去重命名类、变量、方法,但是对于外部的一些引用是通过名字找到对应的方法和类。混淆过后通过原来的名字去找混淆后的名字,是找不到对应方法和类,就会出异常报错。所以有些情况是不能进行混淆的。
自定义控件不进行混淆
枚举类不被混淆
反射类不进行混淆
实体类不被混淆
JS调用的Java方法
四大组件不进行混淆
JNI中调用类不进行混淆
Layout布局使用的View构造函数、android:onClick等
Parcelable的子类和Creator静态成员变量不混淆
第三方开源库或者引用其他第三方的SDK包不进行混淆
先看如下两个比较常用的命令,很多童鞋可能会比较迷惑以下两者的区别。
-keep class cn.hadcn.test.**
-keep class cn.hadcn.test.*
一颗星表示只是保持该包下的类名,而子包下的类名还是会被混淆;两颗星表示把本包和所含子包下的类名都保持;用以上方法保持类后,你会发现类名虽然未混淆,但里面的具体方法和变量命名还是变了,这时如果既想保持类名,又想保持里面的内容不被混淆,我们就需要以下方法了
-keep class cn.hadcn.test.* {*;}
在此基础上,我们也可以使用Java的基本规则来保护特定类不被混淆,比如我们可以用extend,implement等这些Java规则。如下例子就避免所有继承Activity的类被混淆
-keep public class * extends android.app.Activity
如果我们要保留一个类中的内部类不被混淆则需要用$符号,如下例子表示保持ScriptFragment内部类JavaScriptInterface中的所有public内容不被混淆。
-keepclassmembers class cc.ninty.chat.ui.fragment.ScriptFragment$JavaScriptInterface {public *;
}
再者,如果一个类中你不希望保持全部内容不被混淆,而只是希望保护类下的特定内容,就可以使用
<init>; //匹配所有构造器
<fields>; //匹配所有域
<methods>; //匹配所有方法方法
你还可以在<fields>或<methods>前面加上private 、public、native等来进一步指定不被混淆的内容,如
-keep class cn.hadcn.test.One {public <methods>;
}
表示One类下的所有public方法都不会被混淆,当然你还可以加入参数,比如以下表示用JSONObject作为入参的构造函数不会被混淆
-keep class cn.hadcn.test.One {public <init>(org.json.JSONObject);
}
有时候你是不是还想着,我不需要保持类名,我只需要把该类下的特定方法保持不被混淆就好,那你就不能用keep方法了,keep方法会保持类名,而需要用keepclassmembers ,如此类名就不会被保持,为了便于对这些规则进行理解,官网给出了以下表格
保留 | 防止被移除或者被重命名 | 防止被重命名 |
---|---|---|
类和类成员 | -keep | -keepnames |
仅类成员 | -keepclassmembers | -keepclassmembernames |
如果拥有某成员,保留类和类成员 | -keepclasseswithmembers | -keepclasseswithmembernames |
移除是指在压缩(Shrinking)时是否会被删除。以上内容时混淆规则中需要重点掌握的,了解后,基本所有的混淆规则文件你应该都能看懂了。再配合以下几点注意事项,开启你为自己代码,实现混淆规则之旅吧。
03
混淆模版
基本指令
# 设置混淆的压缩比率 0 ~ 7
-optimizationpasses 5
# 混淆时不使用大小写混合,混淆后的类名为小写
-dontusemixedcaseclassnames
# 指定不去忽略非公共库的类
-dontskipnonpubliclibraryclasses
# 指定不去忽略非公共库的成员
-dontskipnonpubliclibraryclassmembers
# 混淆时不做预校验
-dontpreverify
# 混淆时不记录日志
-verbose
# 忽略警告
-ignorewarning
# 代码优化
-dontshrink
# 不优化输入的类文件
-dontoptimize
# 保留注解不混淆
-keepattributes *Annotation*,InnerClasses
# 避免混淆泛型
-keepattributes Signature
# 保留代码行号,方便异常信息的追踪
-keepattributes SourceFile,LineNumberTable
# 混淆采用的算法
-optimizations !code/simplification/cast,!field/*,!class/merging/* # dump.txt文件列出apk包内所有class的内部结构
-dump class_files.txt
# seeds.txt文件列出未混淆的类和成员
-printseeds seeds.txt
# usage.txt文件列出从apk中删除的代码
-printusage unused.txt
# mapping.txt文件列出混淆前后的映射
-printmapping mapping.txt
不需混淆的Android类
-keep public class * extends android.app.Fragment
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.preference.Preference
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class * extends android.view.View
-keep public class com.android.vending.licensing.ILicensingService
support下的所有类及其内部类
support:
-keep class android.support.** {*;}
-dontwarn android.support.**
-keep interface android.support.** { *; }androidx:
-keep class androidx.** {*;}
-keep interface androidx.** {*;}
-keep public class * extends androidx.**
-dontwarn androidx.**
support v4/7库
-keep public class * extends android.support.v4.**
-keep public class * extends android.support.v7.**
-keep public class * extends android.support.annotation.**
support design库
support:
-dontwarn android.support.design.**
-keep class android.support.design.** { *; }
-keep interface android.support.design.** { *; }
-keep public class android.support.design.R$* { *; }androidx:
-keep class com.google.android.material.** {*;}
-dontwarn com.google.android.material.**
-dontnote com.google.android.material.**
代码混淆引用的文章出处:
Android混淆从入门到精通 - 简书 (jianshu.com)
Android常用混淆配置 - 简书 (jianshu.com)
完
扫描二维码
获取更多精彩
微卡智享
「 往期文章 」
Android使用Flow检测版本升级自动下载安装
.Net5中WebApi使用MEF2框架的使用
PaddleOCR C++(三)---动态库返回识别结果及矩形位置
Android制作AAR包并混淆后加载调用相关推荐
- 【Android 插件化】基于插件化的恶意软件的加载策略分析 ( 自定义路径加载插件 | 系统路径加载插件 | 用户同意后加载插件 | 隐藏恶意插件 )
文章目录 一.自定义路径加载插件 二.系统路径加载插件 三.用户同意后加载插件 四.隐藏恶意插件 一.自定义路径加载插件 插件化应用中 , 宿主应用 加载 插件 APK , 需要获取该插件 APK 文 ...
- google android广告异步加载,javascript 广告后加载,加载完页面再加载广告
先加载完页面再加载广告的原理: 网页打开的顺序都是按页面从上到下的顺序加载完成的,所以要想使广告不影响页面打开速度,就要等页面全部打开完成后,再加载JS代码.等页面加载完再加载广告其实就是将广告的 J ...
- 【Android 逆向】整体加固脱壳 ( DexClassLoader 加载 dex 流程分析 | DexFile loadDexFile 函数 | 构造函数 | openDexFile 函数 )
文章目录 前言 一.DexFile.loadDexFile 函数分析 二.DexFile 构造函数分析 三.DexFile.openDexFile 函数分析 前言 上一篇博客 [Android 逆向] ...
- 【Android 逆向】整体加固脱壳 ( DexClassLoader 加载 dex 流程分析 | DexPathList 中根据 File 加载 DexFile | loadDexFile 分析 )
文章目录 前言 一.根据 File 加载 DexFile 二.DexPathList.loadDexFile 函数分析 前言 上一篇博客 [Android 逆向]整体加固脱壳 ( DexClassLo ...
- 【Android 逆向】整体加固脱壳 ( DexClassLoader 加载 dex 流程分析 | DexPathList 构造函数分析 | makeDexElements 函数分析 )
文章目录 前言 一.DexPathList 构造函数分析 二.DexPathList.makeDexElements 函数分析 三.Element 类分析 前言 上一篇博客 [Android 逆向]整 ...
- 【Android NDK 开发】Android.mk 配置动态库 ( Android Studio 配置动态库 | 动态库加载版本限制 | 本章仅做参考推荐使用 CMake 配置动态库 )
文章目录 I . Android Studio 中使用 Android.mk 配置动态库 总结 II . 第三方动态库来源 III . 配置 Android.mk 构建脚本路径 IV . 预编译 第三 ...
- sceneManager.loadscene加载场景时不会主动去加载场景的依赖包,要手动加载或添加场景到build setting列表中...
sceneManager.loadscene加载场景时不会主动去加载场景的依赖包,要手动加载或添加场景到build setting列表中 假设有一场景1001.unity,,manifest文件如下: ...
- android 解决listview.notifyDataSetChanged刷新时Imageloader加载图片闪烁问题
今天,简单讲讲android里再listview调用notifyDataSetChanged刷新界面时,Imageloader加载图片会闪烁的问题. 最近,发现app里的listview图片会出现闪烁 ...
- Android插件化开发之用DexClassLoader加载未安装的APK资源文件来实现app切换背景皮肤
第一步.先制做一个有我们需要的图片资源的APK 如下图,这里有个about_log.png,我们需要生成apk文件. 生成的apk文件如果你不到项目的文件夹里面去取apk,想通过命令放到手机里面去可以 ...
最新文章
- 业余时间用哪里,哪里就有发展的可能
- python重复执行_python flask schedule重复运行 任务被重复执行问题 解决方案
- flume java_Flume的安装及简单的使用(一)
- 三维离散点包络 matlab,求大神指点绘制空间内散点图的包络面,,,散点程序如下...
- cos66度20分怎么用计算机算,物化2期末考试计算复习题
- 部署DNS split分离解析服务
- FPGA时序约束设计经验总结
- java base64字符 转图片_JAVA实现图片与base64字符串之间的转换详解
- 大数据分析平台安全的重要性
- cv::Mat转换RGB
- VC++的Unicode编程(经典之作,交流传薪)
- 对色情app渗透,我居然发现了 ....
- Linux串口终端驱动——S3C6410平台
- 高效办公之Windows高效技巧提高你的工作效率
- 老男孩python怎么样_老男孩Python为什么这么受关注?老男孩到底怎么样?
- NPOI SetRowBreak 插入分页符无用
- 计算机控制系统机器人,机器人的控制系统
- php 远程下载木马
- scrapy之spiders
- 如何降低计算机版本,电脑系统WIN10如何降级,还原老系统_win10专业版教程