微信资源混淆,导致的约束布局 Constraintlayout 控件重叠!

微信资源混淆,导致的约束布局 Constraintlayout 控件重叠!

码农世界 2024-05-30 前端 95 次浏览 0个评论

问题

1、广告六要素

虽然我不参与广告 sdk 接入等相关工作,但是最近总是听到一个词广告六要素。这到底是什么?

国内下载类广告,尤其是针对移动应用推广的广告,其成功实施往往围绕几个关键要素进行,这些要素能够帮助广告主更有效地触达目标用户,促进应用下载。

经查阅知道,国内各大广告 SDK 平台优量汇、穿山甲、快手等已逐步开始(早已)支持广告六要素,提供了获取应用的下载六项信息:

  • 应用名称
  • 开发者公司名称
  • 应用版本
  • 隐私协议超链
  • 权限列表超链
  • 产品功能

    下图以荣耀广告为例,这个是六要素控件显示正常的情况:

    2、布局错乱

    在不使用自定义混淆(包含微信资源混淆 AndResGuard)出包运行布局是正确的!

    使用微信资源混淆之后,运行错乱,六要素重叠显示!

    AndResGuard Github

    排查

    通过使用uiautomatorviewer布局分析,定位找到了该广告的布局文件honor_ads_six_factor.xml,并确定了每个显示文本对应的控件,uiautomatorviewer 工具跟随 Android studio,安装目录下可以找到,也可以全局搜索查找。

    C:\Users\Primer\AppData\Local\Android\Sdk\tools\bin\uiautomatorviewer.bat

    我们知道,父容器使用的是约束布局ConstraintLayout(减少布局嵌套,布局优化),既然是因为使用了资源混淆导致问题出现,得了解资源混淆的配置是什么?

    andResGuard {
        mappingFile = null
        use7zip = true
        useSign = true
        // 打开这个开关,会keep住所有资源的原始路径,只混淆资源的名字
        keepRoot = false
        // 设置这个值,会把arsc name列混淆成相同的名字,减少string常量池的大小
        fixedResName = "arg"
        // 打开这个开关会合并所有哈希值相同的资源,但请不要过度依赖这个功能去除去冗余资源
        mergeDuplicatedRes = true
        //混淆白名单
        whiteList = [
            // for your icon
            "R.drawable.icon",
            // for fabric
            "R.string.com.crashlytics.*",
            // for google-services
            "R.string.google_app_id",
            "R.string.gcm_defaultSenderId",
            "R.string.default_web_client_id",
            "R.string.ga_trackingId",
            "R.string.firebase_database_url",
            "R.string.google_api_key",
            "R.string.google_crash_reporting_api_key"
        ]
        compressFilePattern = [
            "*.png",
            "*.jpg",
            "*.jpeg",
            "*.gif",
        ]
        sevenzip {
             artifact = 'com.tencent.mm:SevenZip:1.2.21'
        }
        /**
        * 可选: 如果不设置则会默认覆盖assemble输出的apk
        **/
        // finalApkBackupPath = "${project.rootDir}/final.apk"
        /**
        * 可选: 指定v1签名时生成jar文件的摘要算法
        * 默认值为“SHA-1”
        **/
        // digestalg = "SHA-256"
    }
    

    1、首先,布局文件加白名单

    白名单配置是whiteList ,一开始我们是连同布局文件也混淆的(上图是加白之后的),查看荣耀广告 SDK 的资源文件,发现文件名称都有统一前缀 honor_ads,所以加白了下面的资源,测试 -> 运行 -> 布局错乱 -> 异常

    "R.drawable.honor_ads*",
    "R.interpolator.honor_ads*",
    "R.anim.honor_ads*",
    "R.animator.honor_ads*",
    "R.attr.honor_ads*",
    "R.color.honor_ads*",
    "R.dimen.honor_ads*",
    "R.mipmap.honor_ads*",
    "R.id.honor_ads*",
    "R.string.honor_ads*",
    "R.layout.honor_ads*",
    "R.style.honor_ads*",
    

    2、仔细查看布局

    上图的布局细看是这样的:

    ① 名称 广告 公司

    ② 隐私 权限 介绍 版本

    • 两行,七个控件
    • 第一行三个,第二行四个控件
    • 猜想:第二行如何很好的约束布局(按照我们的正常编码思维哈)
      • 1、第二行可能是:app:layout_constraintTop_toBottomOf=“第一行”,这个里是把第一行和第二行分别看成一个整体

        【很明显,该布局代码不是这样的(简单布局嵌套过深,没必要)】

      • 2、第二行的第一个可能是:app:layout_constraintTop_toBottomOf=“第一行的第一个(名称)”,然后第二行的其他元素像第一个或上一个控件对齐

        【很明显,布局代码也不是这样的(想必大多数人会这样写吧,没错我就是那大多数人)】

      • 3、使用 androidx.constraintlayout.widget.Barrier 进一步约束布局

        【代码确实是这样】

        此前,我从未使用或了解过约束布局中的 androidx.constraintlayout.widget.Barrier这到底是什么?大概意思就是可以控制布局,具体如何使用自行搜索。

        简书:Barrier的使用及实例

        查资料他有两个重要的属性:

        • barrierDirection:方向
        • constraint_referenced_ids:被约束的控件 id 名称集合
          
              app:barrierDirection="3"
              app:constraint_referenced_ids="ad_empty_view_top,ad_brand_name,ad_flag_view,ad_developer_view"/>
          

          我们知道约束布局中 Direction 是这样的:

          所以布局中的 Barrier 起到什么作用你应该知道了。

          问题的关键是要找到关键问题(手动狗头),关键果然是 Barrier 的 app:constraint_referenced_ids,因为只有他会约束布局影响控件显示位置!

          再细看 Barrier !

          比如像这种属性值能正常替换

          constraint_referenced_ids 属性值为什么不能被替换?

          • 像是插件还不支持比较新的属性值替换?
          • 或者属性值为数组列表的格式不同导致没有被替换?

            3、解决

            总之,问题清晰了,如果要进一步看资源混淆插件源码排查属性值为什么没被替换,自己尝试适配插件那可麻烦,耗时费力(除非你真的激情满满),所以最终解决就是给资源 id 名称加入白名单,保持 constraint_referenced_ids 集合里面的名称不被混淆即可!

            还记的之前的加白里面虽然包含了 id,但是 keep 的是 honor_ads*,无效啊!

            "R.id.honor_ads*",
            

            最终,再次提取加白前缀,那就是

            "R.id.ad_*",
            

            app:constraint_referenced_ids="

            ad_empty_view_top,

            ad_brand_name,

            ad_flag_view,

            ad_developer_view"

            荣耀联运 SDK 竟也有坑,只是当时没测到~

转载请注明来自码农世界,本文标题:《微信资源混淆,导致的约束布局 Constraintlayout 控件重叠!》

百度分享代码,如果开启HTTPS请参考李洋个人博客
每一天,每一秒,你所做的决定都会改变你的人生!

发表评论

快捷回复:

评论列表 (暂无评论,95人围观)参与讨论

还没有评论,来说两句吧...

Top