Android混淆机制

注意:本篇文章是本人阅读相关文章的总结,方便以后查阅,所有内容非原创,侵权删。

本篇文章内容来自于
1.Android高级进阶 顾浩鑫
2.相对应的知识块的最下方会给出原来的帖子的链接

前言

混淆是增加逆向工程和破解的难度,防止APP知识产权被窃取的一个有力手段。
Android混淆包括三种类型
1.Java代码的混淆
2.Native(C&C++)代码的混淆
3.资源文件的混淆

目录

  1. Java代码的混淆
    --1.1 Proguard如何启用
    --1.2 编写混淆文件
    --1.3 Proguard生成的文件
  2. Native(C&C++)代码的混淆 NDK(待补)
  3. 资源文件的混淆(待补)

1. Java代码的混淆-Proguard

Java代码混淆一般依赖于Proguard或者DexGuard工具。其中Proguard免费开源,Proguard付费。DexGuard强大的多,但是一般情况下用DexGuard就足够了。

Android默认集成了ProGuard,它是一个免费的用于压缩、优化和混淆Java字节码的工具,混淆的功能主要是用简短的无意义的字母组合来对代码中的类、字段、方法和属性进行重命名,但它无法对字符串进行混淆
即使用Proguard后,我们还是可以看到反编译后代码中完整的字符串定义。
我们可以选择商业版的Proguard-DexGuard。DexGuard对代码、资源、字符串、AndroidManifest.xml等进行了全面的加密和混淆。

Proguard的特性
Progurad不仅可代码混淆,还提供其他功能。主要有4个功能特性:
1.压缩:Proguard能通过分析字节码,能够检测并移除没有使用到的类、字段、方法和属性。
2.优化:优化java字节码,同时移除没有使用到的指令。
3.混淆:使用无意义的简短字母组合对类名、字段名和方法名进行重命名。
4.预检验:对上述处理后的代码进行预检验。

1.1 Proguard如何启用

在需要进行的module的build.gradle进行配置

android {
    ...
    buildTypes {
        release {
            minifyEnabled true //用于指定是否对项目的代码进行混淆 true表示混淆 false表示不混淆
            //proguardFiles用于指定混淆时使用的规则文件
            //这里指定了2个 proguard-android.txt是AndroidSDK目录下的tools/proguard的,里面是所有项目通用的混淆规则
            //proguard-rules.pro是当前项目根目录下的,里面可以编写当前项目特有的混淆规则
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    ...
}

1.2 编写混淆文件

1.2.1 proguard-android.txt 默认混淆配置文件

proguard-android.txt位于AndroidSDK目录/tools/proguard,该文件是Proguard的基本配置,几乎是每个APP都要用到的配置。

1.2.2 proguard-rules.pro 文件的编写

proguard-android.txt 默认混淆配置文件的配置是远远不够的,我们需要根据自身APP的特殊性增加或减少相关的配置。

混淆文件的规则大致分为三种类型

  • 公共的混淆规则:每个APP都适用,主要是针对Proguard的基本配置,以及Android SDK中API设置的规则,例如Activity、Parceable等。
  • APP特有的混淆规则:根据APP自身的特点进行设置,例如某些类会被反射调用,如果被混淆,那么反射就找不到了。
  • 第三方函数库或者SDK的混淆规则:如果APP引入了第三方开源函数库或者SDK,那么需要查看这些函数库或者SDK的使用说明,将需要去混淆的地方加上去。

混淆模版:(具体查看5分钟搞定android混淆)

#-------------------------------------------定制化区域----------------------------------------------
#---------------------------------1.实体类---------------------------------



#-------------------------------------------------------------------------

#---------------------------------2.第三方包-------------------------------



#-------------------------------------------------------------------------

#---------------------------------3.与js互相调用的类------------------------



#-------------------------------------------------------------------------

#---------------------------------4.反射相关的类和方法-----------------------



#----------------------------------------------------------------------------
#---------------------------------------------------------------------------------------------------

#-------------------------------------------基本不用动区域--------------------------------------------
#---------------------------------基本指令区----------------------------------
-optimizationpasses 5
-dontskipnonpubliclibraryclassmembers
-printmapping proguardMapping.txt
-optimizations !code/simplification/cast,!field/*,!class/merging/*
-keepattributes *Annotation*,InnerClasses
-keepattributes Signature
-keepattributes SourceFile,LineNumberTable
#----------------------------------------------------------------------------

#---------------------------------默认保留区---------------------------------
-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.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
-keep class android.support.** {*;}

-keep public class * extends android.view.View{
    *** get*();
    void set*(***);
    public (android.content.Context);
    public (android.content.Context, android.util.AttributeSet);
    public (android.content.Context, android.util.AttributeSet, int);
}
-keepclasseswithmembers class * {
    public (android.content.Context, android.util.AttributeSet);
    public (android.content.Context, android.util.AttributeSet, int);
}
-keepclassmembers class * implements java.io.Serializable {
    static final long serialVersionUID;
    private static final java.io.ObjectStreamField[] serialPersistentFields;
    private void writeObject(java.io.ObjectOutputStream);
    private void readObject(java.io.ObjectInputStream);
    java.lang.Object writeReplace();
    java.lang.Object readResolve();
}
-keep class **.R$* {
 *;
}
-keepclassmembers class * {
    void *(**On*Event);
}
#----------------------------------------------------------------------------

#---------------------------------webview------------------------------------
-keepclassmembers class fqcn.of.javascript.interface.for.Webview {
   public *;
}
-keepclassmembers class * extends android.webkit.WebViewClient {
    public void *(android.webkit.WebView, java.lang.String, android.graphics.Bitmap);
    public boolean *(android.webkit.WebView, java.lang.String);
}
-keepclassmembers class * extends android.webkit.WebViewClient {
    public void *(android.webkit.WebView, jav.lang.String);
}
#----------------------------------------------------------------------------
#---------------------------------------------------------------------------------------------------

1.3 Proguard生成的文件

在AS中使用Proguard对代码进行混淆,会在build/outputs/mapping/release目录下生成四个文件。
1.dump.txt:列出生成的APK文件中所有class文件的内部结构。
2.mapping.txt:列出混淆前的java源码和混淆后的类、方法和属性名字之间的映射。
3.seeds.txt:列出为混淆的类和成员
4.usage.txt:列出从apk文件中剥离的代码


Android混淆机制_第1张图片

2.Native(C&C++)代码的混淆 NDK(待补)

Android开发中经常需要在客户端中保存敏感信息,相比较将敏感信息写在Java层,将其下移到NDK层是更好的选择。
虽然NDK层存储敏感信息安全性好,但仍然避免不了被破解,为了进一步增加破解难度,我们需要对NDK层的代码进行混淆保护。

Native 层代码混淆没有一个标准的方案或者函数库,常见且比较简单的方法是使用花指令,使Native代码在被反汇编时出错,从而让破解者无法清晰正确的反汇编出代码的内容。

参考
1.Obfuscator-LLVM
2.直接使用由Ryan Welton预先编译的包,具体参见ANdroidObfuscation-NDK这个例子。

3.资源文件的混淆(待补)

资源文件的混淆也没有统一的方案,但是并不常对资源文件进行混淆,因为资源文件的保密性美欧那么高,破解者可以通过apktool轻松得到。

资源文件混淆的好处
1.提高APP破解的难度
2.减少APP的最终包的大小:资源文件的混淆类似于java代码的混淆,也是通过使用无意义的字母来代替完整的命名实现的。他的一个副作用是能在一定程度上减少APP的大小。

资源文件的混淆方案目前有美团和微信两种。
1⃣️美团是通过修改AAPT在处理资源文件相关的源码达到资源文件名的替换。
查看美团Android资源混淆保护实践
2⃣️微信是通过直接修改resources.arsc文件达到资源文件名的混淆。
查看安装包立减1M--微信Android资源混淆打包工具
微信方案开源,地址在AndResGuard

你可能感兴趣的:(Android混淆机制)