美文网首页
混淆小结

混淆小结

作者: gogoingmonkey | 来源:发表于2018-04-25 15:04 被阅读19次

    混淆小结

    最近公司项目在做全量混淆的功能,做好了打包一测 发现一个比较有意思的地方————混淆引起的问题

    异常现象

    在项目中有个我的黄金页面 里面有个实时金价的显示,这个270.84元/克 的显示 是一个定时查询接口返回的数据,默认是5S刷新一次,服务端会返回这个具体的刷新时间,但是现在发现这个控件一直显示0,而且这个文案加了一个上滑更新的效果 ,看到的效果就是一个一直在抖动的东西。

    问题的追溯

    下载一个线上环境发现 没任何问题,然后打了一个混淆的测试包,发现一样的现象,因为没法断点调试,所以在里面打印日志排查,项目中使用的handler发消息

     public  class GoldFreshHandler extends Handler{
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                request();
                if(checkActiveListener()>0) {
                    android.util.Log.e("GoldProvider d的handler ", "GOLD_UPDATE_DURATION "+GOLD_UPDATE_DURATION );
                    mHandler.sendEmptyMessageDelayed(ACTION_GOLD_REQUEST, GOLD_UPDATE_DURATION);
                }
            }
        }
    

    发现在上面的地方这个 GOLD_UPDATE_DURATION 一直为0,使用抓包工具一看:


    image.png

    发现这有数据啊,然后在网络请求回调的地方去吧data.toString()打出来 发现数据都是默认值 就是int double 是0 string类型的是空

    处理问题

    现在就直接定位到问题是打包混淆把这个javaBean对象混淆了,虽然没有报错,但是在解析这种序列化 和反序列化的时候数据出问题了,
    反编译看到,这个包里面确实被混淆了


    image.png

    现在在混淆文件中,也就是 proguard-project.txt 中增加了:

    -keep class com.xiaoniu.finance.interfaces.**{*;}
    

    完美解决了数据显示问题,而且反编译也没有被混淆:
    还有一种方案就是看这个混淆文件注释中给我们提供了:

    -keep class * implements java.io.Serializable {*;}
    

    这个和上面的区别在于这个混淆了接口中的东西,只是实现这个序列化的没有被混淆


    image.png

    知识点总结

    keep 保留类和类中的成员,防止被混淆或者移除
    keepnames 保留类和类中的成员,防止被混淆,但是当成员没有被引用时会被移除
    keepclassmembers 只保留类中的成员,防止他们被混淆或者移除
    keepclassmembersnames 只保留类中的成员,防止他们被混淆或者移除,但是当类中的成员没有被引用时还是会被移除
    keepclasseswithmembers 保留类和类中的成员,前提是指明的类中必须含有该成员,没有的话还是会被混淆
    keepclasseswithmembersnames 保留类和类中的成员,前提是指明的类中必须含有该成员,没有的话还是会被混淆。需要注意的是没有被引用的成员会被移除

    1.不混淆某个类的构造函数

    例如不混淆Test类的构造函数

    -keepcalssmembers clsss com.ticktick.example.Text{
        public <init>(int,int)
    }
    

    2.不混淆某个包下所有的类或者指定的类

    例如不混淆package com.ticktick.example下的所有的类/接口

    不混淆这个包下的所有的类
    -keep class com.ticktick.example.**{*;}
    

    例如不混淆com.ticktick.example.Text类

    -keep class com.ticktick.example.Text{*;}
    

    如果希望不混淆某个接口,则把上述命令的class替换为interface即可.

    3.不混淆某个类的特定的函数

    例如不混淆com.ticktick.example.Test类中的setTestString函数

    -keepclassmembers class com.ticktick.example.Test{
        public void setTestString(java.lang.String);
    }
    

    4.不混淆某个类的子类,某个接口的实现

    例如不混淆com.ticktick.example.Test的子类

    -keep public class * extend com.ticktick.example.Test
    

    例如不混淆com.ticktick.example.TestInterface的实现

    -keep class * implements com.ticktick.example.TestInterface{
        public static final com.ticktick.example.TestInterface$Creator *;
    }
    

    5.注意第三方依赖包

    例如添加android-support-v4.jar依赖包

    -libraryjars libs/android-support-v4.jar
    
    -dontwarn android.support.v4.**{*;}
    -keep class android.support.v4.**{*;}
    -keep interface android.support.v4.**{*;}
    

    注意添加dontwarn,因为默认情况下proguard会检查每一个引用是否正确,但是第三方库里往往有些不会用到的类,没有正确引用,所有如果不配置的话,系统会报错.

    相关文章

      网友评论

          本文标题:混淆小结

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