混淆

作者: 闫鹏飞写字的地方 | 来源:发表于2021-10-28 16:17 被阅读0次
学单词
Pro

美 /proʊ/
n. 职业选手;益处;妓女;赞成者;赞成的意见
adj. (非正式)专业的,职业的
prep. 赞成的
adv. 赞成地
n. (Pro)(俄、美、意、印、西)普罗(人名)

Guard

美 /ɡɑːrd/
n. 卫兵,警卫;看守,守卫;列车长;保护装置;(英国的)禁卫军;(篮球)后卫;(拳击运动员的)防御姿势
v. 守卫,保卫;看守,监视;警惕,防范;保护,维护
【名】(Guard)(英)格尔德(人名)
n. (Guard)人名;(英)格尔德

1.简介

Android Studio自身集成Java语言的ProGuard作为压缩,优化和混淆工具,配合Gradle构建工具使用很简单,只需要在工程应用目录的gradle文件中设置minifyEnabledtrue即可。然后我们就可以到proguard-rules.pro文件中加入我们的混淆规则了。

android {
    ...
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}
学单词
Shrinking

美 /ˈʃrɪŋkɪŋ/
v. 缩水,收缩;变小,缩小;萎缩;退缩;回避,离开(shrink 的现在分词)

Shrink

美 /ʃrɪŋk/
v. (使)缩小,减少;(通常指布料、衣服等洗后)缩水,皱缩;退缩,畏缩;畏避,回避(工作、责任等)
n. <非正式> 精神病学家,心理学家;收缩;畏缩

Optimization

美 /,ɑptəmɪ'zeʃən/
n. 最佳化,最优化

Obfuscation

英 /ˌɒbfʌsˈkeɪʃn/
n. 困惑;模糊;昏迷

2.ProGuard作用

2.1压缩(Shrinking):默认开启,用以减小应用体积,移除未被使用的类和成员,并且会在优化动作执行之后再次执行(因为优化后可能会再次暴露一些未被使用的类和成员)。

-dontshrink 关闭压缩

2.2优化(Optimization):默认开启,在字节码级别执行优化,让应用运行的更快。

-dontoptimize  关闭优化

-optimizationpasses n 表示proguard对代码进行迭代优化的次数,Android一般为5

2.3混淆(Obfuscation):默认开启,增大反编译难度,类和类成员会被随机命名,除非用keep保护。

-dontobfuscate 关闭混淆

混淆后默认会在工程目录app/build/outputs/mapping/release下生成一个mapping.txt文件,这就是混淆规则,我们可以根据这个文件把混淆后的代码反推回源本的代码,所以这个文件很重要,注意保护好。原则上,代码混淆后越乱越无规律越好,但有些地方我们是要避免混淆的,否则程序运行就会出错,所以就有了下面我们要教大家的,如何让自己的部分代码避免混淆从而防止出错。

2.查看混淆后的代码

2.1工具包
dex2jar 0.0.9.15JD-GUIapktool
https://pan.baidu.com/s/12ZApUf_7q0IZIK-x2C34VQ
提取码w000

2.2下载并解压


image.png

2.3使用dex2jar反编译dex文件
将需要反编译的APK后缀名改为.rar或则.zip,解压看到目录

image.png

得到其中的classes.dex文件(它就是java文件编译再通过dx工具打包而成的)

2.4将获取到的classes.dex复制到解压出来的工具dex2jar文件夹内,

image.png

2.5在命令行下,进入到dex2jar.bat所在目录,输入命令:
dex2jar 0.0.9.15输入dex2jar.bat classes.dex
dex2jar-2.0输入:d2j-dex2jar.bat classes.dex

image.png

简单命令

//打开D盘
d: 
//查看当前文件列表
dir
//打开软件目录
cd 软件

2.6运行结束后,在该目录下会生成一个classes_dex2jar.jar的文件

image.png

2.7然后打开工具jd-gui文件夹里的jd-gui.exe,用该工具打开生成的classes_dex2jar.jar文件,便可以看到源码

image.png

tip:如果打开找不到自己写的源码,可以解压classes_dex2jar.jar文件,可看到要找的源码,拖拽代码到jd-gui中即可查看代码

3.混淆基本规则

3.1

-keep class com.example.myapplication.*
-keep class com.example.myapplication.**

*一颗星表示只是保持该包下的类名,而子包下的类名还是会被混淆;
**两颗星表示把本包和所含子包下的类名都保持;
用以上方法保持类后,你会发现类名虽然未混淆,但里面的具体方法和变量命名还是变了

eg:
混淆前

image.png

混淆后
*一颗星

image.png

**两颗星

image.png

3.2
如果既想保持类名,又想保持里面的内容不被混淆,我们就需要以下方法了

-keep class com.example.myapplication.* {*;}
-keep class com.example.myapplication.** {*;}

混淆后
* {*;}一颗星

image.png

** {*;}两颗星

image.png image.png

3.3
在此基础上,我们也可以使用Java的基本规则来保护特定类不被混淆,比如我们可以用extendimplement等这些Java规则。如下例子就避免所有继承Activity的类被混淆

-keep public class * extends android.app.Activity

混淆后

image.png

3.4
如果我们要保留一个类中的内部类不被混淆则需要用$符号,如下例子表示保持MainActivity内部类User中的所有public内容不被混淆。

-keepclassmembers class com.example.myapplication.MainActivity$User {
   public *;
}

eg

混淆前


image.png

没有对内部类处理的


image.png

对内部类处理的


image.png

3.5
再者,如果一个类中你不希望保持全部内容不被混淆,而只是希望保护类下的特定内容,就可以使用

<init>;     //匹配所有构造器
<fields>;   //匹配所有域
<methods>;  //匹配所有方法方法

你还可以在<fields><methods>前面加上privatepublicnative等来进一步指定不被混淆的内容,如

-keep class com.example.myapplication.entity.Person {
    public <methods>;
}

表示Person类下的所有public方法都不会被混淆,当然你还可以加入参数,比如以下表示用java.lang.Stringint作为入参的构造函数不会被混淆

-keep class com.example.myapplication.entity.Person {
   public <init>(java.lang.String, int);
}

有时候你是不是还想着,我不需要保持类名,我只需要把该类下的特定方法保持不被混淆就好,那你就不能用keep方法了,keep方法会保持类名,而需要用keepclassmembers ,如此类名就不会被保持,为了便于对这些规则进行理解,官网给出了以下表格

保留 防止被移除或者被重命名 防止被重命名
类和类成员 -keep -keepnames
仅类成员 -keepclassmembers -keepclassmembernames
如果拥有某成员,保留类和类成员 -keepclasseswithmembers -keepclasseswithmembernames

移除是指在压缩(Shrinking)时是否会被删除。

4.注意事项

1.jni方法不可混淆,因为这个方法需要和native方法保持一致;

-keepclasseswithmembernames class * { # 保持native方法不被混淆    
    native <methods>;
}

2.反射用到的类不混淆(否则反射可能出现问题);
3.AndroidMainfest中的类不混淆,所以四大组件和Application的子类和Framework层下所有的类默认不会进行混淆。自定义的View默认也不会被混淆;所以像网上贴的很多排除自定义View,或四大组件被混淆的规则在Android Studio中是无需加入的;
4.与服务端交互时,使用GSONfastjson等框架解析服务端数据时,所写的JSON对象类不混淆,否则无法将JSON解析成对应的对象;
5.使用第三方开源库或者引用其他第三方的SDK包时,如果有特别要求,也需要在混淆文件中加入对应的混淆规则;
6.有用到WebViewJS调用也需要保证写的接口方法不混淆,原因和第一条一样;
7.Parcelable的子类和Creator静态成员变量不混淆,否则会产生Android.os.BadParcelableException异常;

-keep class * implements Android.os.Parcelable { # 保持Parcelable不被混淆           
    public static final Android.os.Parcelable$Creator *;
}

8.使用enum类型时需要注意避免以下两个方法混淆,因为enum类的特殊性,以下两个方法会被反射调用,见第二条规则。

-keepclassmembers enum * {  
    public static **[] values();  
    public static ** valueOf(java.lang.String);  
}
4.出错后如何排查问题

4.1开启调试模式下混淆代码

debug {
    minifyEnabled true
    proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}

4.2查看mapping.txt文件
它里面存放着源码到混淆之后的代码的映射信息,这个文件是在我们执行proguard之后产生的

image.png

4.3制造一个混淆代码的Crash

public class TestProGuard {

    private static final String TAG = "TestProGuard";

    public static void beforeProGuard(){
        Log.d(TAG, "beforeProGuard");
        createAnCrash();
    }

    private static void createAnCrash() {
        throw new IllegalArgumentException("IllegalArgumentException");
    }

}
public class MainActivity extends AppCompatActivity {


    private Person person;
    private User user;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        TestProGuard.beforeProGuard();
...

运行之后Logcat日志:

image.png

4.3如何还原

mapping文件位置

image.png

我们来到sdk/tools/proguard/bin目录下,打开proguardgui.bat文件

image.png

双击打开后


image.png

到这里即可排查出问题

tip:如果你还没有看到行号可在混淆文件中放入

-keepattributes SourceFile,LineNumberTable
image.png

完结

相关文章

  • js反混淆

    颜文字反混淆颜文字混淆.png 混淆2混淆2.png

  • Android Proguard混淆小记

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

  • Android 混淆相关

    Android 混淆原则 混淆 ProGuard常用语法 混淆基本指令

  • Android打包那些事

    目录 一.混淆(Proguard) 混淆是打包过程中最重要的流程之一,这里所说的的混淆是包括代码混淆和资源的“混淆...

  • 2018-04-21FCN结果分析

    一、混淆矩阵confusion matrix 1,混淆矩阵 2,分类器评估方法:准确率和混淆矩阵*** 使用混淆矩...

  • Android混淆(Proguard)详解

    目录: 1、混淆的作用及好处2、混淆的原理3、混淆的具体使用--- 3.1、混淆的基本语法--- 3.2、...

  • APP常用的安全技巧

    代码中使用混淆,不要使用默认AB混淆,可以使用空白混淆 混淆配置中去除:-keepattributes Sourc...

  • Android代码混淆

    待整理。。。 参考: Android混淆从入门到精通 Android代码混淆之混淆规则 代码混淆规则配置文件:pr...

  • 不能使用混淆的情况

    不能使用混淆的情况 反射使用的元素 最好不要让一些Bean对象混淆 四大组件不能混淆 注解不能混淆 不能混淆枚举中...

  • [iOS]混淆-方法混淆

    Objective-C/Swift的方法名、属性名混淆 特点 混淆的时机是在编译前 混淆后,不影响源代码 混淆生成...

网友评论

      本文标题:混淆

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