美文网首页1-Android开发知识
记一次Android 9.0上"加密算法"变

记一次Android 9.0上"加密算法"变

作者: ZenCabin | 来源:发表于2019-03-07 16:08 被阅读74次

    华为应用市场反馈公司的app用户评论里出现了部分Android 9.0手机崩溃的留言,情况紧急,WTF!! Σ(っ °Д °;)っ

    image.png

    单从评论里可以看到部分蛛丝马迹:

    • 崩溃出现的时间点比较集中
    • 用户是在手机升级到Android 9.0之后,出现的闪退
    • 清理数据重启后不再闪退

    原因分析:

    • 集中出现在那几天,应该就是华为用户升级系统比较密集。
    • 升级前app的缓存文件数据,导致了升级后app运行的崩溃。
    • 是不是新系统的某种和文件操作相关的特性引起的问题,

    Android 9.0行为变更

    还原现场

    想要解决这个问题,就需要先还原出现问题的场景。首先需要找公司申请一部华为手机,越新越好,P打头的,o( ̄︶ ̄)o,,,嘿,醒醒!

    其次,要想还原场景,就需要把系统从9.0之前升级到9.0,这工程量,想想其实就够了>_<

    好吧!还能有什么办法可能模拟类似状况。

    铁锅炖自己.png

    此时,公司大佬的一句话提出一种思路,“可不可以备份9.0之前的数据还原到9.0上”,好吧,试试看。死马当活马医,那就adb backup一下。这个命令在不同手机上支持情况不尽相同,有挺大的几率会失败,厂商也是为了安全,避免数据的泄露。

    <application
            android:name=".app.XXXApplication"
            android:allowBackup="true"
            android:icon="@mipmap/launcher"
    

    首先,AndroidManifest.xml中<application节点需要配置allowBackup这个属性,意思为是否允许备份系统和用户数据的属性。

    然后进入9.0之前(比如8.0)的系统app,正常操作流程,然后执行adb backup命令,备份数据。

    // adb backup [-f ] [-apk|-noapk] [-shared|-noshared] [-all] [-system|nosystem] []
    参数:
    // -s XXX 连接设备的serial,如果只有一部设备,可以不填,多个必须指定
    // -f C://backup/xxx.ab 指定备份文件的目录和文件名,如果不填,就是当前目录的backup.ab
    // -apk|-noapk 是否在备份里包含apk或者仅仅只备份应用数据
    // -shared|-noshared 是否备份设备共享的SD card内容,默认是-noshare,主要包括内部存储中的音乐、图片和视频,因此为保险起见,建议加上-share
    // -all 所有应用,可以指定报名来备份指定应用
    // -system|-nosystem 决定-all标签是否包含系统应用,默认的是-system,根据情况可选择是否用-nosystem
    
    adb -s XXX backup -nosystem -noshared -apk xxx.ab com.xxx.xxxxx
    

    最后我们能得到一个backup.ab的文件,接着我们把数据备份的文件还原到9.0系统上,当前系统也应该已经安装有我们的app,并且最好未启动过,或者执行过清理所有数据。还原到命令:

    adb restore backup.ab
    

    使用备份/还原出来的数据,我们重新启动Android 9.0上的app,然后果然闪退了,不知道是该高兴呢,还是。。。

    image.png

    原因定位

    出现了崩溃,虚拟机会打印出相应的栈信息。


    image.png

    正式包被混淆了,对应mapping文件,一步一步找到出错的位置。发现这是一段aspectJ注入的代码,用来做事件统计之类的操作,由于使用时对象为空,所以崩溃了( ఠൠఠ )ノ。看到这里,突然觉着有些似曾相识的感觉,上bugly悄悄去,果不其然,之前有过类似的出错,看来是老朋友。

    image.png

    追踪初始化操作,发现并没有什么可能性会导致未被初始化,那就奇了怪了,问题究竟出在哪呢?

    image.png

    测试的包都是加固过的,由于新版本修改过加固工具版本,额~,试试未加固的怎么样?

    经过漫长的打包、安装、操作,备份/还原,未加固的包也崩溃了,而且出错信息指向了fastjson解析json的时候,情况看起来有点微妙(微微有点妙)( ̄︶ ̄)↗ ,继续追踪,出问题的地方在刚刚那个问题之前,但是为什么刚刚没有出现这个崩溃?

    关键时刻!大佬又出现了,“是不是加固包的crash被吞掉了”。


    image.png

    查查logcat,发现刚刚的崩溃,果然有这次的log,只不过没有引起系统崩溃,System.err,却没有崩溃,这是什么操作!

    image.png image.png

    然后百度下加固的原理:
    Apk加固原理解析

    猜测可能的原因是:宿主app在Application的onCreate方法中执行application对象替换操作,将我们的app的application对象替换掉宿主app的application,并执行其onCreate方法,这些替换操作和调用onCreate操作都是在native里执行的,所以java的报错被native以System.err的方式输出了。

    image.png

    然后这个报错导致我们的app执行中断,但是目前还在宿主的Application的onCreate方法中,所以生命周期方法仍然在继续,之后由于终端导致的对象初始化操作未执行,而出现了空指针异常。这个时候的执行已经不在natvie里面了,所以就导致了app的崩溃!!!

    解决问题

    经过进一步调查,发现这个fastjson的解析异常是由于Android 9.0上加密算法的变化导致的旧数据解析异常了。Android9.0针对加密算法的实现和处理引入了几项变更,好🕳!!

    问题原因找到了,场景也复现了,下一步就是解决这个问题了!(/▽\)

    这么看来这个问题算是新版本适配的问题了!我们需要针对新的版本出相应的处理,对于解析失败的数据,我们返回空字符来避免错误就好。

    Android 9(API 级别 28)行为变更:所有应用

    Android9加密变更.png

    相关文章

      网友评论

        本文标题:记一次Android 9.0上"加密算法"变

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