精华内容
下载资源
问答
  • 代码混淆

    2016-05-25 14:48:48
    代码混淆

    什么是代码混淆

    Java 是一种跨平台的、解释型语言,Java 源代码编译成中间”字节码”存储于 class 文件中。由于跨平台的需要,Java 字节码中包括了很多源代码信息,如变量名、方法名,并且通过这些名称来访问变量和方法,这些符号带有许多语义信息,很容易被反编译成 Java 源代码。为了防止这种现象,我们可以使用 Java 混淆器对 Java 字节码进行混淆。

    混淆就是对发布出去的程序进行重新组织和处理,使得处理后的代码与处理前代码完成相同的功能,而混淆后的代码很难被反编译,即使反编译成功也很难得出程序的真正语义。被混淆过的程序代码,仍然遵照原来的档案格式和指令集,执行结果也与混淆前一样,只是混淆器将代码中的所有变量、函数、类的名称变为简短的英文字母代号,在缺乏相应的函数名和程序注释的况下,即使被反编译,也将难以阅读。同时混淆是不可逆的,在混淆的过程中一些不影响正常运行的信息将永久丢失,这些信息的丢失使程序变得更加难以理解。

    混淆器的作用不仅仅是保护代码,它也有精简编译后程序大小的作用。由于以上介绍的缩短变量和函数名以及丢失部分信息的原因, 编译后 jar 文件体积大约能减少25% ,这对当前费用较贵的无线网络传输是有一定意义的。

    混淆文件 proguard.cfg 参数详解

    [plain] view plain copy
     在CODE上查看代码片派生到我的代码片
    1. -optimizationpasses 5                                                           # 指定代码的压缩级别  
    2. -dontusemixedcaseclassnames                                                     # 是否使用大小写混合  
    3. -dontskipnonpubliclibraryclasses                                                # 是否混淆第三方jar  
    4. -dontpreverify                                                                  # 混淆时是否做预校验  
    5. -verbose                                                                        # 混淆时是否记录日志  
    6. -optimizations !code/simplification/arithmetic,!field/*,!class/merging/*        # 混淆时所采用的算法  
    7.   
    8. -keep public class * extends android.app.Activity                               # 保持哪些类不被混淆  
    9. -keep public class * extends android.app.Application                            # 保持哪些类不被混淆  
    10. -keep public class * extends android.app.Service                                # 保持哪些类不被混淆  
    11. -keep public class * extends android.content.BroadcastReceiver                  # 保持哪些类不被混淆  
    12. -keep public class * extends android.content.ContentProvider                    # 保持哪些类不被混淆  
    13. -keep public class * extends android.app.backup.BackupAgentHelper               # 保持哪些类不被混淆  
    14. -keep public class * extends android.preference.Preference                      # 保持哪些类不被混淆  
    15. -keep public class com.android.vending.licensing.ILicensingService              # 保持哪些类不被混淆  
    16.   
    17. -keepclasseswithmembernames class * {                                           # 保持 native 方法不被混淆  
    18.     native <methods>;  
    19. }  
    20.   
    21. -keepclasseswithmembers class * {                                               # 保持自定义控件类不被混淆  
    22.     public <init>(android.content.Context, android.util.AttributeSet);  
    23. }  
    24.   
    25. -keepclasseswithmembers class * {  
    26.     public <init>(android.content.Context, android.util.AttributeSet, int);     # 保持自定义控件类不被混淆  
    27. }  
    28.   
    29. -keepclassmembers class * extends android.app.Activity {                        # 保持自定义控件类不被混淆  
    30.    public void *(android.view.View);  
    31. }  
    32.   
    33. -keepclassmembers enum * {                                                      # 保持枚举 enum 类不被混淆  
    34.     public static **[] values();  
    35.     public static ** valueOf(java.lang.String);  
    36. }  
    37.   
    38. -keep class * implements android.os.Parcelable {                                # 保持 Parcelable 不被混淆  
    39.   public static final android.os.Parcelable$Creator *;  
    40. }  
    41.   
    42. -keep class MyClass;                                                            # 保持自己定义的类不被混淆  


    代码混淆的方法

    根据 SDK 的版本不同有 2 中不同的代码混淆方式,以上的 proguard.cfg 参数详解中所涉及到的信息是在较低版本 SDK 下的混淆脚本,事实上在高版本的 SDK 下混淆的原理和参数也与低版本的相差无几,只是在不同 SDK 版本的环境下引入混淆脚本的方式有所不同。具体方法如下:

    • 低版本 SDK 下,项目中同时包含 proguard.cfg 和 project.properties 文件,则只需在 project.properties 文件末尾添加 proguard.config=proguard.cfg 再将项目 Export 即可。
    • 高版本 SDK 下,项目中同时包含 proguard-project.txt 和 project.properties 文件,这时需要在 proguard-project.txt 文件中进行如下信息的配置,然后再将项目 Export 即可。下面以真实的文件进行演示说明。
    复制代码
    # This file is automatically generated by Android Tools.
    # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
    #
    # This file must be checked in Version Control Systems.
    #
    # To customize properties used by the Ant build system edit
    # "ant.properties", and override values to adapt the script to your
    # project structure.
    #
    # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
    #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
    
    proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
    
    # Project target.
    target=android-16
    复制代码

    以上的配置信息即是 project.properties 文件中内容,蓝色文字为我们在代码混淆过程中需要添加的配置信息,其中:sdk.dir 为你在当前机器上 SDK 的安装路径。如果想保留某个包下的文件不被混淆,可以在 proguard-project.txt文件中加入保留对应包名的语句即可。

    复制代码
    # To enable ProGuard in your project, edit project.properties
    # to define the proguard.config property as described in that file.
    #
    # Add project specific ProGuard rules here.
    # By default, the flags in this file are appended to flags specified
    # in ${sdk.dir}/tools/proguard/proguard-android.txt
    # You can edit the include path and order by changing the ProGuard
    # include property in project.properties.
    #
    # For more details, see
    #   http://developer.android.com/guide/developing/tools/proguard.html
    
    # Add any project specific keep options here:
    
    -dontwarn com.cnki.android.cnkireader.** 
    -keep class com.cnki.android.cnkireader.** { *; }
    
    # 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 *;
    #}
    复制代码


    -optimizationpasses 5


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


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


    # 不预校验
    # -dontpreverify


    # 预校验
    -dontoptimize 




    # 这1句是屏蔽警告
    -ignorewarnings 
    -verbose


    # 优化
    -optimizations !code/simplification/arithmetic,!field/*,!class/merging/*


    # 这1句是导入第三方的类库,防止混淆时候读取包内容出错
    #-libraryjars libs/youjar.jar 


    # 去掉警告
    -dontwarn 
    -dontskipnonpubliclibraryclassmembers


    # 不进行混淆保持原样
    -keep public class * extends android.app.Activity
    -keep public class * extends android.app.Application
    -keep public class * extends android.app.Fragment 
    -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




    # 过滤R文件的混淆:
    -keep class **.R$* {*;}


    # 过滤第三方包的混淆:其中packagename为第三方包的包名
    # -keep class packagename.** {*;}
    -keep class com.hisilicon.android.hibdinfo.** {*;}
    -keep class com.huawei.iptv.stb.dlna.mymedia.dto.** {*;}
    -keep class com.huawei.iptv.stb.dlna.mymedia.facade.** {*;}
    -keep class com.huawei.mymediaprifacade.** {*;}
    -keep class com.hisilicon.android.mediaplayer.** {*;}
    -keep class com.nostra13.universalimageloader.** {*;}
    -keep class com.huawei.android.airsharing.** {*;}


    # 所有方法不进行混淆
    -keep public abstract interface com.huawei.android.airsharing.listener{
    public protected <methods>;
    }


    -keep public abstract interface com.huawei.android.airsharing.api{
    public protected <methods>;
    }


    # 对该方法不进行混淆
    # -keep public class com.asqw.android{
    # public void Start(java.lang.String); 
    # }


    # 保护指定的类和类的成员的名称,如果所有指定的类成员出席(在压缩步骤之后)
    #-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 class * extends android.app.Activity {
    public void *(android.view.View);
    }




    -keepclassmembers enum * {
        public static **[] values();
        public static ** valueOf(java.lang.String);
    }


    # 保护指定的类文件和类的成员
    -keep class * implements android.os.Parcelable {
      public static final android.os.Parcelable$Creator *;
    }


    #-libraryjars libs/android-support-v4.jar
    #-dontwarn android.support.v4.**{*;}


    # 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 *;
    }


    #不混淆第三方包中的指定内容
    -keep class android-support-v4.**{*;}
    -keep public class * extends android.support.v4.**
    -keep class android.view.**{*;}









    ProGuard是一个免费的java类文件压缩,优化,混淆器.它探测并删除没有使用的类,字段,方法和属性.它删除没有用的说明并使用字节码得到最大优化.它使用无意义的名字来重命名类,字段和方法.

    ProGuard的使用是为了:

    1.创建紧凑的代码文档是为了更快的网络传输,快速装载和更小的内存占用.
    2.创建的程序和程序库很难使用反向工程.
    3.所以它能删除来自源文件中的没有调用的代码
    4.充分利用java6的快速加载的优点来提前检测和返回java6中存在的类文件.

    参数:

    -include {filename} 从给定的文件中读取配置参数

    -basedirectory {directoryname} 指定基础目录为以后相对的档案名称

    -injars {class_path} 指定要处理的应用程序jar,war,ear和目录

    -outjars {class_path} 指定处理完后要输出的jar,war,ear和目录的名称

    -libraryjars {classpath} 指定要处理的应用程序jar,war,ear和目录所需要的程序库文件

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

    -dontskipnonpubliclibraryclassmembers 指定不去忽略包可见的库类的成员。

    保留选项
    -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 不混淆输入的类文件

    -printmapping {filename}

    -applymapping {filename} 重用映射增加混淆

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

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

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

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

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

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

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

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

    因为我们开发的是webwork+spring+hibernate架构的项目,所有需要很详细的配置。(经过n次失败后总结)

    Example:

    -injars <project>.jar

    -outjars <project>_out.jar

    -libraryjars <java.home>/lib/rt.jar

    -libraryjars <project.home>/webroot/WEB-INF/lib/webwork.jar

    .......

    # 保留实现Action接口类中的公有的,友好的,私有的属性 和 公有的,友好的方法。其它的全部压缩,优化,混淆。

    # 因为配置文件中的类名是一个完整的类名,如果经过处理后就有可能找不到这个类。

    # 属性是jsp页面所需要的,如果经过处理jsp页面就无法得到action中的数据。

    -keep public class * implements com.opensymphony.xwork.Action{

    public protected private <fields>;

    public protected <methods>;

    }

    # 保留实现了Serializable接口类中的公有的,友好的,私有的成员(属性和方法)

    # 这个配置主要是对应实体类的配置。

    -keep public class * implements java.io.Serializable{

    public protected private *;

    }



    由于工作需要,这两天和同事在研究Android下面的ProGuard工具的使用,通过查看android官网对该工具的介绍以及网络上其它相关资料,再加上自己的亲手实践,算是有了一个基本了解。下面将自己的理解和认识简要的做个笔记,有异议或者不解的,可以直接留言。

    什么是ProGuard工具?


    ProGuard是android提供的一个免费的工具,它能够移除工程中一些没用的代码,或者使用语义上隐晦的名称来重命名代码中的类、字段和函数等,达到压缩、优化和混淆代码的功能。具体来说,使用ProGuard工具,可以达到下面两个目的:

    • 删除了源文件中没有调用的那部分代码,最大化的精简了字节码文件,使得最终生成的apk文件更小。
    • 使用语义混淆的命名替换了代码中的类、字段和函数等,使得其他人无法反编译获取源代码,起到对代码的保护作用。

    我看网上有不少人根据ProGuard工具的作用,直接称呼其为“混淆代码工具”,本文也暂时用这个词简称。

    更多的理解,可以参考ProGuard工具的官方文档地址:http://developer.android.com/tools/help/proguard.html

    ProGuard工具的集成与使用环境


    其实,ProGuard工具是已经集成到我们android系统中的,所以不需要用户手动的去集成。但是有一点需要注意,仅在程序处于Release模式时ProGuard才有效,反之在Debug模式是不能通过ProGuard来混淆代码的。

    根据ProGuard的具体使用环境,我分在Eclipse工具和android源码两种编译环境浅谈ProGuard的使用方法。

    Eclipse环境中ProGuard的使用


    以我电脑的android4.0环境为例,当我们在Eclipse中新建一个项目,或者导入一个已存在项目(保证当前项目没有语法错误)后,在工程的根目录,会自动生成两个ProGuard的混淆文件:proguard-project.txt和project.properties(在老版本的ADT中,只会生成一个叫proguard.cfg的文件)。我们先看下文件project.properties :

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    # This file is automatically generated by Android Tools.
    # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
    #
    # This file must be checked in Version Control Systems.
    #
    # To customize properties used by the Ant build system edit
    # "ant.properties", and override values to adapt the script to your
    # project structure.
    #
    # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
    #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
    
    # Project target.
    target=android-16
    

    看后面一段注释:To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home) ,意指要让ProGuard 来压缩和混淆代码,把这句注释去掉即可!所以,我们只要把下面一句注释取消即可,如下所示:

    1
    2
    # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
    proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
    

    我们仔细的看下这部分代码:这个地方是通过设置proguard.config属性来指定混淆代码的配置文件为本机SDK目录下面的proguard-android.txt文件,以及制定混淆的个性化配置文件为当前工程(eclipse下)根目录下面的proguard-project.txt文件 ,而后面这个文件,恰是我们刚才看到的原本在根目录下自动生成的另外一个文件!

    其实打开了这个地方,我们就已经可以混淆代码了,不过这里要注意:不能试图通过运行eclipse中的Run as 和 Debug as 菜单来生成混淆代码,必须通过如下图所示的方法将apk导出才行,当然你可以选择“签名”或者“不签名”:

    图片说明文字

    这样一步操作后,算是代码混淆完成了。那么怎么才能检验我们真的混淆了代码了呢?首先,我们能够看到在工程的根目录新生产了一个文件夹proguard,里面有四个文件,其内容如下:

    • dump.txt : 描述了apk中所有类 文件中内部的结构体。( Describes the internal structure of all the class files in the .apk file )
    • mapping.txt : 列出了原始的类、方法和名称与混淆代码见得映射。( Lists the mapping between the original and obfuscated class, method, and field names. )
    • seeds.txt : 列出了没有混淆的类和方法。( Lists the classes and members that are not obfuscated )
    • usage.txt : 列出congapk中删除的代码。( Lists the code that was stripped from the .apk )

    同时使用反编译软件对新生成的apk反编译后会发现,里面的类名、方法和变量等,都变成了简单的a、b、c、d等毫无含义的字母,这样就达到了混淆的目的:
    图片说明文字

    但在实际使用过程中,我们会发现当前apk中的有些方法和类,是要供外部使用的,而此时混淆了名称,外部调用就会报错了,那么怎么解决这个问题?此时就要用到我们刚才提到的混淆的个性化配置文件proguard-project.txt,在其中去配置不需要混淆的类、方法和变量等。关于混淆文件的具体配置方法,请看下面的最后一个标题会有详述。

    Android源码环境中ProGuard使用


    在Google发布的android源码中,面对那么多代码和文件目录,此时该如何混淆代码与配置混淆文件呢?

    android中默认是将代码混淆ProGuard关闭的,在alps/build/core/proguard.flags中有下面一句,意指将默认不混淆,不需要代码删除,我们将这一句注释起来,就起到代码混淆编译的作用。

    1
    2
    # Don't obfuscate. We only need dead code striping.
    -dontobfuscate
    

    可以说,这句是android工程中代码混淆的总开关,然而,注释了上面的代码后,整个工程就已经是代码混淆了吗?不是的,这里还要关注一个文件alps/build/core/package.mk,在这个文件中有这么一段:

    1
    2
    3
    4
    5
    6
    ifndef LOCAL_PROGUARD_ENABLED
    ifneq ($(filter user userdebug, $(TARGET_BUILD_VARIANT)),)
        # turn on Proguard by default for user & userdebug build
        #LOCAL_PROGUARD_ENABLED :=full
    endif
    endif
    

    切记:当我们需要对整个工程进行代码混淆的时候,就把此处的 #LOCAL_PROGUARD_ENABLED :=full注释去掉,成为有效的宏即可。如果不想对整个工程代码混淆,而只是相对某个模块混淆的话,就先不要动这里的代码。

    接着建议将真个工程new一遍,之后就可以针对具体的apk文件进行混淆文件的设置和定制了。下面以alps/packages/apps/Music为例说说该如何对特定模块做到混淆代码:

    在Music目录下,我们看到一个平时不太关注,但今天一定很在意的文件名:proguard.flags ,对了,这个文件就是Music的混淆配置文件,可以打开看看(有些地方没有这个文件,用户可以自己手动新建一下,最好名称也叫proguard.flags,android下默认都是这个名字)。当然,设置了配置文件还是不够的,还需要在同目录的Android.mk中如下设置如下两句:

    1
    2
    LOCAL_PROGUARD_ENABLED  := full
    LOCAL_PROGUARD_FLAG_FILES := proguard.flags
    

    只有这样才能让混淆代码有效,并且将混淆配置文件关联起来。(有些模块没有这两句句,就自己手动加上)

    反之,如果用户已经在alps/build/core/package.mk打开了全工程混淆编译的控制点后,又在针对某个模块时不想混淆编译怎么办?这就简单了,将模块下的Android.mk中设置为**LOCAL_PROGUARD_ENABLED := disabled**即可。

    这样,我们通过mm编译后的代码生成的apk,或者new真个工程后生成的烧机代码,都是已经添加相应配置的混淆代码了。

    反编译后,除过proguard.flags中定制的不需要混淆的代码外,其他都是被混淆了,如图所示是android中Music模块的混淆后反编译结果:

    图片说明文字

    混淆文件的配置


    在实际使用过程中,我们会发现当前apk中的有些方法和类,是要供外部使用的,而此时混淆了名称,外部调用就会报错了,那么怎么解决这个问题?此时就需要我们配置混淆的个性化文件proguard-project.txt(eclipse环境中)或者proguard.flags(android源码环境),在其中去配置不需要混淆的类、方法和变量等。关于混淆文件的具体配置方法,大家可以去搜索下,我这里提供一段网上有人共享的配置代码,这个配置代码保留了工程文件中的Activity、Application、Service、BroadcastReceiver、ContentProvider、BackupAgentHelper、Preference和ILicensingService的子类,并保留了所有的Native变量名及类名,所有类中部分以设定了固定参数格式的构造函数,枚举等等,用来防止外部调用出错,大家可以借鉴下,以后来配置自己的文件:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    -optimizationpasses 5
    -dontusemixedcaseclassnames
    -dontskipnonpubliclibraryclasses
    -dontpreverify
    -verbose
    -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
    
     -keepclasseswithmembernames class * {
         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 * {
        public static **[] values();
        public static ** valueOf(java.lang.String);
    }
    
    -keep class * implements android.os.Parcelable {
        public static final android.os.Parcelable$Creator *;
    }
    

    就写这么多了,有问题和建议,欢迎一起讨论!

    4.2以下版本尝试

         1.android中默认是将代码混淆ProGuard关闭的,在alps/build/core/proguard.flags中有下面一句,意指将默认不混淆,不需要代码删除,我们将这一句注释起来,就起到代码混淆编译的作用。

    1

    2

    # Don't obfuscate. We only need dead code striping.

    -dontobfuscate

                      将上面改为

    1

    2

    # Don't obfuscate. We only need dead code striping.

    #-dontobfuscate

                 2.还要关注一个文件alps/build/core/package.mk,在这个文件中有这么一段:

    1

    2

    3

    4

    5

    6

    ifndef LOCAL_PROGUARD_ENABLED

    ifneq($(filter user userdebug, $(TARGET_BUILD_VARIANT)),)

        # turn on Proguard by defaultfor user& userdebug build

        #LOCAL_PROGUARD_ENABLED :=full

    endif

    endif

                      不动,如果没注释,请注释下,注释为了下面部分加扰,打开应该是全部加扰,没有尝试过

                      3.在自己的工程下下面Android.mk里添加

    LOCAL_PROGUARD_ENABLED  := full

    LOCAL_PROGUARD_FLAG_FILES := proguard.cfg

                      proguard.cfgAndroid.mk同级目录下。

                      4.把源码重新全编译下

    4.4版本  可能还涉及\build\core\java.mk  具体改法在测试中

    4.4的话,还需要改一处才生效

    Build/core/java.mk 里的

    ifeq ($(filter obfuscation,$(LOCAL_PROGUARD_ENABLED)),)

    # By default no obfuscation

    # proguard_flags += -dontobfuscate ――注释掉这句

    endif  # No obfuscation


    6
    展开全文
  • Flutter 代码混淆 混淆Dart代码

    千次阅读 2020-10-23 15:39:02
    代码混淆 Flutter的代码混淆 flutter的代码混淆就是混淆dart代码。 代码混淆是修改应用程序二进制文件的过程,以使人们更难以理解。混淆将函数名和类名隐藏在已编译的Dart代码中,从而使攻击者很难对您的专有应用...

    代码混淆

    Flutter的代码混淆

    flutter的代码混淆就是混淆dart代码。
    代码混淆是修改应用程序二进制文件的过程,以使人们更难以理解。混淆将函数名和类名隐藏在已编译的Dart代码中,从而使攻击者很难对您的专有应用程序进行反向工程。

    Flutter代码混淆的做法

    Flutter版本小于1.16

    Android

    将以下行添加到<ProjectRoot> /android/gradle.properties

    extra-gen-snapshot-options=--obfuscate
    

    有关混淆Android主机的信息,请参阅“准备发布Android应用”中的启用Proguard

    iOS

    1. 修改build aot调用

    将以下标志添加到 /packages/flutter_tools/bin/xcode_backend.sh文件中的build aot调用中:

    ${extra_gen_snapshot_options_or_none}
    

    如下定义此标志:

    local extra_gen_snapshot_options_or_none=""
    if [[ -n "$EXTRA_GEN_SNAPSHOT_OPTIONS" ]]; then
      extra_gen_snapshot_options_or_none="--extra-gen-snapshot-options=$EXTRA_GEN_SNAPSHOT_OPTIONS"
    fi
    

    在这里插入图片描述
    修改xcode_backend.sh,要记得在build aot里的前一行加“\".

    2.修改发布配置
    <ProjectRoot> /ios/Flutter/Release.xcconfig中,添加以下行:

    EXTRA_GEN_SNAPSHOT_OPTIONS=--obfuscate
    

    Flutter 1.16.2或更高版本

    要混淆应用程序,请使用--obfuscate标志和--split-debug-info标志相结合来构建发行版本。

    --split-debug-info标志指定Flutter可以在其中输出调试文件的目录。该命令生成符号图。目前支持apk,appbundle,ios和ios框架目标。 (master和dev通道支持macos和aar。)例如:

    flutter build apk --obfuscate --split-debug-info=/<project-name>/<directory>
    

    混淆二进制文件后,请保存符号文件。如果以后要取消混淆堆栈跟踪,则需要这个文件。

    请注意,--split-debug-info标志也可以单独使用。实际上,它可以大大减少代码大小。有关应用程序大小的更多信息,请参阅测量应用程序的大小

    读取混淆的堆栈跟踪

    要调试由模糊处理的应用程序创建的堆栈跟踪,请使用以下步骤使其易于阅读:

    1. 找到匹配的符号文件。例如,从Android arm64设备崩溃将需要app.android-arm64.symbols
    2. flutter symbolize命令提供堆栈跟踪(存储在文件中)和符号文件。例如:
    flutter symbolize -i <stack trace file> -d /out/android/app.android-arm64.symbols
    

    ⚠️警告

    在编写最终将成为混淆的二进制代码的应用程序时,请注意以下几点。

    • 依赖于匹配特定类,函数或库名称的代码将失败。例如,以下对Expect()的调用在混淆的二进制文件中将不起作用:
    expect(foo.runtimeType.toString(), equals('Foo'))
    

    参考链接:
    Obfuscating Dart code
    flutter wiki

    展开全文
  • JAVA代码混淆

    千次阅读 2016-03-28 00:28:40
    代码混淆

    什么是代码混淆

    • Java 是一种跨平台的、解释型语言,Java 源代码编译成中间”字节码”存储于 class 文件中。由于跨平台的需要,Java
      字节码中包括了很多源代码信息,如变量名、方法名,并且通过这些名称来访问变量和方法,这些符号带有许多语义信息,很容易被反编译成 Java源代码。为了防止这种现象,我们可以使用 Java 混淆器对 Java 字节码进行混淆。

    • 混淆就是对发布出去的程序进行重新组织和处理,使得处理后的代码与处理前代码完成相同的功能,而混淆后的代码很难被反编译,即使反编译成功也很难得出程序的真正语义。被混淆过的程序代码,仍然遵照原来的档案格式和指令集,执行结果也与混淆前一样,只是混淆器将代码中的所有变量、函数、类的名称变为简短的英文字母代号,在缺乏相应的函数名和程序注释的况下,即使被反编译,也将难以阅读。同时混淆是不可逆的,在混淆的过程中一些不影响正常运行的信息将永久丢失,这些信息的丢失使程序变得更加难以理解。

    • 混淆器的作用不仅仅是保护代码,它也有精简编译后程序大小的作用。由于以上介绍的缩短变量和函数名以及丢失部分信息的原因, 编译后 jar 文件体积大约能减少25% ,这对当前费用较贵的无线网络传输是有一定意义的。

    混淆文件 proguard.cfg 参数详解

    -optimizationpasses 5                                                           # 压缩级别
    -dontusemixedcaseclassnames                                                     # 不使用大小写混合
    -dontskipnonpubliclibraryclasses                                                # 混淆第三方jar
    -dontpreverify                                                                  # 不做预校验
    -verbose                                                                        # 记录日志
    -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                    # 保持哪些类不被混淆
    
    -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 *;
    }
    
    -keep class MyClass;                                                            # 保持自己定义的类不被混淆
    

    代码混淆的方法

    • 高版本 SDK 下,项目中同时包含 proguard-project.txt 和 project.properties 文件,这时需要在 proguard-project.txt 文件中进行如下信息的配置,然后再将项目 Export 即可。下面以真实的文件进行演示说明。
    # This file is automatically generated by Android Tools.
    # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
    #
    # This file must be checked in Version Control Systems.
    #
    # To customize properties used by the Ant build system edit
    # "ant.properties", and override values to adapt the script to your
    # project structure.
    #
    # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
    #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
    
    proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
    
    # Project target.
    target=android-18
    

    以上的配置信息即是 project.properties 文件中内容,蓝色文字为我们在代码混淆过程中需要添加的配置信息,其中:sdk.dir 为你在当前机器上 SDK 的安装路径。如果想保留某个包下的文件不被混淆,可以在 proguard-project.txt文件中加入保留对应包名的语句即可。

    # To enable ProGuard in your project, edit project.properties
    # to define the proguard.config property as described in that file.
    #
    # Add project specific ProGuard rules here.
    # By default, the flags in this file are appended to flags specified
    # in ${sdk.dir}/tools/proguard/proguard-android.txt
    # You can edit the include path and order by changing the ProGuard
    # include property in project.properties.
    #
    # For more details, see
    #   http://developer.android.com/guide/developing/tools/proguard.html
    
    # Add any project specific keep options here:
    
    -dontwarn com.cnki.android.cnkireader.** 
    -keep class com.cnki.android.cnkireader.** { *; }
    
    # 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 *;
    #}
    
    
    
    -optimizationpasses 5
    
    
    # 混淆时不会产生形形色色的类名 
    -dontusemixedcaseclassnames
    
    
    # 指定不去忽略非公共的库类
    -dontskipnonpubliclibraryclasses
    
    
    # 不预校验
    # -dontpreverify
    
    
    # 预校验
    -dontoptimize 
    
    
    
    
    # 这1句是屏蔽警告
    -ignorewarnings 
    -verbose
    
    
    # 优化
    -optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
    
    
    # 这1句是导入第三方的类库,防止混淆时候读取包内容出错
    #-libraryjars libs/youjar.jar 
    
    
    # 去掉警告
    -dontwarn 
    -dontskipnonpubliclibraryclassmembers
    
    
    # 不进行混淆保持原样
    -keep public class * extends android.app.Activity
    -keep public class * extends android.app.Application
    -keep public class * extends android.app.Fragment 
    -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
    
    
    
    
    # 过滤R文件的混淆:
    -keep class **.R$* {*;}
    
    
    # 过滤第三方包的混淆:其中packagename为第三方包的包名
    # -keep class packagename.** {*;}
    -keep class com.hisilicon.android.hibdinfo.** {*;}
    -keep class com.huawei.iptv.stb.dlna.mymedia.dto.** {*;}
    -keep class com.huawei.iptv.stb.dlna.mymedia.facade.** {*;}
    -keep class com.huawei.mymediaprifacade.** {*;}
    -keep class com.hisilicon.android.mediaplayer.** {*;}
    -keep class com.nostra13.universalimageloader.** {*;}
    -keep class com.huawei.android.airsharing.** {*;}
    
    
    # 所有方法不进行混淆
    -keep public abstract interface com.huawei.android.airsharing.listener{
    public protected <methods>;
    }
    
    
    -keep public abstract interface com.huawei.android.airsharing.api{
    public protected <methods>;
    }
    
    
    # 对该方法不进行混淆
    # -keep public class com.asqw.android{
    # public void Start(java.lang.String); 
    # }
    
    
    # 保护指定的类和类的成员的名称,如果所有指定的类成员出席(在压缩步骤之后)
    #-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 class * extends android.app.Activity {
    public void *(android.view.View);
    }
    
    
    
    
    -keepclassmembers enum * {
        public static **[] values();
        public static ** valueOf(java.lang.String);
    }
    
    
    # 保护指定的类文件和类的成员
    -keep class * implements android.os.Parcelable {
      public static final android.os.Parcelable$Creator *;
    }
    
    
    #-libraryjars libs/android-support-v4.jar
    #-dontwarn android.support.v4.**{*;}
    
    
    # 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 *;
    }
    
    
    #不混淆第三方包中的指定内容
    -keep class android-support-v4.**{*;}
    -keep public class * extends android.support.v4.**
    -keep class android.view.**{*;}
    
    ProGuard是一个免费的java类文件压缩,优化,混淆器.它探测并删除没有使用的类,字段,方法和属性.它删除没有用的说明并使用字节码得到最大优化.它使用无意义的名字来重命名类,字段和方法.
    
    ProGuard的使用是为了:
    
    1.创建紧凑的代码文档是为了更快的网络传输,快速装载和更小的内存占用.
    2.创建的程序和程序库很难使用反向工程.
    3.所以它能删除来自源文件中的没有调用的代码
    4.充分利用java6的快速加载的优点来提前检测和返回java6中存在的类文件.
    
    参数:
    
    -include {filename} 从给定的文件中读取配置参数
    
    -basedirectory {directoryname} 指定基础目录为以后相对的档案名称
    
    -injars {class_path} 指定要处理的应用程序jar,war,ear和目录
    
    -outjars {class_path} 指定处理完后要输出的jar,war,ear和目录的名称
    
    -libraryjars {classpath} 指定要处理的应用程序jar,war,ear和目录所需要的程序库文件
    
    -dontskipnonpubliclibraryclasses 指定不去忽略非公共的库类。
    
    -dontskipnonpubliclibraryclassmembers 指定不去忽略包可见的库类的成员。
    
    保留选项
    -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 不混淆输入的类文件
    
    -printmapping {filename}
    
    -applymapping {filename} 重用映射增加混淆
    
    -obfuscationdictionary {filename} 使用给定文件中的关键字作为要混淆方法的名称
    
    -overloadaggressively 混淆时应用侵入式重载
    
    -useuniqueclassmembernames 确定统一的混淆类的成员名称来增加混淆
    
    -flattenpackagehierarchy {package_name} 重新包装所有重命名的包并放在给定的单一包中
    
    -repackageclass {package_name} 重新包装所有重命名的类文件中放在给定的单一包中
    
    -dontusemixedcaseclassnames 混淆时不会产生形形色色的类名
    
    -keepattributes {attribute_name,...} 保护给定的可选属性,例如LineNumberTable, LocalVariableTable, SourceFile, Deprecated, Synthetic, Signature, and InnerClasses.
    
    -renamesourcefileattribute {string} 设置源文件中给定的字符串常量
    因为我们开发的是webwork+spring+hibernate的架构的项目,所有需要很详细的配置。(经过n次失败后总结)
    Example:
    -injars <project>.jar
    -outjars <project>_out.jar
    -libraryjars <java.home>/lib/rt.jar
    -libraryjars <project.home>/webroot/WEB-INF/lib/webwork.jar
    .......
    # 保留实现Action接口类中的公有的,友好的,私有的属性 和 公有的,友好的方法。其它的全部压缩,优化,混淆。
    # 因为配置文件中的类名是一个完整的类名,如果经过处理后就有可能找不到这个类。
    # 属性是jsp页面所需要的,如果经过处理jsp页面就无法得到action中的数据。
    -keep public class * implements com.opensymphony.xwork.Action{
    public protected private <fields>;
    public protected <methods>;
    }
    # 保留实现了Serializable接口类中的公有的,友好的,私有的成员(属性和方法)
    # 这个配置主要是对应实体类的配置。
    -keep public class * implements java.io.Serializable{
    public protected private *;
    }
    
    
    keep选项
    [@annotationtype] [[!]public|final|abstract|@ ...] [!]interface|class|enum classname
        [extends|implements [@annotationtype] classname]
    [{
        [@annotationtype] [[!]public|private|protected|static|volatile|transient ...] <fields> |
                                                                          (fieldtype fieldname);
        [@annotationtype] [[!]public|private|protected|static|synchronized|native|abstract|strictfp ...] <methods> |
                                                                                               <init>(argumenttype,...) |
                                                                                               classname(argumenttype,...) |
                                                                                               (returntype methodname(argumenttype,...));
        [@annotationtype] [[!]public|private|protected|static ... ] *;
        ...
    }]
    
    
    

    什么是ProGuard工具?

    ProGuard是android提供的一个免费的工具,它能够移除工程中一些没用的代码,或者使用语义上隐晦的名称来重命名代码中的类、字段和函数等,达到压缩、优化和混淆代码的功能。具体来说,使用ProGuard工具,可以达到下面两个目的:

    删除了源文件中没有调用的那部分代码,最大化的精简了字节码文件,使得最终生成的apk文件更小。
    使用语义混淆的命名替换了代码中的类、字段和函数等,使得其他人无法反编译获取源代码,起到对代码的保护作用。
    我看网上有不少人根据ProGuard工具的作用,直接称呼其为“混淆代码工具”,本文也暂时用这个词简称。

    更多的理解,可以参考ProGuard工具的官方文档地址:http://developer.android.com/tools/help/proguard.html

    ##ProGuard工具的集成与使用环境
    其实,ProGuard工具是已经集成到我们android系统中的,所以不需要用户手动的去集成。但是有一点需要注意,仅在程序处于Release模式时ProGuard才有效,反之在Debug模式是不能通过ProGuard来混淆代码的。

    根据ProGuard的具体使用环境,我分在Eclipse工具和android源码两种编译环境浅谈ProGuard的使用方法

    Eclipse环境中ProGuard的使用

    以我电脑的android4.0环境为例,当我们在Eclipse中新建一个项目,或者导入一个已存在项目(保证当前项目没有语法错误)后,在工程的根目录,会自动生成两个ProGuard的混淆文件:proguard-project.txt和project.properties(在老版本的ADT中,只会生成一个叫proguard.cfg的文件)。我们先看下文件project.properties :
    
    # This file is automatically generated by Android Tools.
    # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
    #
    # This file must be checked in Version Control Systems.
    #
    # To customize properties used by the Ant build system edit
    # "ant.properties", and override values to adapt the script to your
    # project structure.
    #
    # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
    #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
    
    # Project target.
    target=android-18
    看后面一段注释:To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home) ,意指要让ProGuard 来压缩和混淆代码,把这句注释去掉即可!所以,我们只要把下面一句注释取消即可,如下所示:
    
    # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
    proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
    我们仔细的看下这部分代码:这个地方是通过设置proguard.config属性来指定混淆代码的配置文件为本机SDK目录下面的proguard-android.txt文件,以及制定混淆的个性化配置文件为当前工程(eclipse下)根目录下面的proguard-project.txt文件 ,而后面这个文件,恰是我们刚才看到的原本在根目录下自动生成的另外一个文件!
    
    其实打开了这个地方,我们就已经可以混淆代码了,不过这里要注意:不能试图通过运行eclipse中的Run as 和 Debug as 菜单来生成混淆代码,必须通过如下图所示的方法将apk导出才行,当然你可以选择“签名”或者“不签名”:
    
    这样一步操作后,算是代码混淆完成了。那么怎么才能检验我们真的混淆了代码了呢?首先,我们能够看到在工程的根目录新生产了一个文件夹proguard,里面有四个文件,其内容如下:
    
    dump.txt : 描述了apk中所有类 文件中内部的结构体。( Describes the internal structure of all the class files in the .apk file )
    mapping.txt : 列出了原始的类、方法和名称与混淆代码见得映射。( Lists the mapping between the original and obfuscated class, method, and field names. )
    seeds.txt : 列出了没有混淆的类和方法。( Lists the classes and members that are not obfuscated )
    usage.txt : 列出apk中删除的代码。( Lists the code that was stripped from the .apk )
    同时使用反编译软件对新生成的apk反编译后会发现,里面的类名、方法和变量等,都变成了简单的a、b、c、d等毫无含义的字母,这样就达到了混淆的目的:
    
    但在实际使用过程中,我们会发现当前apk中的有些方法和类,是要供外部使用的,而此时混淆了名称,外部调用就会报错了,那么怎么解决这个问题?此时就要用到我们刚才提到的混淆的个性化配置文件proguard-project.txt,在其中去配置不需要混淆的类、方法和变量等。关于混淆文件的具体配置方法,请看下面的最后一个标题会有详述。
    
    Android源码环境中ProGuard使用
    
    在Google发布的android源码中,面对那么多代码和文件目录,此时该如何混淆代码与配置混淆文件呢?
    
    android中默认是将代码混淆ProGuard关闭的,在alps/build/core/proguard.flags中有下面一句,意指将默认不混淆,不需要代码删除,我们将这一句注释起来,就起到代码混淆编译的作用。
    
    
    # Don't obfuscate. We only need dead code striping.
    -dontobfuscate
    可以说,这句是android工程中代码混淆的总开关,然而,注释了上面的代码后,整个工程就已经是代码混淆了吗?不是的,这里还要关注一个文件alps/build/core/package.mk,在这个文件中有这么一段:
    
    ifndef LOCAL_PROGUARD_ENABLED
    ifneq ($(filter user userdebug, $(TARGET_BUILD_VARIANT)),)
        # turn on Proguard by default for user & userdebug build
        #LOCAL_PROGUARD_ENABLED :=full
    endif
    endif
    切记:当我们需要对整个工程进行代码混淆的时候,就把此处的 #LOCAL_PROGUARD_ENABLED :=full注释去掉,成为有效的宏即可。如果不想对整个工程代码混淆,而只是相对某个模块混淆的话,就先不要动这里的代码。
    
    接着建议将真个工程new一遍,之后就可以针对具体的apk文件进行混淆文件的设置和定制了。下面以alps/packages/apps/Music为例说说该如何对特定模块做到混淆代码:
    
    在Music目录下,我们看到一个平时不太关注,但今天一定很在意的文件名:proguard.flags ,对了,这个文件就是Music的混淆配置文件,可以打开看看(有些地方没有这个文件,用户可以自己手动新建一下,最好名称也叫proguard.flags,android下默认都是这个名字)。当然,设置了配置文件还是不够的,还需要在同目录的Android.mk中如下设置如下两句:
    LOCAL_PROGUARD_ENABLED  := full
    LOCAL_PROGUARD_FLAG_FILES := proguard.flags
    只有这样才能让混淆代码有效,并且将混淆配置文件关联起来。(有些模块没有这两句句,就自己手动加上)
    
    反之,如果用户已经在alps/build/core/package.mk打开了全工程混淆编译的控制点后,又在针对某个模块时不想混淆编译怎么办?这就简单了,将模块下的Android.mk中设置为**LOCAL_PROGUARD_ENABLED := disabled**即可。
    
    这样,我们通过mm编译后的代码生成的apk,或者new真个工程后生成的烧机代码,都是已经添加相应配置的混淆代码了。
    
    反编译后,除过proguard.flags中定制的不需要混淆的代码外,其他都是被混淆了,如图所示是android中Music模块的混淆后反编译结果:
    
    
    混淆文件的配置
    
    在实际使用过程中,我们会发现当前apk中的有些方法和类,是要供外部使用的,而此时混淆了名称,外部调用就会报错了,那么怎么解决这个问题?此时就需要我们配置混淆的个性化文件proguard-project.txt(eclipse环境中)或者proguard.flags(android源码环境),在其中去配置不需要混淆的类、方法和变量等。关于混淆文件的具体配置方法,大家可以去搜索下,我这里提供一段网上有人共享的配置代码,这个配置代码保留了工程文件中的Activity、Application、Service、BroadcastReceiver、ContentProvider、BackupAgentHelper、Preference和ILicensingService的子类,并保留了所有的Native变量名及类名,所有类中部分以设定了固定参数格式的构造函数,枚举等等,用来防止外部调用出错,大家可以借鉴下,以后来配置自己的文件:
    
    
    -optimizationpasses 5
    -dontusemixedcaseclassnames
    -dontskipnonpubliclibraryclasses
    -dontpreverify
    -verbose
    -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
    
     -keepclasseswithmembernames class * {
         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 * {
        public static **[] values();
        public static ** valueOf(java.lang.String);
    }
    
    -keep class * implements android.os.Parcelable {
        public static final android.os.Parcelable$Creator *;
    }
    
    
    展开全文
  • Android 代码混淆

    千次阅读 2020-09-09 16:19:12
    Android 代码混淆 简介 在我们日常开发中,对已经开发完成的源代码,需做一些代码混淆工作,以对代码起到一种保护和降低安装包体积的作用。 开启混淆 在app的build.gradle文件中如下代码: android { ...... ...

    Android 代码混淆

    简介
    在我们日常开发中,对已经开发完成的源代码,需做一些代码混淆工作,以对代码起到一种保护和降低安装包体积的作用。

    开启混淆
    在app的build.gradle文件中如下代码:

    android {
        ......
        buildTypes {
            release {
                //开启代码混淆
                minifyEnabled true
                //开启资源混淆,移除未使用的资源
                shrinkResources true
                //proguard-android-optimize.txt:SDK提供的默认混淆文件
                //proguard-rules.pro:自定义混淆文件
                proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            }
        }
    }
    

    配置混淆文件
    在app的proguard-rules.pro文件中编写混淆代码即可
    在这里插入图片描述
    在这里插入图片描述

    混淆语法

    命令 作用
    -keep 防止类和成员被移除或者被重命名
    -keepnames 防止类和成员被重命名
    -keepclassmembers 防止成员被移除或者被重命名
    -keepclassmembersname 防止成员被重命名
    -keepclasseswithmembers 防止拥有该成员的类和成员被移除或者被重命名
    -keepclasseswithmembernames 防止拥有该成员的类和成员被重命名
    类通配符 * 匹配任意长度字符,但不含包名分隔符(.)
    类通配符 ** 匹配任意长度字符,并且包含包名分隔符(.)
    类extends 即可以指定类的基类
    类implements 匹配实现了某接口的类
    类$ 内部类
    成员(方法)通配符 * 匹配任意长度字符,但不含包名分隔符(.)
    成员(方法)通配符 ** 匹配任意长度字符,并且包含包名分隔符(.)
    成员(方法)通配符 *** 匹配任意参数类型
    成员(方法)通配符 … 匹配任意长度的任意类型参数
    成员(方法)通配符 <> 匹配方法名,eg.

    常用基本混淆

    #############################################
    #
    # 基本指令区域(没什么别的需求不需要动)
    #
    #############################################
    # 代码混淆压缩比,在0~7之间,默认为5,一般不做修改
    -optimizationpasses 5
    
    # 混合时不使用大小写混合,混合后的类名为小写
    -dontusemixedcaseclassnames
    
    # 指定不去忽略非公共库的类
    -dontskipnonpubliclibraryclasses
    
    # 这句话能够使我们的项目混淆后产生映射文件
    # 包含有类名->混淆后类名的映射关系
    -verbose
    
    # 指定不去忽略非公共库的类成员
    -dontskipnonpubliclibraryclassmembers
    
    # 不做预校验,preverify是proguard的四个步骤之一,Android不需要preverify,去掉这一步能够加快混淆速度。
    -dontpreverify
    
    # 保留Annotation不混淆
    -keepattributes *Annotation*,InnerClasses
    
    # 避免混淆泛型
    -keepattributes Signature
    
    # 抛出异常时保留代码行号
    -keepattributes SourceFile,LineNumberTable
    
    # 指定混淆是采用的算法,后面的参数是一个过滤器
    # 这个过滤器是谷歌推荐的算法,一般不做更改
    -optimizations !code/simplification/cast,!field/*,!class/merging/*
    
    
    #############################################
    #
    # Android开发中一些需要保留的公共部分(没什么别的需求不需要动)
    #
    #############################################
    
    # 保留我们使用的四大组件,自定义的Application等等这些类不被混淆
    # 因为这些子类都有可能被外部调用
    -keep public class * extends android.app.Activity
    -keep public class * extends android.app.Appliction
    -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
    
    
    # 保留support下的所有类及其内部类
    -keep class android.support.** {*;}
    
    # 保留继承的
    -keep public class * extends android.support.v4.**
    -keep public class * extends android.support.v7.**
    -keep public class * extends android.support.annotation.**
    
    # 保留R下面的资源
    -keep class **.R$* {*;}
    
    # 保留本地native方法不被混淆
    -keepclasseswithmembernames class * {
        native <methods>;
    }
    
    # 保留在Activity中的方法参数是view的方法,
    # 这样以来我们在layout中写的onClick就不会被影响
    -keepclassmembers class * extends android.app.Activity{
        public void *(android.view.View);
    }
    
    # 保留枚举类不被混淆
    -keepclassmembers enum * {
        public static **[] values();
        public static ** valueOf(java.lang.String);
    }
    
    # 保留我们自定义控件(继承自View)不被混淆
    -keep public class * extends android.view.View{
        *** get*();
        void set*(***);
        public <init>(android.content.Context);
        public <init>(android.content.Context, android.util.AttributeSet);
        public <init>(android.content.Context, android.util.AttributeSet, int);
    }
    
    # 保留Parcelable序列化类不被混淆
    -keep class * implements android.os.Parcelable {
        public static final android.os.Parcelable$Creator *;
    }
    
    # 保留Serializable序列化的类不被混淆
    -keepclassmembers class * implements java.io.Serializable {
        static final long serialVersionUID;
        private static final java.io.ObjectStreamField[] serialPersistentFields;
        !static !transient <fields>;
        !private <fields>;
        !private <methods>;
        private void writeObject(java.io.ObjectOutputStream);
        private void readObject(java.io.ObjectInputStream);
        java.lang.Object writeReplace();
        java.lang.Object readResolve();
    }
    
    # 对于带有回调函数的onXXEvent、**On*Listener的,不能被混淆
    -keepclassmembers class * {
        void *(**On*Event);
        void *(**On*Listener);
    }
    
    # WebView处理,项目中没有使用到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);
    }
    
    #-----------处理实体类---------------
    # 在开发的时候我们可以将所有的实体类放在一个包内,这样我们写一次混淆就行了。
    -keep class com.zzs.wanandroidmvvm.model.bean.** { *; }
    

    常见第三方混淆

    ButterKnife

    # ButterKnife
    -keep class butterknife.** { *; }
    -dontwarn butterknife.internal.**
    -keep class **$$ViewBinder { *; }
    -keepclasseswithmembernames class * {
        @butterknife.* <fields>;
    }
    -keepclasseswithmembernames class * {
        @butterknife.* <methods>;
    }
    

    EventBus

    # EventBus
    -keepattributes *Annotation*
    -keepclassmembers class ** {
        @org.greenrobot.eventbus.Subscribe <methods>;
    }
    -keep enum org.greenrobot.eventbus.ThreadMode { *; }
    

    OkHttp3

    # OkHttp3
    -dontwarn com.squareup.okhttp3.**
    -keep class com.squareup.okhttp3.** { *;}
    -dontwarn okio.**
    

    Retrofit

    # Retrofit
    -dontwarn retrofit2.**
    -keep class retrofit2.** { *; }
    -keepattributes Signature
    -keepattributes Exceptions
    

    RxJava RxAndroid

    # RxJava RxAndroid
    -dontwarn sun.misc.**
    -keepclassmembers class rx.internal.util.unsafe.*ArrayQueue*Field* {
        long producerIndex;
        long consumerIndex;
    }
    -keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueProducerNodeRef {
        rx.internal.util.atomic.LinkedQueueNode producerNode;
    }
    -keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueConsumerNodeRef {
        rx.internal.util.atomic.LinkedQueueNode consumerNode;
    }
    

    Glide

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

    Gson

    # Gson
    -keepattributes Signature
    -keepattributes *Annotation*
    -dontwarn sun.misc.**
    -keep class com.google.gson.examples.android.model.** { <fields>; }
    -keep class * implements com.google.gson.TypeAdapterFactory
    -keep class * implements com.google.gson.JsonSerializer
    -keep class * implements com.google.gson.JsonDeserializer
    -keepclassmembers,allowobfuscation class * {
      @com.google.gson.annotations.SerializedName <fields>;
    }
    

    GreenDao

    # GreenDao
    -keepclassmembers class * extends org.greenrobot.greendao.AbstractDao {
        public static java.lang.String TABLENAME;
    }
    -keep class **$Properties { *; }
    

    不混淆第三方库(包括jar、aar、依赖)

    -keep class 第三方库包名.** { *;}
    如:
    -keep class com.baidu.map.** { *;}
    
    展开全文
  • 代码混淆技术

    2021-01-23 11:24:39
    代码混淆技术 代码混淆亦称花指令,是将计算机程序的代码,转换成一种功能上等价,但是难于阅读和理解的形式的行为。代码混淆可以用于程序源代码,也可以用于程序编译而成的中间代码。执行代码混淆的程序被称作...
  • 代码混淆是一种代码保护机制可以保护js逻辑不被破译。项目一般要经过三个阶段开发、测试、部署上线。在部署的时候我们会对代码进行压缩和整合。代码混淆一般是通过正则替换实现或者语法树替换实现。代码混淆后安全...
  • 在实际的开发成产品apk的发布过程中,我们经常会使用到代码混淆技术。不过在讲解如何进行代码混淆之前,我先跟大家演示一下反编译的过程,这样才能让大家明白为什么需要进行代码混淆。    一、代码反编译  ...
  • Android代码混淆之混淆规则
  • ios加固,ios代码混淆,ios代码混淆工具,iOS源码混淆产品是一款纯离线的源码加密工具,主要用于保护iOS项目中的核心代码,避免因逆向工程或破解,造成核心技术被泄漏、代码执行流程被分析等安全问题。该加密工具和...
  • Java代码混淆

    2018-11-18 01:39:59
    Java代码混淆
  • Unity 代码混淆

    千次阅读 2018-07-06 11:39:49
    ===oc-代码混淆=======代码混淆过程====由于ios过审没有通过,苹果回赠了一个2.1的大礼包。首先想到的可能的解决方案是代码混淆,关于object-c的代码混淆的流程如下1,下载一个oc 的代码混淆工具:...
  • iOS代码混淆加密工具 制作iOS马甲包,包括代码加密、代码混淆、修改方法名、修改类名、生成垃圾代码、修改工程名等 https://zfj1128.blog.csdn.net/article/details/95482006
  • Allatori代码混淆

    千次阅读 2019-09-04 15:05:07
    Allatori代码混淆 *在项目(模块)中添加代码混淆,采用allatori官网提供的allatori.jar,本案例采用SpringBoot搭建,maven私服搭建引入allatori依赖 一、采用pom方式引入 1、pom.xml中引入依赖 在dependencies标签中...
  • java代码混淆

    千次阅读 2018-12-01 10:38:28
    代码混淆是为了防止反编译。如果没有对代码混淆,那么其他人很容易就可以得到你的项目中的所有代码。而混淆之后,其他人就没那么容易获得了。 保护软件有着双重意义: 一是保护软件的知识产权 (intellectual ...
  • Allatori代码混淆springboot

    千次阅读 热门讨论 2020-12-10 15:05:17
    Allatori代码混淆 这个是下载的allatori包 Clean.bat用来清除混淆后生成的jar包和日志文件。 config.xml是主要的配置文件,用来配置代码混淆的格式。 mousegestures-1.2.jar是要混淆的jar包文件。 ...
  • iOS代码混淆

    千次阅读 热门讨论 2018-05-14 16:46:30
    代码混淆都是一个很重要的安全技术手段,如何进行全局的自动化代码混淆,以下开源项目详细介绍了如何实现这个目标。 如果你的工程支持cocoapod,你可以直接添加! pod "STCObfuscator" (注:请用最新版本...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 16,583
精华内容 6,633
关键字:

代码混淆