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/framework

adb 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方法,其调用来源在这如下代码这。上面的这个拦截白名单的使用并没有跟我们的场景关联起来,而是在另一种场景,其调用的入口如下图的最后一行代码:

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

 最后,分享一款免费看热门电影和电视剧的app,仅限Android:

  • 13
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
### 回答1: 《Android应用安全实战:Frida协议分析》是一本介绍Frida工具的使用和Android应用安全分析的书籍。Frida是一个强大的动态分析工具,可以帮助开发人员和安全研究人员对应用进行动态分析。本书以Frida为基础,介绍了如何对一些常见的安全问题进行定位和修复。 本书主要分为三部分,第一部分介绍了Frida工具的安装和使用方法,包括如何在Windows、Mac和Ubuntu三个系统上安装Frida,以及如何使用Frida对应用进行动态分析和漏洞挖掘。第二部分介绍了一些常见的安全问题,如反调试、class tampering、hook、rpc等问题,并详细介绍了如何通过Frida对这些问题进行分析和修复。第三部分介绍了一些应用案例分析,以及如何通过Frida对应用中的加密算法、网络协议、第三方代码等进行分析。 本书的特点在于实战性强,作者通过大量的实例和案例,让读者能够更加深入地理解Frida工具的使用方法,并能够将所学知识应用到实际的项目中。同时,本书还提供了一些工具和脚本,方便读者能够更加快速地进行分析和修复工作。 总的来说,本书是一本对于安卓开发人员、移动安全研究人员和安全工程师来说非常有价值的工具书,无论是对于入门和提高都有很大的帮助。Frida工具的特点在于动态分析,能够帮助开发人员和安全工程师快速定位和修复常见的安全问题。而本书则是一个详细的实例教程,通过这份教程的学习,读者将能够掌握Frida工具的使用方法,并能够熟练地应用到实际的项目中。 ### 回答2: 《Android应用安全实战:Frida协议分析PDF》是一本针对移动应用安全的实战指南。这本书主要讲述了如何借助Frida这个强大的工具来进行移动应用的安全分析和漏洞挖掘。 Frida是一款可用于对移动应用进行实时动态分析的工具,它的优点在于可以轻松地hook任意函数和类,还可以在不用重新编译应用程序的情况下动态修改应用程序的行为。Frida的这些特性使得它成为了许多黑客和渗透测试人员使用的首选工具之一。 在《Android应用安全实战:Frida协议分析PDF》中,作者首先介绍了Frida工具的基本原理和使用方法,包括安装和配置Frida、使用Frida脚本、使用Frida进行hook等。接着,作者详细介绍了Android应用程序的各个组成部分和重要的安全机制,并给出了许多实例来演示如何通过Frida来绕过这些安全机制。 最后,作者还介绍了一些常用的Frida脚本和工具,比如Hooking SSLPinning脚本、Frida-Extract工具、在Android 8.0上使用Frida等。这些工具和脚本可以帮助读者更快更高效地进行移动应用的安全分析和漏洞挖掘。 总的来说,《Android应用安全实战:Frida协议分析PDF》是一本非常实用的书籍,对于渗透测试人员、黑客和移动应用开发人员来说都具有一定的参考价值。通过学习和掌握Frida这个工具,可以让我们更好地发现和修复移动应用程序中的安全问题,从而提升我们的移动应用程序的安全性和可靠性。 ### 回答3: 《Android应用安全实战:Frida协议分析》是一本关于安卓应用安全的实战教程。该书的重点在于介绍如何使用Frida协议进行应用程序的逆向分析,得出应用程序的安全漏洞,并给出相应的解决方案。 Frida是一个能够在运行时动态注入JavaScript并调试代码的工具。这也意味着Frida能够直接访问运行在内存中的应用程序。这个优势使Frida成为了一个强大的安卓应用程序分析和调试工具。通过使用Frida,用户可以对应用程序进行监视、修改、甚至是攻击。 《Android应用安全实战:Frida协议分析》详细介绍了Frida的使用方法,包括Frida的架构、基本操作、配置和调试应用程序等。此外,该书还介绍了有关安卓应用程序逆向工程和安全审计的实操技能。通过本书的学习,在安卓应用程序的开发过程中,读者可以掌握一定的安全知识和技能,从而提高应用程序的安全性,避免攻击和漏洞的发生。 总之,《Android应用安全实战:Frida协议分析》是一本非常实用、易懂的安卓应用程序安全入门教材。在阅读该书并掌握其中的技能后,用户可以应用这些技能进行应用程序的逆向分析和安全审计,从而达到提高安卓应用程序安全性的目的。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一个玩游戏的程序猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值