文档章节

Apk混淆

android-key
 android-key
发布于 2017/07/09 16:02
字数 1769
阅读 53
收藏 1
点赞 0
评论 0

本文主要讲解Apk的混淆,这里的混淆分为两种代码混淆和资源文件混淆。实际的产品研发中为了防止自己的劳动成果被别人窃取,混淆代码能有效防止apk文件被反编译,进而查看源代码。说来惭愧,作为互联网创业公司的我们也确实对竞品Apk反编译研究过,如果Apk混淆之后确实对理解源码的业务流程造成了困扰,这也从侧面说明了Apk混淆的重要性。

Android提供了Progurd方式来混淆apk中的代码,其核心的逻辑是在代码层将一些易懂的源代码类名,方法名称替换成毫无意义的a、b、c、d…,这样当别人反编译出你的Apk文件时,看到的源代码也无法还原其本身的逻辑。

1.代码混淆-Progurd

1.1)在Android studio的Android项目中找到module的gradle配置文件,添加proguard配置

buildTypes {
        debug {
            // 显示Log
            buildConfigField "boolean", "LOG_DEBUG", "true"
            //混淆
            minifyEnabled false
            //Zipalign优化
            zipAlignEnabled true
            // 移除无用的resource文件
            shrinkResources true
            //加载默认混淆配置文件
            proguardFiles getDefaultProguardFile('proguard-Android.txt'), 'proguard-rules.pro'
            //签名
            signingConfig signingConfigs.debug
        }
        release {
            // 不显示Log
            buildConfigField "boolean", "LOG_DEBUG", "false"
            //混淆
            minifyEnabled true
            //Zipalign优化
            zipAlignEnabled true
            // 移除无用的resource文件
            shrinkResources true
            //加载默认混淆配置文件
            proguardFiles getDefaultProguardFile('proguard-Android.txt'), 'proguard-rules.pro'
            //签名
            signingConfig signingConfigs.relealse
        }
    }

1.2)找到项目中的proguard-rules.pro文件,该文件就是我们的混淆配置文件

1.3)编写proguard-rules.pro文件,添加混淆配置

  1. proguard混淆语法
-libraryjars class_path 应用的依赖包,如Android-support-v4  
-keep [,modifier,...] class_specification 这里的keep就是保持的意思,意味着不混淆某些类 
-keepclassmembers [,modifier,...] class_specification 同样的保持,不混淆类的成员  
-keepclasseswithmembers [,modifier,...] class_specification 不混淆类及其成员  
-keepnames class_specification 不混淆类及其成员名  
-keepclassmembernames class_specification 不混淆类的成员名  
-keepclasseswithmembernames class_specification 不混淆类及其成员名  
-assumenosideeffects class_specification 假设调用不产生任何影响,在proguard代码优化时会将该调用remove掉。如system.out.println和Log.v等等  
-dontwarn [class_filter] 不提示warnning  
  1. 混淆原则
jni方法不可混淆
反射用到的类不混淆(否则反射可能出现问题)
AndroidMainfest中的类不混淆,四大组件和Application的子类和Framework层下所有的类默认不会进行混淆
Parcelable的子类和Creator静态成员变量不混淆,否则会产生Android.os.BadParcelableException异常
使用GSON、fastjson等框架时,所写的JSON对象类不混淆,否则无法将JSON解析成对应的对象
使用第三方开源库或者引用其他第三方的SDK包时,需要在混淆文件中加入对应的混淆规则
有用到WEBView的JS调用也需要保证写的接口方法不混淆

    3.第三方库的混淆原则

一般的第三方库都有自身的混淆方案,可直接引用其自身的混淆配置即可
若无混淆配置,一般的可配置不混淆第三方库

    4.最后帖上我们项目中实际的混淆方案

# Glide图片库的混淆处理
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {
    **[] $VALUES;
    public *;
}

-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*

# 高德地图混淆脚本
-keep class com.Android.support.**{ *; }
-keep interface Android.support.v4.app.**{ *; }
-keep public class * extends Android.support.v4.**
-keep public class * extends Android.app.Fragment

-dontwarn com.amap.api.**
-dontwarn com.a.a.**
-dontwarn com.autonavi.**
-keep class com.amap.api.** {*;}
-keep class com.autonavi.** {*;}
-keep class com.a.a.** {*;}

# Gson混淆脚本
-keep class com.google.gson.stream.** {*;}
-keep class com.youyou.uuelectric.renter.Network.user.** {*;}

# butterknife混淆脚本
-dontwarn butterknife.internal.**
-keep class **$$ViewInjector { *; }
-keepnames class * { @butterknife.InjectView *;}

# -------------系统类不需要混淆 --------------------------
-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.content.ContentProvider
-keep public class * extends Android.app.backup.BackupAgentHelper
-keep public class * extends Android.preference.Preference
-keep public class * extends Android.support.**
-keep public class com.Android.vending.licensing.ILicensingService

-keepclasseswithmembernames class * { # 保持native方法不被混淆
    native <methods>;
}
-keepclasseswithmembernames class * { # 保持自定义控件不被混淆
    public <init>(Android.content.Context, Android.util.AttributeSet);
}
-keepclasseswithmembernames class * { # 保持自定义控件不被混淆
    public <init>(Android.content.Context, Android.util.AttributeSet, int);
}
-keepclassmembers enum * { # 保持枚举enum类不被混淆
    public static **[] values();
    public static ** valueOf(java.lang.String);
}
-keep class * implements Android.os.Parcelable { # 保持Parcelable不被混淆
  public static final Android.os.Parcelable$Creator *;
}

# --------- 忽略异常提示 --------------------
-dontwarn butterknife.internal.**
-dontwarn com.alipay.**
-dontwarn com.mikepenz.**
-dontwarn org.apache.**
-dontwarn com.amap.**
-dontwarn com.Android.volley.**
-dontwarn com.rey.**
-dontwarn com.testin.**
-dontwarn jp.wasabeef.**

# ---------- 保持代码 --------------
-keep class com.youyou.uuelectric.renter.Utils.** {*;}
-keep class it.neokree.** {*;}
-keep class org.apache.** {*;}
-keep class com.iflytek.** {*;}
-keep class com.google.protobuf.** { *; }
-keep class com.youyou.uuelectric.renter.pay.** {*;}

# ---------------- eventbus避免混淆 ------------
-keepclassmembers class ** {
    public void onEvent*(**);
    void onEvent*(**);
}


# --------------- 友盟统计避免混淆 -------------------------
-dontwarn Android.support.v4.**
-dontwarn org.apache.commons.net.**
-dontwarn com.tencent.**
-keepclasseswithmembernames class * {
    native <methods>;
}
-keepclasseswithmembernames class * {
    public <init>(Android.content.Context, Android.util.AttributeSet);
}
-keepclasseswithmembernames class * {
    public <init>(Android.content.Context, Android.util.AttributeSet, int);
}
-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}
-keep class * implements Android.os.Parcelable {
  public static final Android.os.Parcelable$Creator *;
}
-keepclasseswithmembers class * {
    public <init>(Android.content.Context);
}
-dontshrink
-dontoptimize
-dontwarn com.google.Android.maps.**
-dontwarn Android.webkit.WebView
-dontwarn com.umeng.**
-dontwarn com.tencent.weibo.sdk.**
-dontwarn com.facebook.**
-keep enum com.facebook.**
-keepattributes Exceptions,InnerClasses,Signature
-keepattributes *Annotation*
-keepattributes SourceFile,LineNumberTable
-keep public interface com.facebook.**
-keep public interface com.tencent.**
-keep public interface com.umeng.socialize.**
-keep public interface com.umeng.socialize.sensor.**
-keep public interface com.umeng.scrshot.**
-keep public class com.umeng.socialize.* {*;}
-keep public class javax.**
-keep public class Android.webkit.**
-keep class com.facebook.**
-keep class com.umeng.scrshot.**
-keep public class com.tencent.** {*;}
-keep class com.umeng.socialize.sensor.**
-keep class com.tencent.mm.sdk.openapi.WXMediaMessage {*;}
-keep class com.tencent.mm.sdk.openapi.** implements com.tencent.mm.sdk.openapi.WXMediaMessage$IMediaObject {*;}
-keep class im.yixin.sdk.api.YXMessage {*;}
-keep class im.yixin.sdk.api.** implements im.yixin.sdk.api.YXMessage$YXMessageData{*;}
-keep public class [your_pkg].R$*{
    public static final int *;
}

# 热修复混淆
-keep class * extends java.lang.annotation.Annotation
-keep class com.alipay.euler.andfix.** { *; }
-keepclasseswithmembernames class * {
    native <methods>;
}
##---------------Begin: proguard configuration for Gson  ----------
# Gson uses generic type information stored in a class file when working with fields. Proguard
# removes such information by default, so configure it to keep all of it.
-keepattributes Signature

# For using GSON @Expose annotation
-keepattributes *Annotation*

# Gson specific classes
-keep class sun.misc.Unsafe { *; }
#-keep class com.google.gson.stream.** { *; }

# Application classes that will be serialized/deserialized over Gson
-keep class net.oschina.app.improve.bean.** { *; }

-keepattributes EnclosingMethod

##---------------End: proguard configuration for Gson  ----------

-keep class net.oschina.app.** { *; }
-keep class net.oschina.common.** { *; }


-keep class butterknife.** { *; }
-dontwarn butterknife.internal.**
-keep class **$$ViewBinder { *; }

-keepclasseswithmembernames class * {
    @butterknife.* <fields>;
}

-keepclasseswithmembernames class * {
    @butterknife.* <methods>;
}

-dontwarn com.thoughtworks.xstream.**
-keep class com.thoughtworks.xstream.** { *; }

-dontwarn com.makeramen.roundedimageview.**
-keep class com.makeramen.roundedimageview.RoundedTransformationBuilder

-dontwarn com.tencent.weibo.sdk.android.**
-keep class com.tencent.weibo.sdk.android.** { *; }

-dontwarn com.squareup.leakcanary.DisplayLeakService
-keep class com.squareup.leakcanary.DisplayLeakService

-dontwarn android.widget.**
-keep class android.widget.** {*;}

-dontwarn android.support.v7.widget.**
-keep class android.support.v7.widget.**{*;}

-dontshrink
-dontoptimize
-dontwarn com.google.android.maps.**
-dontwarn android.webkit.WebView
-dontwarn com.tencent.weibo.sdk.**

-keepattributes Exceptions,InnerClasses,Signature
-keepattributes *Annotation*
-keepattributes SourceFile,LineNumberTable

-keep public interface com.tencent.**
-keep public class javax.**
-keep public class android.webkit.**
-keep public class com.tencent.** {*;}

#open
-keep class net.oschina.open.**{*;}

-keep class com.sina.weibo.** {*;}
-keep class com.tencent.mm.sdk.** {*;}
-keep class com.tencent.mm.opensdk.** {*;}
-keep class com.tencent.wxop.** {*;}
-keep class com.tencent.mm.sdk.modelmsg.WXMediaMessage {*;}
-keep class com.tencent.mm.sdk.modelmsg.** implements com.tencent.mm.sdk.modelmsg.WXMediaMessage$IMediaObject {*;}

# baidu map sdk
-keep class com.baidu.** {*;}
-keep class vi.com.** {*;}
-dontwarn com.baidu.**

# Glide Start
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {
    **[] $VALUES;
    public *;
}
# Glide End

#-dontwarn android.net.SSLCertificateSocketFactory

# 友盟Start
-keepclassmembers class * {
   public <init> (org.json.JSONObject);
}
-keep public class net.oschina.app.R$*{
    public static final int *;
}
-keepclassmembers enum * {
    public static **[] values();
    public static ** valueOf(java.lang.String);
}
-dontwarn com.umeng.**
-keep public interface com.umeng.socialize.**
-keep public interface com.umeng.socialize.sensor.**
-keep public interface com.umeng.scrshot.**
-keep public class com.umeng.socialize.* {*;}
-keep class com.umeng.scrshot.**
-keep class com.umeng.socialize.sensor.**
-keep class pub.devrel.easypermissions.**
# 友盟End

-dontwarn okio.**

5.混淆配置完成之后编译混淆包

2.资源文件混淆-微信方案

该方案的具体原理课参见:安装包立减1M–微信Android资源混淆打包工具

https://github.com/shwenzhang/AndResGuard

在其文章中分析了资源文件混淆的几种方案:

  • 方案一:最简单的方法,我们按照Proguard的做法,直接在源码级别修改,将代码以及xml的R.string.name中替换到R.string.a,icon.png重命名为a.png 然后再交给Android编译。

  • 方案二:根据Android的编译流程,所有资源ID已经被编译成32位int值。这说明我们并不需要去修改xml与Java,因为在编译过程已经被R.java所替换,我们直接修改resources.arsc的二进制数据,不改变打包流程,只要在生成resources.arsc之后修改它,同时重命名资源文件。

  • 方案三:直接处理安装包. 不依赖源码,不依赖编译过程,仅仅输入一个安装包,得到一个混淆包。

© 著作权归作者所有

共有 人打赏支持
android-key
粉丝 6
博文 88
码字总数 154324
作品 0
孝感
[Android]混淆代码后生成带签名的apk

Android从2.3的SDK开始,将ProGuard混淆代码的功能加入了进来。 我们可以从android sdk的tools目录下看到有一个proguard目录。说明具有了代码混淆的功能。 至于如何进行代码的混淆。我们需要...

亭子happy ⋅ 2012/10/11 ⋅ 4

Android Studio遇到的坑

jvm内存问题,解决办法(gradle.properties): org.gradle.jvmargs=-Xmx512m MaxHeapSize=1024m android.enableAapt2=false 混淆问题: native方法不能混淆、有用反射的类不能混淆、第三方库...

晓乐凡 ⋅ 03/26 ⋅ 0

Android 代码混淆及反编译方法

一、AndroidSDK自带proguard混淆 在Android SDK中自带有proguard代码混淆器,但在默认的情况下该混淆器是没有打开的。该混淆器在SDK中的路径是android-sdk-windowstoolsproguard 启动android...

鉴客 ⋅ 2011/11/13 ⋅ 3

APK瘦身看这一篇文章就够了

原创 2016-08-12 张明云 来源:Open软件开发小组 前言 之前我在微信群里面有说到,随着Android开发越来越成熟,关于Android方面的技术文章越来越多,作为开发者不缺资源,缺乏的是系统的知识...

3kqing ⋅ 2016/09/06 ⋅ 0

Android的反编译和代码混淆

系列文章: Android的反编译和代码混淆 Android的打包签名 Android的多渠道打包 前言 包括以下内容 要反编译apk需要下面3个工具 反编译资源文件 反编译类文件 代码混淆 要反编译apk需要下面3...

跳动的松鼠 ⋅ 2017/11/21 ⋅ 0

[Android技术专题]APK瘦身看这一篇文章就够了

前言 之前我在微信群里面有说到,随着Android开发越来越成熟,关于Android方面的技术文章越来越多,作为开发者不缺资源,缺乏的是系统的知识和指导,对于学生和上班族来讲,更缺乏筛选信息的...

张明云 ⋅ 2016/08/11 ⋅ 0

android 热修复 HotFix 混淆apk生成patch包方案

android 热修复框架目前了解的有qq空间分包方案的HotFix 和Nuwa,还有阿里开源的AndFix和Dexposed. https://github.com/dodola/HotFix https://github.com/jasonross/Nuwa https://github.com......

chuxuezhe_ ⋅ 2016/03/02 ⋅ 0

Android项目构建相关面试问题

一、Android构建流程 android apk构建详细流程图 打包步骤 1. 通过aapt打包res资源文件,生成R.java、resources.arsc和res文件(二进制 & 非二进制如res/raw和pic保持原样) 。 2. 处理.aidl...

千涯秋瑟 ⋅ 2017/12/07 ⋅ 0

IpuWadeMobile客户端简单混淆解决方案 及 非普通jar混淆(android工程的jar)

一、场景描述: 在你已经知道如何使用Export打包一个签名的Apk的前提下,当你使用最新版的开发工具开发完客户端工程,你或许会考虑将客户端工程进行混淆,以保证客户端的安全性。 二、具体需...

天堂之镜 ⋅ 2015/02/16 ⋅ 0

Android安全防护之旅---带你把Apk混淆成中文语言代码

一、前言 最近想爆破一个app,没有加壳,简单的使用Jadx打开查看源码,结果把我逗乐了,代码中既然都是中文,而且是一些比较奇葩的中文字句,如图所示: 瞬间感觉懵逼了,这app真会玩,我们知...

guozhendan ⋅ 2017/04/05 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

骰子游戏代码开源地址

因为阿里云现在服务器已经停用了,所以上面的配置已经失效。 服务端开源地址:https://gitee.com/goalya/chat4.git 客户端开源地址:https://gitee.com/goalya/client4.git 具体运行界面请参考...

算法之名 ⋅ 34分钟前 ⋅ 0

设计模式--装饰者模式

装饰者模式 定义 动态地给一个对象添加一些额外的职责。就增加功能来说,装饰模式相比生成子类更为灵活。 通用类图 意图 动态地给一个对象添加一些额外的职责。就增加功能来说,装饰模式相比...

gaob2001 ⋅ 今天 ⋅ 0

JavaScript零基础入门——(八)JavaScript的数组

JavaScript零基础入门——(八)JavaScript的数组 欢迎大家回到我们的JavaScript零基础入门,上一节课我们讲了有关JavaScript正则表达式的相关知识点,便于大家更好的对字符串进行处理。这一...

JandenMa ⋅ 今天 ⋅ 0

sbt网络问题解决方案

转自:http://dblab.xmu.edu.cn/blog/maven-network-problem/ cd ~/.sbt/launchers/0.13.9unzip -q ./sbt-launch.jar 修改 vi sbt/sbt.boot.properties 增加一个oschina库地址: [reposit......

狐狸老侠 ⋅ 今天 ⋅ 0

大数据,必须掌握的10项顶级安全技术

我们看到越来越多的数据泄漏事故、勒索软件和其他类型的网络攻击,这使得安全成为一个热门话题。 去年,企业IT面临的威胁仍然处于非常高的水平,每天都会看到媒体报道大量数据泄漏事故和攻击...

p柯西 ⋅ 今天 ⋅ 0

Linux下安装配置Hadoop2.7.6

前提 安装jdk 下载 wget http://mirrors.hust.edu.cn/apache/hadoop/common/hadoop-2.7.6/hadoop-2.7.6.tar.gz 解压 配置 vim /etc/profile # 配置java环境变量 export JAVA_HOME=/opt/jdk1......

晨猫 ⋅ 今天 ⋅ 0

crontab工具介绍

crontab crontab 是一个用于设置周期性被执行的任务工具。 周期性执行的任务列表称为Cron Table crontab(选项)(参数) -e:编辑该用户的计时器设置; -l:列出该用户的计时器设置; -r:删除该...

Linux学习笔记 ⋅ 今天 ⋅ 0

深入Java多线程——Java内存模型深入(2)

5. final域的内存语义 5.1 final域的重排序规则 1.对于final域,编译器和处理器要遵守两个重排序规则: (1)在构造函数内对一个final域的写入,与随后把这个被构造对象的引用赋值给一个引用...

江左煤郎 ⋅ 今天 ⋅ 0

面试-正向代理和反向代理

面试-正向代理和反向代理 Nginx 是一个高性能的反向代理服务器,但同时也支持正向代理方式的配置。

秋日芒草 ⋅ 今天 ⋅ 0

Spring 依赖注入(DI)

1、Setter方法注入: 通过设置方法注入依赖。这种方法既简单又常用。 类中定义set()方法: public class HelloWorldOutput{ HelloWorld helloWorld; public void setHelloWorld...

霍淇滨 ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部