Android逆向实战 - MIUI调起三方应用系统拦截弹窗分析

本文主要是介绍Android逆向实战 - MIUI调起三方应用系统拦截弹窗分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

    近期,发现在部分Android手机调起其他应用时,会弹出一个系统弹窗拦截调起,需要用户二次确认。经过内部众测,发现绝大多数是小米手机,而且跟Android版本没有直接关系,猜测是MIUI某次升级引入的功能。这篇文章,我们从MIUI系统源码分析下该弹窗。

    我有一系列Android逆向相关的文章,这是我今年六月份关于反编译腾讯新闻去开屏广告的逆向实战文章,也欢迎大家阅读:

Android逆向实战 - 腾讯新闻去开屏广告_apktool去广告_一个玩游戏的程序猿的博客-CSDN博客文章浏览阅读2.3k次,点赞6次,收藏17次。上次反编译一个工具类app去广告失败,原因是使用了360加固,回编译后无法启动。一般来讲,大厂的app考虑到性能、兼容性、包体积等,通常不用加固。因此,本次我们选一个大一些的app-腾讯新闻。写在前面:本篇博客仅用来研究和学习。如有侵权,请联系我删除,谢谢。_apktool去广告https://blog.csdn.net/qq_21154101/article/details/130409016?spm=1001.2014.3001.5501

目录

一、背景

二、确定弹窗来源

三、反编译手机管家

四、framework代码分析 

1、获取framework

2、miui-services.jar分析

3、miui-framework.jar分析

五、疑似拦截白名单


一、背景

    最近,发现手机在调起淘宝或京东时,有时会弹窗让二次确认。尤其是双11期间,各大厂商app都在疯狂投放阿里、京东等电商app的广告。跟往年大家吐槽一不小心就跳到其他app不一样,今年我们发现很多手机会进行拦截,尤其是小米手机。在这里给小米点个赞,我也是忠实的小米用户。现象如下图:

二、确定弹窗来源

    当弹出该弹窗时,通过mCurrentFocus去确定来源:

adb shell
dumpsys window|grep Focus

    如下: 

mCurrentFocus=Window{c16c09e u0 com.miui.securitycenter/com.miui.wakepath.ui.ConfirmStartActivity}mFocusedApp=ActivityRecord{83602ab u0 com.miui.securitycenter/com.miui.wakepath.ui.ConfirmStartActivity} t5345}mPreferredTopFocusableRootTask=Task{5d40ca1 #5345 type=standard A=1000:com.miui.wakepath.ui.ConfirmStartActivit U=0 visible=true visibleRequested=true mode=fullscreen translucent=true sz=1}mLastFocusedRootTask=Task{5d40ca1 #5345 type=standard A=1000:com.miui.wakepath.ui.ConfirmStartActivit U=0 visible=true visibleRequested=true mode=fullscreen translucent=true sz=1}mFocusedWindow=Window{c16c09e u0 com.miui.securitycenter/com.miui.wakepath.ui.ConfirmStartActivity}mTopFocusedDisplayId=0

    可以发现,弹窗来源于com.miui.securitycenter/com.miui.wakepath.ui.ConfirmStartActivity,securitycenter也就是小米手机的手机管家。 

三、反编译手机管家

    下载手机管家app,反编译。在这里我用的最新的版本(v8.6.2.231116,也就是2023年11月16号的版本)。反编译的步骤在这不细说了,反编译后,搜索ConfirmStartActivity:

     

    看到如下代码: 

    第一部分代码是从intent中获取调起app的pkgname和被调起app的pkgname以及UserId等其他信息,这些信息获取后,在r0这个判断中有用到。看下r0这个方法,就是拿上面拿到的包名和UserId等做了一系列的判断:

 private boolean r0() {PackageInfo n10;PackageInfo n11;if (Build.VERSION.SDK_INT <= 33) {return false;}boolean z10 = false;for (UserHandle userHandle : ((UserManager) getSystemService("user")).getUserProfiles()) {if (userHandle.hashCode() == this.f18556g) {z10 = true;}}if (z10) {Object d10 = sf.e.d(f18552n, this, "getLaunchedFromUid", null, new Object[0]);return !(d10 == null || p1.b(((Integer) d10).intValue()) == this.f18557h) || (n10 = x0.n(this.mAppContext, this.f18554e)) == null || p1.b(n10.applicationInfo.uid) != p1.b(this.f18557h) || (n11 = x0.n(this.mAppContext, this.f18555f)) == null || p1.b(n11.applicationInfo.uid) != p1.b(this.f18558i) || this.f18553d == null;}return true;}

    在AndroidManifest文件中看,该Activity的配置了一个ACTION:CHECK_ALLOW_START_ACTIVITY,顾名思义:检验是否允许启动Activity。

   

    继续看,看到了弹窗的方法i0,而且其两个按钮文案的命名是"deny"和"accept",因此高度怀疑就是dp调起拦截弹窗代码:

    但是该弹窗代码只是构建弹窗的部分UI,并没有在ConfirmStartActivity中看到其调用的地方,看下其父类,发现在父类AlertActivity的onCreate中调用了i0方法: 

    而l0方法中调用了dialog.show(),该方法是在子类ConfirmStartActivity中k0调用的,k0又是在父类如上的onCreate方法最后调用的:

    也就是说,弹窗是在ConfirmStartActivity的onCreate中展现的。如果f10185c这个变量是true,那就return不出弹窗。f10185c这个变量在哪赋值的呢?又是在ConfirmStartActivity的j0里面赋值的,大家可以往上翻一下j0的代码。

四、framework代码分析 

1、获取framework

    通过公司内部众测我们发现,该弹窗只有在MIUI才有,目前没发现是MIUI的哪个版本有的,现在是猜测需要MIUI版本 > XXX并且手机管家版本大于XXX,二者缺一不可。

    我们看下framework的代码,在这里把framework和system_ext下的framework代码一并pull下来:

adb pull /system/frameworkadb pull /system/system_ext/framework

    MIUI系统,system_ext下的framework代码主要是小米自己魔改的framework,比较经典的就是miui-framework.jar和miui-services.jar:

2、miui-services.jar分析

    直接反编译miui-services.jar,搜索ConfirmStartActivity:

    打开ConfirmStartHelper类看下,这里并没有看到启动ConfirmStartActivity的入口代码,但是看到了在isAllowStartCurrentActivity方法中用到手机管家,ACTION和ConfirmStartActivity包名类名进行判断的逻辑:

    isAllowStartCurrentActivity方法比较清晰:

  • 如果Uid不是1000才需要进行相关的判断,否则直接放行。1000代表的是MIUI系统应用(也就是MIUI对自己的应用默认开后门
  • 如果不是系统应用,判断Action是CONFIRM_START_ACTIVITY_ACTION,return false,不放行。
  • Intent的来源是手机管家并且Activity是ConfirmStartActivity,那就直接return false,不放行。

    可以看到,在miui-services.jar包中,相关的逻辑也就到此为止了。再搜索isAllowStartCurrentActivity也看不到更多的信息。因此,更多的逻辑可能还是在其他的framework代码里。(注意:以下篇幅也是经常在miui-services.jar和miui-framework.jar来回折腾

3、miui-framework.jar分析

    反编译miui-framework.jar,搜索CHECK_ALLOW_START_ACTIVITY:

    MiuiIntent中定义了Intent的一些Action,在这里不截图分析。看SecurityManager类中的调用,主要就在getCheckStartActivityIntent这个方法。这个方法比较长,第一部分是通过Action是PICK还是SEND来做挑选图库图片还是发送图片的判断,然后通过buildStartIntent方法去构建Intent:

 

    第二部分则是我们调研的场景:

规则大致如下:

  • 如果被调起的app已经启动,则return null,也就是不进行拦截。
  • 如果调起者为系统app(uid<10000)并且 IFAAFaceManager.ERR_FACE_LOCKED!=0,放行。
  • 如果调起者不为系统app(uid>=10000),但是被调起者为系统app并且 IFAAFaceManager.ERR_FACE_LOCKED!=0,放行。
  • 如果调起者与被调起者同包名,放行。
  • 否则,通过checkAllowStartActivity方法判断,判断通过放行。

 

    mService是SecurityManager的一个变量,可以看到是ISecurityManager,我们看下这个接口,这接口里面有两个实现类Proxy和Stub(这里就是用的代理模式),二者都继承了Binder,并且实现了ISecurityManager接口: 

    我们知道Binder是用来跨进程通信的,在这里简单说下Binder通信机制: 

(1)服务端创建对应Binder实例对象,接收来自客户端的请求,同时,将自身的Binder注册到ServiceManager。

(2)Binder驱动中创建对应mRemote对象。

(3)客户端想和服务端通信,通过ServiceManager查找到服务端的Binder,然后Binder驱动将对应的mRemote对象返回,至此已经建立完通信。

(4)在建立完毕通信之后,客户端通过调用mRemote对象的transact()方法,将数据发送到服务端,然后挂起自己等待回复。服务端收到数据后在onTransact()方法进行处理后将结果返回给客户端,客户端收到数据,重新拉起线程,至此进程间通信完毕。

    继续看下去Proxy类中checkAllowStartActivity的实现:

    看Stub类的实现:

    上面我们也提到了,Stub继承了Binder,该调用是在onTransact方法中:

     所以,以上代码简单整理一下:

(1)客户端在_data写入了调起者和被调起者的包名、uid等信息,这些信息通过mRemote对象的transact()方法传递给服务端

(2)服务端处理后返回给客户端,客户端通过_replay.readBoolean去获取判断结果,决定是否放行。

五、疑似拦截白名单

    Stub是一个抽象类,其实现类SecurityManagerService在miui-services.jar中。这个类里面有个AccessController对象,看其作用,其中有几个方法例如filterIntentLocked,skipActivity等:

 

     进一步看checkAccessControlPassLockedCore方法的调用链,可以看到是如下两个方法:

    我们进一步看AccessController这个类,看到了疑似拦截的白名单代码。首先,有一套本地写死的白名单,如下:

    其次,还提供了服务端更新白名单的逻辑: 

    看下mSkipList的使用,在filterIntentLocked方法中,主要就是判断packageName是否在白名单中: 

     咱们一开始其实是根据Intent的Action - CHECK_ALLOW_START_ACTIVITY来跟踪的,定位到了getCheckStartActivityIntent方法,其调用来源在这如下代码这。上面的这个拦截白名单的使用并没有跟我们的场景关联起来,而是在另一种场景,其调用的入口如下图的最后一行代码:

    因此,该白名单大概率不是调起三方应用的那个场景,而是其他的场景。 试想一下,针对调起三方应用弹窗的场景:如果小米对支付宝加白放行,没对微信或抖音放行,那么不会引起公愤吗?所以,我认为这必然不是该场景。

这篇关于Android逆向实战 - MIUI调起三方应用系统拦截弹窗分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/425331

相关文章

网页解析 lxml 库--实战

lxml库使用流程 lxml 是 Python 的第三方解析库,完全使用 Python 语言编写,它对 XPath表达式提供了良好的支 持,因此能够了高效地解析 HTML/XML 文档。本节讲解如何通过 lxml 库解析 HTML 文档。 pip install lxml lxm| 库提供了一个 etree 模块,该模块专门用来解析 HTML/XML 文档,下面来介绍一下 lxml 库

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

中文分词jieba库的使用与实景应用(一)

知识星球:https://articles.zsxq.com/id_fxvgc803qmr2.html 目录 一.定义: 精确模式(默认模式): 全模式: 搜索引擎模式: paddle 模式(基于深度学习的分词模式): 二 自定义词典 三.文本解析   调整词出现的频率 四. 关键词提取 A. 基于TF-IDF算法的关键词提取 B. 基于TextRank算法的关键词提取

基于人工智能的图像分类系统

目录 引言项目背景环境准备 硬件要求软件安装与配置系统设计 系统架构关键技术代码示例 数据预处理模型训练模型预测应用场景结论 1. 引言 图像分类是计算机视觉中的一个重要任务,目标是自动识别图像中的对象类别。通过卷积神经网络(CNN)等深度学习技术,我们可以构建高效的图像分类系统,广泛应用于自动驾驶、医疗影像诊断、监控分析等领域。本文将介绍如何构建一个基于人工智能的图像分类系统,包括环境

水位雨量在线监测系统概述及应用介绍

在当今社会,随着科技的飞速发展,各种智能监测系统已成为保障公共安全、促进资源管理和环境保护的重要工具。其中,水位雨量在线监测系统作为自然灾害预警、水资源管理及水利工程运行的关键技术,其重要性不言而喻。 一、水位雨量在线监测系统的基本原理 水位雨量在线监测系统主要由数据采集单元、数据传输网络、数据处理中心及用户终端四大部分构成,形成了一个完整的闭环系统。 数据采集单元:这是系统的“眼睛”,

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

hdu1394(线段树点更新的应用)

题意:求一个序列经过一定的操作得到的序列的最小逆序数 这题会用到逆序数的一个性质,在0到n-1这些数字组成的乱序排列,将第一个数字A移到最后一位,得到的逆序数为res-a+(n-a-1) 知道上面的知识点后,可以用暴力来解 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#in

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听