美文网首页
Android SDK 开发系列二 代码混淆

Android SDK 开发系列二 代码混淆

作者: 打杂的_e2c9 | 来源:发表于2020-01-13 19:01 被阅读0次

现在大多商业应用都是经过混淆的,混淆后虽然不能防止反编译,但是可以增加反编译后的难度,减小包的大小,做sdk开发一般都是比较核心的技术,所以一般都是需要添加上混淆规则的
文中大部分转自:https://www.cnblogs.com/zhangmiao14/p/7098168.html

混淆的原理

Java是一种跨平台、解释型语言,Java源代码编译成的class文件中有大量包含语义的变量名、方法名的信息,很容易被反编译为Java源代码。为了防止这种现象,我们可以对Java字节码进行混淆。混淆不仅能将代码中的类名、字段、方法名变为无意义的名称,保护代码,也由于移除无用的类、方法,并使用简短名称对类、字段、方法进行重命名缩小了程序的大小。

ProGuard由shrink、optimize、obfuscate和preverify四个步骤组成,每个步骤都是可选的,需要哪些步骤都可以在脚本中配置。参见ProGuard官方介绍。
  压缩(Shrink):默认开启,侦测并移除代码中无用的类、字段、方法和特性,减少应用体积,并且会在优化动作执行之后再次执行(因为优化后可能会再次暴露一些未使用的类和成员)。
  -dontshrink 关闭混淆
  优化(Optimize):默认开启,分析和优化字节码,让应用运行的更快。
  -dontoptimize 关闭优化,默认混淆配置文件开始
  -optimizationpasses n 表示proguard对代码进行迭代优化的次数,Android一般为5
  混淆(Obfuscate):默认开启,使用a、b、c、d这样简短而无意义的名称,对类、字段和方法进行重命名,增大反编译难度。
  -dontobfuscate 关闭混淆
上面三个步骤使代码大小更小、更高效,也更难被逆向工程。
  预检(Preverify):在java平台上对处理后的代码进行预检。
混淆流程图:

image

Proguard读入input jars(or wars,zip or directories),经过四个步骤生成处理之后的jars(or wars,ears,zips or directories),Optimization步骤可选择多次进行。
为了确定哪些代码应该被保留,哪些代码应该被移除或混淆,需要确定一个或多个Entry Point。Entry Point经常是带有main methods,applets,midlets的classes,它们在混淆过程中会被保留。
Proguard的几个步骤如何处理Entry Points。
  (1).在压缩阶段,Proguard从上述Entry Points开始遍历搜索哪些类和类成员被使用。其他没有被使用的类和类成员会移除。
  (2).在优化阶段,Proguard进一步设置非Entry Point的类和方法为private、static和final来进行优化,不使用的参数会被移除,某些方法会被标记为内联。
  (3).在混淆阶段,Proguard重命名非Entry Points的类和类成员。
  (4).预检阶段是唯一没有触及Entry Points的阶段。

混淆的使用方法

1. 开启混淆
在build.gradle 中开启混淆

buildTypes {
        release {
           // 设置为true,开启混淆开关
            minifyEnabled true
          // 'proguard-android.txt' 是AndroidStudio默认自动导入的规则,这个文件位于Android SDK根目录\tools\proguard\proguard-android.txt。这里面是一些比较常规的不能被混淆的代码规则。'proguard-rules.pro'是针对我们自己的项目需要特别定义混淆规则,它位于项目根目录下面,里面的内容需要我们自己编写
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

2. 编写自己的编译规则
在proguard-rules.pro 中进行编写

因为我们是jar包开发,完成以上两步还要自己编写打包规则

// 依赖一个我们上边已经写好的打包task
task proguardJar(dependsOn: ['xxx'], type: proguard.gradle.ProGuardTask) {

    //Android 默认的 proguard 文件
    configuration android.getDefaultProguardFile('proguard-android.txt')

    //混淆的配置文件
    configuration 'proguard-rules.pro'

  // 一下为 
   String inJar = xxx.archivePath.getAbsolutePath()
    //输入 jar
    injars inJar
    println "inJar->>" + inJar
    //输出 jar
    String outJar = inJar.substring(0, inJar.lastIndexOf(File.separator)) + "/proguard-${xxx.archiveName}"
    outjars outJar
    println "outJar->>" + outJar

    //设置不删除未引用的资源(类,方法等)
    dontshrink
}

3.查看构建输出
构建时Proguard都会输出下列文件:(build之后)
  (1)dump.txt --- 说明APK中所有类文件的内部结构
  (2)mapping.txt --- 提供原始与混淆过的类、方法和字段名称之间的转换
  (3)seeds --- 列出未进行混淆的类和成员
  (4)usage.txt --- 列出从APK移除的代码
这些文件保存在/build/outputs/mapping/release目录下。
4.解码混淆过的堆栈追踪
使用混淆后,保存好mapping文件,程序csh时通过脚本进行解码。
retrace工具位于/tools/proguard/目录下,解码命令为(注意把stacktrace_file 中的AndroidRuntime 等字段去掉)

retrace.bat|retrace.sh [-verbose] mapping.txt [<stacktrace_file>]

混淆的规则介绍

#?      匹配一个字符
#*       匹配一个名字,除了目录外分隔符外的任意部分
#**      匹配任意名,可能包含任意路径分隔符
#!     排除
#<field>        匹配类中的所有字段
#<method>   匹配类中所有的方法
#<init>          匹配类中所有的构造函数

#代码混淆压缩比,在0~7之间
-optimizationpasses 5# 
#混淆时不适用大小写混合,混合后的类名为小写
-dontusemixedcaseclassnames

#指定不去忽略非公共库的类
-dontskipnonpubliclibraryclasses

#不做预校验,preverify是proguard的四个步骤之一,Android不需要precerify,去掉这一步能够加快混淆速度。
-dontpreverify

-verbose

#google推荐算法
-optimizations !code/simplification/arithmetic,!code/simplication/cast,!field/*,!class/mergin/*

#避免混淆Annotation、内部类、泛型、匿名类
-keepattributes *Annotation*,InnerClasses,Signature,EnclosingMethod

#重命名抛出异常时的文件名称
-renamesourcefileattribute SourceFile

#抛出异常时保留代码行号
-keepattributes SourceFile,LineNumberTable

#处理support包
-dontnote android.support.**
-dontwarn android.support.**

#保留四大组件,自定义的Application等这些类不被混淆
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * entends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService

#保留本地native方法不被混淆
-keepclasseswithmembernames class * {
native <methods>
}

#保留枚举类不被混淆
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}

#第三方jar包不被混淆
-keep class com.github.test.** {*;}

#保留自定义的Test类和类成员不被混淆
-keep class class.lily.Test {*;}

#保留自定义的xlog文件夹下面的类、类成员和方法不被混淆
-keep class com.text.xlog.** {
<fields>;
<methods>;
}

#assume no side effects;删除android.util.Log输出的日志
-assumenosideeffects class android.util.Log {
public static *** v(...);
public static *** d(...);
public static *** i(...);
public static *** w(...);
public static *** e(...);
}

#保留keep注解的类名和方法
-keep,allowobfuscation @interface android.support.annotation.Keep
-keep @android.support.annotation.Keep class *
-keepclassmember class * {
@android.support.annotation.Keep *;
}

#避免混淆内部类
-keep class com.letv.tracker2.msg.MessageProcessor$* {*;}

相关文章

  • Android SDK 开发系列二 代码混淆

    现在大多商业应用都是经过混淆的,混淆后虽然不能防止反编译,但是可以增加反编译后的难度,减小包的大小,做sdk开发一...

  • Android中的代码混淆

    混淆规则 因为Android是使用Java开发的,所以开发者可以使用ProGuard对代码进行混淆。SDK已经集成...

  • Android代码混淆实战

    什么是代码混淆:     Android SDK 自带了混淆工具Proguard。它位于SDK根目录\tools\...

  • 读懂 Android 中的代码混淆

    在Android开发工作中,我们都或多或少接触过代码混淆。比如我们想要集成某个SDK,往往需要做一些排除混淆的操作...

  • android sdk 代码混淆

    前言 各位同学大家好 有段时间没有给大家更新文章了, 最近在做海外项目 所以有时间就跟各位聊一下安卓代码混淆的 因...

  • Android Proguard混淆小记

    混淆的基本语法 常规不可混淆的代码 1.腾讯系列SDK混淆 2.GSON混淆 3.ButterkKnife混淆 4...

  • Android-SDK默认混淆配置ProGuard

    一.介绍 二.混淆配置 1.自定义混淆文件proguard-rules.pro 2.Android SDK默认混淆...

  • ProGuard详解

    Android分享:代码混淆那些事Android代码混淆之混淆规则Android-Dev-Favorites An...

  • Android如何进行混淆

    android开发为什么要进相混淆? Android开发使用Java作为开发语言,Java代码是非常容易反编译的。...

  • 御安全浅析安卓开发代码混淆技术

    御安全浅析安卓开发代码混淆技术 【关键词:代码混淆,Android应用加固,移动应用保护,APP保护,御安全】 提...

网友评论

      本文标题:Android SDK 开发系列二 代码混淆

      本文链接:https://www.haomeiwen.com/subject/pdjpactx.html