Android混淆和反混淆

news2024/9/22 4:30:10

    本篇来介绍下Android的混淆和反混淆,说起混淆,大家都会很自然地想到ProGuard,此外还有R8。事实上,AGP3.3之后,官方默认使用R8做代码优化、混淆和压缩。ProGuard和R8常常用于混淆最终的Android项目,增加项目被反编译的难度。

目录

一、ProGuard

1、压缩(Shrink)

2、优化(Optimize)

3、混淆(Obfuscate)

4、预检(Preveirfy)

二、R8

1、代码压缩

2、资源压缩

3、代码混淆

4、代码优化

三、Proguard和R8对比

四、混淆​​​​​​​

五、反混淆

1、mapping文件

2、proguardgui.sh


一、ProGuard

    ProGuard是一个压缩、优化和混淆Java字节码文件的免费的工具。混淆只是ProGuard的其中一项功能,ProGuard能够对Java类中的代码进行压缩(Shrink),优化(Optimize),混淆(Obfuscate),预检(Preveirfy)。

1、压缩(Shrink)

删除没有使用的类,字段,方法和属性。

2、优化(Optimize)

对字节码进行优化,并且移除无用指令。

3、混淆(Obfuscate)

使用a,b,c等无意义的名称,对类,字段和方法进行重命名。

4、预检(Preveirfy)

在Java平台上对处理后的代码进行预检。

二、R8

    R8是一个将java字节码转换为优化的dex的工具。它遍历整个应用程序,然后对其进行优化,例如删除未使用的类、方法等。它可以帮助我们减少构建的大小并使我们的应用程序更加安全。R8使用Proguard的规则,R8比Proguard更快更强。

1、代码压缩

安全地从App及其库依赖项中删除未使用的类,字段,方法和属性。

2、资源压缩

从打包的App中删除未使用的资源,包括应用程序库依赖项中未使用的资源。它与代码压缩一起使用,这样一旦删除了未使用的代码,也可以安全地删除不再引用的资源。

3、代码混淆

使用简短无意义的名称重命名代码里的类,字段和方法,从而减少DEX文件大小。

4、代码优化

删除未使用的代码或重写代码使其更简洁。

三、Proguard和R8对比

    在使用 Proguard 时,应用程序代码由Java编译器转换为Java字节码.class文件。然后Proguard使用我们编写的规则对其进行优化产出优化后的.class文件,最后将其转换为可执行的Dalvik字节码。编译打包的流程如下:

 R8引入之后,代码的混淆和转换为dex通过R8一步完成,编译打包的流程如下:

1、R8 有效地内联容器类并删除未使用的类、字段和方法,包体积更小。

2、与 Proguard 相比,R8 对 Kotlin 的支持更多。

3、R8比 Proguard 更快,从而减少了整体构建时间。

四、混淆

虽然Android Studio已经默认使用R8作为编译器,但是需要我们在build.gradle(app)中配置一下:

    buildTypes {
        release {
            // 是否开启代码压缩
            minifyEnabled true
            // 是否开启资源压缩
            shrinkResources true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            signingConfig signingConfigs.release
            android.applicationVariants.all { variant ->
                variant.outputs.all {
                    outputFileName = "demo_" + defaultConfig.versionName + "_release.apk"
                }
            }
        }
    }

 本篇我们使用如下demo,代码造了一个空指针异常,这是为后面反混淆准备的:

package com.example.proguarddemo;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.View;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {
    private TextView mTextView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mTextView = findViewById(R.id.crash);
        mTextView.setOnClickListener(v -> {
            mTextView = null;
            mTextView.setText("11111");
        });
    }
}

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/crash"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

    既然AS已经默认使用R8作为编译器,那么我们不再去对比Proguard和R8的包体积和编译速度,我们使用本篇博客的demo来对比下开R8和不开R8打release包的体积。

(1)不开R8:

(2)开R8,但不开资源压缩:

(3)开R8,开资源压缩:

 通过对比上面的包体积,可以看到,开了R8 + 资源压缩后,包体积缩减了55.6%。接下来,我们看下代码是否真的混淆了,装上打包后的release包,运行后点击textview,触发了崩溃,我们看下堆栈能不能看到源码:

2023-04-24 16:46:45.163 6037-6037/? E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.proguarddemo, PID: 6037
    java.lang.NullPointerException: throw with null exception
        at a1.a.onClick(SourceFile:5)
        at android.view.View.performClick(View.java:7281)
        at android.view.View.performClickInternal(View.java:7255)
        at android.view.View.access$3600(View.java:828)
        at android.view.View$PerformClick.run(View.java:27925)
        at android.os.Handler.handleCallback(Handler.java:900)
        at android.os.Handler.dispatchMessage(Handler.java:103)
        at android.os.Looper.loop(Looper.java:219)
        at android.app.ActivityThread.main(ActivityThread.java:8393)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1055)

可以看到,崩溃的堆栈是混淆后的,a1.a.onClick,代码确实是混淆后的,这增强了代码的安全性,让外人不那么容易反编译得到关键代码。

五、反混淆

    承接上文说到的,代码混淆后代码的安全性增强了。正式包发版后,针对线上的crash收集到的崩溃堆栈也是混淆后的,增加了crash问题排查定位的难度。那么,如何反混淆呢?

    混淆的原理是把一些类名、方法名、属性名等修改为无意义的字母等,降低代码可阅读性的同时,压缩代码体积。混淆的同时会生成一个mapping文件,记录的就是映射关系,通过映射关系可以拿到混淆前的类名和方法名。

     

1、mapping文件

打release包后,生成的mapping文件路径:app/build/outputs/mapping/release

2、proguardgui.sh

在sdk中有反混淆的工具:proguardgui.sh,可以帮助我们通过mapping文件解析崩溃堆栈。进入到Android/sdk/tools/proguard/bin,直接运行

./proguardgui.sh

会打开一个gui界面,选择mapping文件,粘贴crash堆栈后,点击Retrace!:

 可以看到,是MainActivity的onClick方法的第三行发生了空指针:

    本篇系统的介绍了Android的Proguard和R8,总结了二者的执行过程和对比,并通过实际的demo去验证R8优化后的包体积和混淆的结果。同时,也介绍了如何通过解析mapping的工具proguardgui.sh去辅助我们解析混淆后的crash堆栈,方便更快速的定位线上问题。如果对你有所帮助或启发,欢迎关注点赞。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/456586.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vue-router【VUE】

6. vue-router 6.1 相关理解 6.1.1 vue-router 的理解 路由就是一组key-value的对应关系。多个路由&#xff0c;需要经过路由器的管理vue是一个插件库&#xff0c;专门用来实现SPA应用。 6.1.2 对SPA应用的理解 单页 Web 应用&#xff08;single page web application, SP…

C++基础阶段入门 (1)

1.C统一初始化: 初始化列表解决方案&#xff1a; //C语言的初始化方案 int main() {int a 10;int* ip nullptr;int ar[] { 12,23,34,45,56,67 }; } C 初始化&#xff1a;使用{ } int main(){//char ch a;char ch{ a };//int a 10;int a{ 10 };int b int(10);int x{ 10…

企业软文怎么写吸引人?教你几招

企业每年都要投放大量的商业软文到热门的内容平台上&#xff0c;也许现在你阅读的某篇文章&#xff0c;就是一篇企业软文。 真正厉害的软文在于你根本看不出来这是一条广告&#xff0c;从而让你心甘情愿的为某个产品掏腰包。企业软文到底怎么写才吸引人&#xff0c;接下来伯乐…

sfavsrv导致主机负载高

下午接客户电话&#xff0c;监控告警了&#xff0c;主机负载高&#xff0c;登录后top查看&#xff0c;确实比较的高 再次查看负载高的cpu发现是sfavsrv 吓了一跳&#xff0c;还以为中毒了&#xff0c;发给客户检查是否自行部署了第3方软件&#xff0c;确实第3方的&#xff0c;关…

如何将pdf图片文字转换成word 文字word图片怎么转换pdf

如今大家在工作中常常会运用到电脑来办公&#xff0c;电脑的运用大大提高了我们的工作效率&#xff0c;在带来机会的同时同样也带来了新挑战。 pdf图片怎么转换成word文档&#xff1f;PDF格式是一种常用的文档格式&#xff0c;它可以保持文档内容和格式的完整性&#xff0c;但是…

4月有8本SCIE期刊被剔除(附MDPI/Frontiers/Hindawi最新在检期刊)

2023年4月SCI、SSCI期刊目录更新 2023年4月18日&#xff0c;科睿唯安更新了WOS期刊目录&#xff0c;继上次3月WOS期刊目录剔除50本SCIE&SSCI期刊之后&#xff0c;此次4月更新又有8本SCIE期刊发生变动&#xff0c;其中有4本期刊被踢出SCIE数据库&#xff0c;4本期刊更改了名…

QMS-云质说质量 - 2 你真的知道什么是质量吗

云质QMS原创 转载请注明来源 作者&#xff1a;王洪石 引言 暴露的只是冰山一角 注&#xff1a;&#xff08;&#xff09;中为ISO9000:2015 质量管理体系基础和术语的编号 一个组织的质量管理(3.3.4)&#xff0c;可包括制定质量方针(3.5.9)和质量目标(3.7.2)&#xff0c;以及通…

Web 攻防之业务安全:接口未授权访问/调用测试(敏感信息泄露)

Web 攻防之业务安全&#xff1a;接口未授权访问/调用测试 业务安全是指保护业务系统免受安全威胁的措施或手段。广义的业务安全应包括业务运行的软硬件平台&#xff08;操作系统、数据库&#xff0c;中间件等&#xff09;、业务系统自身&#xff08;软件或设备&#xff09;、业…

火车站闸机web3d数字展示平台全方位动态呈现设备细节

智能互联网时代&#xff0c;传统的图片、文字、视频等产品展示方式&#xff0c;因为缺少互动性&#xff0c;很难引起用户的兴趣&#xff0c;已经逐渐失去了宣传优势。 Web3D交互展示技术的出现&#xff0c;让众多品牌和企业找到了新的方向&#xff0c;线上产品展示不在枯燥无趣…

少儿编程 中国电子学会图形化编程等级考试Scratch编程一级真题解析(选择题)2023年3月

2023年3月scratch编程等级考试一级真题 选择题&#xff08;共25题&#xff0c;每题2分&#xff0c;共50分&#xff09; 1、下列说法不正确的是 A、可以从声音库中随机导入声音 B、可以录制自己的声音上传 C、可以修改声音的大小 D、不能修改声音的速度 答案&#xff1a;D…

计算机网络第1章(概述)

文章目录 1.1、计算机网络在信息时代的作用1.2、因特网概述1、网络、互连网&#xff08;互联网&#xff09;和因特网2、因特网发展的三个阶段3、因特网的标准化工作4、因特网的组成 1.3 三种交换方式1、电路交换&#xff08;Circuit Switching&#xff09;2、分组交换&#xff…

Composer使用教程

Composer使用教程 前言1.Composer 简介2. 下载与安装2.1 局部安装2.2 全局安装2.3 更新composer2.4查看composer2.5 安装composer镜像加速 3. composer的使用3.1初始化3.2安装第三方包 4. 自动加载器4.1 加载非 class 文件4.2 加载自己写 class 文件4.3 PSR-4 自动加载规范 5. …

【脱产二站上岸】上海交大819复习经验总结

笔者来自通信考研小马哥23上交819全程班学员 本科西南某985&#xff0c;成绩排名中下&#xff08;面试被老师疯狂吐槽&#xff09;&#xff0c;一战本校&#xff0c;初试分数差10来分被刷。21年12月考完数学和专业课出来就知道考不上了&#xff0c;分数一出就下决心二战&#…

软件测试,想找一份20k以上的工作需要掌握哪些知识?

都知道IT行业是高薪人员的聚集地&#xff0c;但想要成为高薪程序员却并不容易。月薪20k是测试工程师的一个门槛&#xff0c;想要突破就必须掌握更多的技能。 因为程序员职业发展很快&#xff0c;即使是相同起点的人&#xff0c;经过几年的工作或学习&#xff0c;会迅速拉开极…

Python列表和字典前面为什么要加星号(**)?

人生苦短&#xff0c;我用python 今天来和大家一起学习一下为什么Python列表和字典前面会加星号&#xff08;&#xff09;&#xff1f;** python 安装包资料:点击此处跳转文末名片获取 Python 中&#xff0c; 单星号*和双星号**除了作为“乘”和“幂”的数值运算符外&#xff…

【python的pdb调试简单了解一下?】

调试是程序开发过程中的重要环节&#xff0c;它可以帮助开发人员识别和解决程序中的错误和问题。Python 提供了一个内置的调试器 pdb&#xff08;Python Debugger&#xff09;&#xff0c;可以帮助开发人员逐行分析代码、查看变量值、跟踪函数调用等。 入门 要使用 pdb 调试器…

Numpy从入门到精通——存读矩阵以及读取矩阵中的数据

这个专栏名为《Numpy从入门到精通》&#xff0c;顾名思义&#xff0c;是记录自己学习numpy的学习过程&#xff0c;也方便自己之后复盘&#xff01;为深度学习的进一步学习奠定基础&#xff01;希望能给大家带来帮助&#xff0c;爱睡觉的咋祝您生活愉快&#xff01; 这一篇介绍《…

c#期末复习题重点难点题

2. (单选题, 9分)在.NET中&#xff0c;.NET Framework由&#xff08; &#xff09;组成。 A. FCL和CLR -开发库和运行环境B. ADO.NETASP.NET -数据操作和web框架C. CLS和CTS -语法规范和类型规范 即所有语言和语法规范 和 各语言间的类型互操作性规范D. Winform和ASP.NET…

2023前端面试上岸手册——JavaScript部分

目录 JavaScript 有哪些数据类型&#xff0c;它们的区别&#xff1f;数据类型检测的方式有哪些null 和undefined 区别如何获取安全的 undefined 值&#xff1f;Object.is() 与比较操作符 “两等” 、“三等” 的区别&#xff1f;什么是 JavaScript 中的包装类型&#xff1f;为什…

盘点:这些好用的ERP软件你知道哪些?

在选择ERP系统时&#xff0c;我们可以按照这三个维度&#xff0c;然后再按照需求去选择ERP系统。 市面上ERP软件大概可以分为三大类&#xff1a; ① 标准ERP应用&#xff1a;功能比较固定&#xff0c;难以满足个性化需求&#xff0c;二次开发难度很高&#xff1b; ② 找外包/…