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

news2024/12/23 9:53:16

在这里插入图片描述

问题

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 名称集合
<androidx.constraintlayout.widget.Barrier
    android:id="@+id/xlp"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    <!-- 这里编译后是 3,我推测是 Bottom (你们可以验证下)-->
    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 竟也有坑,只是当时没测到~

在这里插入图片描述

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

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

相关文章

互联网政务应用安全管理规定:使用安全连接方式访问

前几日&#xff0c;由中央网络安全和信息化委员会办公室、中央机构编制委员会办公室、工业和信息化部、公安部等4部门联合制定的《互联网政务应用安全管理规定》&#xff08;以下简称规定&#xff09;发布了&#xff0c;规定定义了互联网政务应用&#xff0c;也对互联网政务应用…

stream-并行流

定义 常规的流都是串行的流并行流就是并发的处理数据&#xff0c;一般要求被处理的数据互相不影响优点&#xff1a;数据多的时候速度更快&#xff0c;缺点&#xff1a;浪费系统资源&#xff0c;数据少的时候开启线程更耗费时间 模版 Stream<Integer> stream1 Stream.of…

拿捏数据结构- 链式二叉树

链式二叉树的概念&#xff1a; 链式二叉树解决的是非完全二叉树解决不了的问题 什么意思呢&#xff0c;简单的说就是&#xff0c;链式二叉树 可以是下面三种二叉树 但是非链式二叉树只能是前两种 链式二叉树的存储 节点结构&#xff1a;首先定义一个结构体或类来表示二叉树的节…

快速上手 HuggingFace

HuggingFace HuggingFace 是类似于 GitHub 的社区&#xff0c;它主要提供各种的模型的使用&#xff0c;和 github 不同的是&#xff0c;HuggingFace 同时提供了一套框架&#xff0c;进行模型推理&#xff0c;模型训练、和模型库文件的管理等等。本文将介绍&#xff0c;如何快速…

大字体学生出勤记录系统网页源码

源码介绍 上课需要一个个点名记录出勤情况&#xff0c;就借助AI制作了一个网页版学生出勤记录系统&#xff0c; 大字体显示学生姓名和照片&#xff0c;让坐在最后排学生也能看清楚&#xff0c;显示姓名同时会语音播报姓名&#xff0c; 操作很简单&#xff0c;先导入学生姓名…

Golang | Leetcode Golang题解之第115题不同的子序列

题目&#xff1a; 题解&#xff1a; func numDistinct(s, t string) int {m, n : len(s), len(t)if m < n {return 0}dp : make([][]int, m1)for i : range dp {dp[i] make([]int, n1)dp[i][n] 1}for i : m - 1; i > 0; i-- {for j : n - 1; j > 0; j-- {if s[i] …

C++ | Leetcode C++题解之第115题不同的子序列

题目&#xff1a; 题解&#xff1a; class Solution { public:int numDistinct(string s, string t) {int m s.length(), n t.length();if (m < n) {return 0;}vector<vector<unsigned long long>> dp(m 1, vector<unsigned long long>(n 1));for (i…

正点原子[第二期]Linux之ARM(MX6U)裸机篇学习笔记-19.1讲 串口格式化输出printf

前言&#xff1a; 本文是根据哔哩哔哩网站上“正点原子[第二期]Linux之ARM&#xff08;MX6U&#xff09;裸机篇”视频的学习笔记&#xff0c;在这里会记录下正点原子 I.MX6ULL 开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了正点原子教学视频和链接中的内容。…

PHP:集成Xunsearch生成前端搜索骨架

如果是安装宝塔&#xff0c;我们在集成xunsearch的时候就会比较简单&#xff0c;后面我们在介绍其他的接入方式&#xff1b; 首先我们进入到宝塔管理后台&#xff1a;【软件商店】-【输入xun】-【点击xunsearch】直接安装即可 安装成功之后&#xff0c;会自动在www/server中创…

(delphi11最新学习资料) Object Pascal 学习笔记---第13章第4节 (内存管理和接口)

13.4 内存管理和接口 ​ 在第11章中&#xff0c;我介绍了接口的内存管理的关键要素。与对象不同&#xff0c;接口是受管理且具有引用计数。如我所提到的&#xff0c;接口引用会增加所引用对象的引用计数&#xff0c;但您可以声明接口引用为弱引用以禁用引用计数&#xff08;但…

Reactor模式Proactor模式

1.Reactor/Dispatcher模式 1.1 概述 Reactor模式下&#xff0c;服务端的构成为Reactor 处理资源池。其中&#xff0c;Reactor负责监听和分发事件&#xff0c;而处理资源池则负责处理事件。 该模式下的组合方案有下面几种(第三种几乎没有被实际应用)&#xff1a; 1 * Reacto…

AURIX TC3xx单片机介绍-启动过程介绍1

从各个域控制器硬件解决方案来看,MPU可能来自多个供应商,有瑞萨,有NXP等,但对于MCU来说,基本都采用英飞凌TC3xx。 今天我们就来看一下TC3xx的启动过程,主要包含如下内容: uC上电过程中,会经过一个上电时序,从复位状态“脱离”出来;Boot Firmware是复位后第一个执行的…

设计模式:原型模式(Prototype)

设计模式&#xff1a;原型模式&#xff08;Prototype&#xff09; 设计模式&#xff1a;原型模式&#xff08;Prototype&#xff09;模式动机模式定义模式结构时序图模式实现在单线程环境下的测试在多线程环境下的测试模式分析优缺点适用场景应用场景模式扩展应用实例实例 1&am…

SecureCRT for Mac注册激活版:专业终端SSH工具

SecureCRT是一款支持SSH&#xff08;SSH1和SSH2&#xff09;的终端仿真程序&#xff0c;简单地说是Windows下登录UNIX或Linux服务器主机的软件。 SecureCRT支持SSH&#xff0c;同时支持Telnet和rlogin协议。SecureCRT是一款用于连接运行包括Windows、UNIX和VMS的理想工具。通过…

user-agents,一个无敌的 Python 库!

更多Python学习内容&#xff1a;ipengtao.com 大家好&#xff0c;今天为大家分享一个无敌的 Python 库 - user-agents。 Github地址&#xff1a;https://github.com/selwin/python-user-agents 在Web开发和数据分析中&#xff0c;了解用户的设备和浏览器信息是非常重要的。通过…

开发一个comfyui的自定义节点

文章目录 目标功能开发环境comfyui自定义节点的实现原理仓库地址完整代码目标功能 开发一个comfyui的自定义节点,该节点的功能是:可以对comfyui工作流中最终输出的图像添加一些自定义文案,且可以指定文案在图像上的位置、文案的字体样式、字体大小、字体颜色等。最终效果如…

Go语言之GORM框架(三)——Hook(钩子)与Gorm的高级查询

Hook(钩子) 和我们在gin框架中讲解的Hook函数一样&#xff0c;我们也可以在定义Hook结构体&#xff0c;完成一些操作&#xff0c;相关接口声明如下&#xff1a; type CreateUser interface { //创建对象时使用的HookBeforeCreate() errorBeforeSave() errorAfterCreate() …

小识MFC,一套设计优雅与不优雅并存的类库----小话MFC(2)

Q1&#xff1a; CPoint继承于POINT&#xff0c;这样有什么好处&#xff1f; A&#xff1a; 继承的一个最基本的好处当然就是减少代码量。CPoint和POINT内部数据一样&#xff0c;只是一个提供了更多的方法来操作对象。 typedef struct tagPOINT {LONG x;LONG y; } POINT, *P…

ARM IHI0069F GIC architecture specification (7)

3.1 GIC逻辑组件 GICv3体系结构由一组逻辑组件组成&#xff1a; •Distributor。 •每个受支持的PE都有一个Redistributor。 •支持的每个PE都有一个CPU interface。 •中断翻译服务组件&#xff08;ITS&#xff09;&#xff0c;支持将事件翻译为LPI。 Distri…

APM2.8飞控

ArduPilotMega 主控可应用于 固定翼、直升机、多旋翼、地面车辆 APM2.8飞控供电有两种 1.电流计供电&#xff0c; 2.带BEC&#xff08;稳压功能&#xff09;的电调供电 ArduPilotMega 内部的硬件结构图&#xff1a; 调试时&#xff0c;不要使用向导&#xff0c;由于向导功能不…