当前位置: 美高梅集团手机版 > 美高梅集团 > 正文

因为项目源码安全需要,可以对代码进行混淆(

时间:2019-09-30 15:31来源:美高梅集团
大家应该知道有些工具比如apktool,dextojar等是可以对我们android安装包进行反编译,获得源码的。为了减少被别人破解,导致源码泄露,程序被别人盗取代码,等等。我们需要对代码进行

大家应该知道有些工具比如apktool,dextojar等是可以对我们android安装包进行反编译,获得源码的。为了减少被别人破解,导致源码泄露,程序被别人盗取代码,等等。我们需要对代码进行混淆,android的sdk中为我们提供了ProGrard这个工具,可以对代码进行混淆(一般是用无意义的名字来重命名),以及去除没有使用到的代码,对程序进行优化和压缩,这样可以增加你想的难度。最近我做的项目,是我去配置的混淆配置,因此研究了一下,这里分享一下。

因为项目源码安全需要,最近研究了下proguard混淆源码,在这里做一些分享。以下分享基于Android Studio。

当前是有些工具比如apktool,dextojar等是可以对我们android安装包进行反编译,获得源码的。为了减少被别人破解,导致源码泄露,程序被别人盗取代码,等等。我们需要对代码进行混淆,android的sdk中为我们提供了ProGrard这个工具,可以对代码进行混淆(一般是用无意义的名字来重命名),以及去除没有使用到的代码,对程序进行优化和压缩,这样可以增加你想的难度。最近我做的项目,是我去配置的混淆配置,因此研究了一下,这里分享一下。

在build.gradle中进行配置minifyEnabled true 表示编译时会混淆代码

如何启用Proguard

通常项目新建完成后,build.gradle文件中会有如下一段配置:

buildTypes {

美高梅集团手机版,debug {

minifyEnabledtrue

proguardFiles getDefaultProguardFile('proguard-android.txt'),'proguard-rules.pro'

signingConfig signingConfigs.config

}

release {

minifyEnabledtrue

proguardFiles getDefaultProguardFile('proguard-android.txt'),'proguard-rules.pro'

signingConfig signingConfigs.config

}

}

如上截图,将minifyEnabled设置为true,开启混淆代码,可以同时配置多个混淆文件。

配置中默认加入了sdk的混淆文件,proguard-android.txt

如何启用ProGuard

buildTypes { //开发调试的时候有效 debug { // 显示Log buildConfigField "boolean", "LOG_DEBUG", "true" minifyEnabled false zipAlignEnabled true shrinkResources true } //打包的时候使用 release { // 不显示Log buildConfigField "boolean", "LOG_DEBUG", "false" //混淆 minifyEnabled true //Zipalign优化 zipAlignEnabled true // 移除无用的resource文件 shrinkResources true //加载混淆配置文件 //proguard-android.txt为默认的混淆文件 proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } }

Proguard配置

百度了一些语法,方便以后查阅。


保留选项(配置不进行处理的内容)

-keep {Modifier} {class_specification} 保护指定的类文件和类的成员

-keepclassmembers {modifier} {class_specification} 保护指定类的成员,如果此类受到保护他们会保护的更好

-keepclasseswithmembers {class_specification} 保护指定的类和类的成员,但条件是所有指定的类和类成员是要存在。

-keepnames {class_specification} 保护指定的类和类的成员的名称(如果他们不会压缩步骤中删除)

-keepclassmembernames {class_specification} 保护指定的类的成员的名称(如果他们不会压缩步骤中删除)

-keepclasseswithmembernames {class_specification} 保护指定的类和类的成员的名称,如果所有指定的类成员出席(在压缩步骤之后)

-printseeds {filename} 列出类和类的成员-keep选项的清单,标准输出到给定的文件

压缩

-dontshrink 不压缩输入的类文件

-printusage {filename}

-whyareyoukeeping {class_specification}

优化

-dontoptimize 不优化输入的类文件

-assumenosideeffects {class_specification} 优化时假设指定的方法,没有任何副作用

-allowaccessmodification 优化时允许访问并修改有修饰符的类和类的成员

澳门美高梅游戏,混淆

-dontobfuscate 不混淆输入的类文件

-obfuscationdictionary {filename} 使用给定文件中的关键字作为要混淆方法的名称

-overloadaggressively 混淆时应用侵入式重载

-useuniqueclassmembernames 确定统一的混淆类的成员名称来增加混淆

-flattenpackagehierarchy {package_name} 重新包装所有重命名的包并放在给定的单一包中

-repackageclass {package_name} 重新包装所有重命名的类文件中放在给定的单一包中

-dontusemixedcaseclassnames 混淆时不会产生形形色色的类名

-keepattributes {attribute_name,…} 保护给定的可选属性,例如LineNumberTable, LocalVariableTable, SourceFile, Deprecated, Synthetic, Signature, and InnerClasses.

-renamesourcefileattribute {string} 设置源文件中给定的字符串常量

后面的文件名,类名,或者包名等可以使用占位符代替

?表示一个字符

可以匹配多个字符,但是如果是一个类,不会匹配其前面的包名

** 可以匹配多个字符,会匹配前面的包名。


在android中在android Manifest文件中的activity,service,provider, receviter,等都不能进行混淆。一些在xml中配置的view也不能进行混淆,android提供的默认配置中都有。(未知原因)

ant项目和eclipse项目启用方法

在项目的project.properties文件中添加一下代码

proguard.config=proguard.cfg //proguard.cfg为proguard的配置文件
proguard.config=/path/to/proguard.cfg //路径不在项目根目录时,填写实际路径

填写这句配置后,在release打包时就会按照我们的配置进行混淆,注意,在我们平时的debug时是不会进行混淆的。

一些常用包的Proguard配置,在proguard-rules.pro中配置,以下是基本的配置

Proguard输出文件

混淆之后,会给我们输出一些文件,在build/outputs/mapping/debug目录下。


分别有以下文件:

dump.txt 描述apk文件中所有类文件间的内部结构。

mapping.txt 列出了原始的类,方法,和字段名与混淆后代码之间的映射。

seeds.txt 列出了未被混淆的类和成员

usage.txt 列出了从apk中删除的代码


Gradle项目(以及Android Studio)

在build.gradle中进行配置

android {
    buildTypes {
        release {
            runProguard true
            proguardFiles getDefaultProguardFile('proguard-android.txt'),'some-other-rules.txt'
            //proguardFile 'some-other-rules.txt'  配置单个文件这样
        }
    }
}

如上面代码所示,我们可以使用runProguard true开启,并且对其配置混淆配置,可以配置多个文件或单个文件。

android的sdk中已经为我们提供了两个默认的配置文件,我们可以拿过来进行使用,proguard-android.txt和proguard-android-optimize.txt。

# Add project specific ProGuard rules here.# By default, the flags in this file are appended to flags specified# in E:SDKsdk/tools/proguard/proguard-android.txt# You can edit the include path and order by changing the proguardFiles# directive in build.gradle.## For more details, see# http://developer.android.com/guide/developing/tools/proguard.html# Add any project specific keep options here:# 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 *;#}-dontskipnonpubliclibraryclasses # 不忽略非公共的库类-optimizationpasses 5 # 指定代码的压缩级别-dontusemixedcaseclassnames # 是否使用大小写混合-dontpreverify # 混淆时是否做预校验-verbose # 混淆时是否记录日志-keepattributes *Annotation* # 保持注解-ignorewarning # 忽略警告-dontoptimize # 优化不优化输入的类文件-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* # 混淆时所采用的算法#保持哪些类不被混淆-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 com.android.vending.licensing.ILicensingService-keep public class * extends android.app.Fragment#如果有引用v4包可以添加下面这行-keep public class * extends android.support.v4.app.Fragment#生成日志数据,gradle build时在本项目根目录输出-dump class_files.txt #apk包内所有class的内部结构-printseeds seeds.txt #未混淆的类和成员-printusage unused.txt #打印未被使用的代码-printmapping mapping.txt #混淆前后的映射-keep public class * extends android.support.** #如果有引用v4或者v7包,需添加-libraryjars libs/xxx.jar #混淆第三方jar包,其中xxx为jar包名-keep class com.xxx.**{*;} #不混淆某个包内的所有文件-dontwarn com.xxx** #忽略某个包的警告-keepattributes Signature #不混淆泛型-keepnames class * implements java.io.Serializable #不混淆Serializable-keepclassmembers class **.R$* { #不混淆资源类 public static <fields>;}-keepclasseswithmembernames class * { # 保持 native 方法不被混淆 native <methods>;}-keepclasseswithmembers class * { # 保持自定义控件类不被混淆 public <init>(android.content.Context, android.util.AttributeSet);}-keepclasseswithmembers class * { # 保持自定义控件类不被混淆 public <init>(android.content.Context, android.util.AttributeSet, int);}-keepclassmembers class * extends android.app.Activity { # 保持自定义控件类不被混淆 public void *(android.view.View);}-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 *;}

Proguard案例文件


# This is a configuration file for ProGuard.

#

-dontusemixedcaseclassnames

-dontskipnonpubliclibraryclasses

-verbose

-dontoptimize

-dontpreverify

-keepattributesSignature

-keepattributes*Annotation*

-keepclass sun.misc.Unsafe { *; }

-keepclass com.eastelsoft.zk.bean.** { *; }

-keepclass * implements org.coreframe.ui.I_KJActivity { *; }

-dontwarncom.igexin.**

-keepclass com.igexin.**{*;}

-keepclass com.baidu.**{*;}

-keepclass vi.com.gdi.bgl.**{*;}

-keepclassmembersclass * {

public (org.json.JSONObject);

}

-keepclass com.umeng.**

-keeppublic class com.idea.fifaalarmclock.app.R$*{

public static final int *;

}

-keeppublic class com.umeng.fb.ui.ThreadView {

}

-dontwarncom.umeng.**

-dontwarnorg.apache.commons.**

-keeppublic class * extends com.umeng.**

-keepclass com.umeng.** {*; }

-keepclasseswithmembernamesclass * {

native ;

}

-keepclassmemberspublic class * extends android.view.View {

void set*(***);

*** get*();

}

-keepclassmembersclass * extends android.app.Activity {

public void *(android.view.View);

}

-keepclassmembersenum * {

public static **[] values();

public static ** valueOf(java.lang.String);

}

-keepclass * implements android.os.Parcelable {

public static final android.os.Parcelable$Creator *;

}

-keepclassmembersclass **.R$* {

public static ;

}

-dontwarnandroid.support.**

ProGuard配置

上面说到android为我们提供了两个默认的配置文件,在其中,我们可以看到他的一些语法。本节进行描述。

保留选项(配置不进行处理的内容)

-keep {Modifier} {class_specification} 保护指定的类文件和类的成员
-keepclassmembers {modifier} {class_specification} 保护指定类的成员,如果此类受到保护他们会保护的更好
-keepclasseswithmembers {class_specification} 保护指定的类和类的成员,但条件是所有指定的类和类成员是要存在。
-keepnames {class_specification} 保护指定的类和类的成员的名称(如果他们不会压缩步骤中删除)
-keepclassmembernames {class_specification} 保护指定的类的成员的名称(如果他们不会压缩步骤中删除)
-keepclasseswithmembernames {class_specification} 保护指定的类和类的成员的名称,如果所有指定的类成员出席(在压缩步骤之后)
-printseeds {filename} 列出类和类的成员-keep选项的清单,标准输出到给定的文件

压缩

-dontshrink 不压缩输入的类文件
-printusage {filename}
-whyareyoukeeping {class_specification}

优化

-dontoptimize 不优化输入的类文件
-assumenosideeffects {class_specification} 优化时假设指定的方法,没有任何副作用
-allowaccessmodification 优化时允许访问并修改有修饰符的类和类的成员

混淆

-dontobfuscate 不混淆输入的类文件
-obfuscationdictionary {filename} 使用给定文件中的关键字作为要混淆方法的名称
-overloadaggressively 混淆时应用侵入式重载
-useuniqueclassmembernames 确定统一的混淆类的成员名称来增加混淆
-flattenpackagehierarchy {package_name} 重新包装所有重命名的包并放在给定的单一包中
-repackageclass {package_name} 重新包装所有重命名的类文件中放在给定的单一包中
-dontusemixedcaseclassnames 混淆时不会产生形形色色的类名
-keepattributes {attribute_name,...} 保护给定的可选属性,例如LineNumberTable, LocalVariableTable, SourceFile, Deprecated, Synthetic, Signature, and InnerClasses.
-renamesourcefileattribute {string} 设置源文件中给定的字符串常量

后面的文件名,类名,或者包名等可以使用占位符代替
?表示一个字符

  • 可以匹配多个字符,但是如果是一个类,不会匹配其前面的包名
    ** 可以匹配多个字符,会匹配前面的包名。

在android中在android Manifest文件中的activity,service,provider, receviter,等都不能进行混淆。一些在xml中配置的view也不能进行混淆,android提供的默认配置中都有。

ProGuard配置

配置过程中遇到的坑

1.项目中使用了许多第三方库,如百度地图,友盟,Gson等包,需要根据官方上的说明进行分别配置,

e.g. 百度地图

-keepclass com.baidu.**{*;}

-keepclass vi.com.gdi.bgl.**{*;}

2. 第一次配置完后,软件跑起来各种问题,后面发现全是gson解析失败,所以对model进行了keep操作,也没找到更好的方法。

-keepclass com.eastelsoft.zk.bean.** { *; }

3.项目中如果用了反射,需要额外配置一些.

-keepattributesSignature

-keepattributes*Annotation*

-keepclass * implements org.coreframe.ui.I_KJActivity { *; }

这里对接口进行了keep操作。

当你用了proguard配置后如果出现问题,要一步一步去分析,如果发现按钮不能点击的问题, 就尝试看看activity中的代码是否出现问题,先keep一些类,逐步调试,最后解决问题。

ProGuard的输出文件及用处

混淆之后,会给我们输出一些文件,在gradle方式下是在<project_dir>/build/proguard/目录下,ant是在<project_dir>/bin/proguard目录,eclipse构建在<project_dir>/proguard目录像。
分别有以下文件:

  • dump.txt 描述apk文件中所有类文件间的内部结构。
  • mapping.txt 列出了原始的类,方法,和字段名与混淆后代码之间的映射。
  • seeds.txt 列出了未被混淆的类和成员
  • usage.txt 列出了从apk中删除的代码

当我们发布的release版本的程序出现bug时,可以通过以上文件(特别时mapping.txt)文件找到错误原始的位置,进行bug修改。同时,可能一开始的proguard配置有错误,也可以通过错误日志,根据这些文件,找到哪些文件不应该混淆,从而修改proguard的配置。

注意:重新release编译后,这些文件会被覆盖,所以没吃发布程序,最好都保存一份配置文件。

编辑:美高梅集团 本文来源:因为项目源码安全需要,可以对代码进行混淆(

关键词: