Android安全问题 抢先拦截短信

同上篇文章一样,这里只陈述结果,代码分析稍后给出

导读:本文叙述如何先于某些伪杀毒软件、病毒、常规软件获取到短信

众所周知,android系统在收到短信息的时候会发送广播,但是此广播是有序广播,也就是说:先接收到广播的人,如果心情不好,它就不会向后传递此广播,后面的人就不会知道有短信到来

这与无序广播不同,无序广播并不是真的没有顺序(只是似乎大家习惯这么叫而已),无序广播的接收者也是排队等待广播的,只不过是在传递过程中,大家必须遵守规则,一直把消息传递给最后一个人才可以

关于无序广播与静态接收器搭配的接收顺序,上一篇文章已经说的很清楚了

由于开机之后程序都没有开始运行,所以想自动运行必须要接收

现在我们看看程序启动之后的情况,我以大家关心的接收短消息为例

想要在程序中接收短信,就要接收如下广播

android.provider.Telephony.SMS_RECEIVED

系统把它作为有序广播进行发送,那么,谁第一个接收到短信将变得至关重要, 无论你是杀毒软件、伪杀毒软件、病毒还是普通程序

之前说过静态接收器的接收顺序

那么动态接收器和静态接收器相比呢?

如果是接收静态广播

答案是静态接收器优先级低于动态接收器,也就是说,无论多么高级别的静态接收器和多么低级别的动态接收器都接收同一广播,永远都是动态接收器先接收到!

动态接收器是在代码中设置的,所以,我们需要先启动程序,才能接收广播,这也是我们无法用它接收开机广播的原因

如果是接收动态广播

同优先级的,动态接收器先接收到广播,静态后接收到

同样的,动态接收器也可以设置优先级,高优先级的接收器会在低优先级的接收器之前接收到广播

那么,同样优先级的动态接收器,接收广播的顺序是怎样的呢?

幸好,他们的规则与静态接收器的规则不同

同样优先级的动态接收器,谁先注册到系统,谁就抢先接收到广播

上面虽然完全只是文字叙述,但我相信,大家也是看明白了的

下面总结一下,如何能保证自己的程序抢先于其他程序接收到短信

1.根据上一篇文章的做法,保证自己先于其他程序启动

2.启动第一个事情就要开启服务,动态注册广播,并把优先级设置为最高

代码实现也非常简单

一个接收器

private DynamicReceiver dynamicReceiver = new DynamicReceiver();
public class DynamicReceiver extends BroadcastReceiver {
    public void onReceive(Context context, Intent intent) {
        Log.e(SmsUtil.TAG, "dynamic receiver");
        String action = intent.getAction();
        if(SmsUtil.SMS_ACTION.equals(action)){
            context.startService(SmsUtil.getIntent(context, MainService.class, intent, "dynamic receiver"));
        }
    }
}

动态注册

public static final String SMS_ACTION = "android.provider.Telephony.SMS_RECEIVED";

IntentFilter intentFilter = new IntentFilter(SMS_ACTION);
intentFilter.setPriority(Integer.MAX_VALUE);
registerReceiver(dynamicReceiver, intentFilter);

最后总结一下,接收器接收广播的顺序

之前由于受之前记忆的影响,下了错误的结论,抱歉给大家带来了困扰

后来整理原理的时候,仔细阅读源码才发现,特此纠正一下

普适原则

同等优先级的动态接收器,先注册的先接收

同等优先级的静态接收器,接收广播的顺序与String[] java.io.File.list()顺序一致

ordered广播

假设有如下优先级的5个接收器

1.动态A(优先级=1)

2.动态B(优先级=2)

3.动态C(优先级=2)

4.静态D(优先级=1)

5.静态E(优先级=2)

并且B先于C注册

那么实际接收顺序应为

B C E A D

也就是说,如果静态接收器的优先级高于动态接收器的优先级,那么还是静态接收器先接收到广播(比如接收短信)

非ordered广播

动态接收器高优先级 > 动态接收器低优先级 > 静态接收器高优先级 > 静态接收器低优先级

结束之前说点题外话

有些广播,我们无法用静态接收器接收

比如ACTION_SCREEN_ON,当屏幕被点亮的时候系统发送此广播

如果你尝试在manifest中注册receiver来接收,那么会失败,这是为什么呢

我们来看看系统是如何发送此广播的

void com.android.server.PowerManagerService.initInThread()

void initInThread() {
    ……
    mScreenOnIntent = new Intent(Intent.ACTION_SCREEN_ON);
    mScreenOnIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
    mScreenOffIntent = new Intent(Intent.ACTION_SCREEN_OFF);
    mScreenOffIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
    ……
}

他们在Intent中都设置了Intent.FLAG_RECEIVER_REGISTERED_ONLY,所以,如果要接收,必须动态注册广播接收器

ACTION_SCREEN_OFF也是如此

(这段说明应该放的之前的android安全问题(三) 钓鱼程序 中,现在补上)

关于FLAG_RECEIVER_REGISTERED_ONLY的说明

public static final int  FLAG_RECEIVER_REGISTERED_ONLY

Added in API level 1

If set, when sending a broadcast only registered receivers will be called -- no BroadcastReceiver components will be launched.

Constant Value:  1073741824 (0x40000000)

在来看一个广播,ACTION_BATTERY_CHANGED

电池电量发生变化的时候,系统发送此广播

void com.android.server.BatteryService.sendIntent()

private final void sendIntent() {
    //  Pack up the values and broadcast them to everyone
    Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED);
    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
            | Intent.FLAG_RECEIVER_REPLACE_PENDING);
    ……
}

所以我们必须动态接收

时间: 2025-01-16 14:37:30

Android安全问题 抢先拦截短信的相关文章

Android安全问题 抢先接收广播 - 内因篇之广播接收器注册流程

导读:本文说明系统是如何注册动态广播以及静态广播,这里主要注意其注册的顺序 这篇文章主要是针对我前两篇文章 android安全问题  抢先开机启动 - 结果篇 android安全问题  抢先拦截短信 - 结果篇 之前只给出了结果,并没有给出代码分析,现在给出第一步分的分析 大家都知道,广播接收器分为动态注册和静态注册两种 静态接收,就是配置到manifest.xml文件中,PackageManagerService扫描后记录其信息…… 动态接收,就是从代码中注册,通过调用下面的方法实现 Inte

14.拦截短信

拦截短信,播放音乐(app系统的声音,也是这逻辑) /** * 拦截短信 * * @author Kevin * */ public class SmsReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Object[] objects = (Object[]) intent.getExtras().get("pdus"); for

Android安全问题 抢先接收广播 - 内因篇之广播发送流程

导读:本文说明系统发送广播的部分流程,如何利用Intent查找到对应接收器.我们依然只关注接收器的排序问题 这篇文章主要是针对我前两篇文章 android安全问题(四) 抢先开机启动 - 结果篇 android安全问题(五) 抢先拦截短信 - 结果篇 现在给出第二步分的分析 下面就来看看发送广播的流程 Context中的sendBroadCast函数的实现是在ContextImpl中,和发送广播相关的有如下六个函数 void android.app.ContextImpl.sendBroadca

Android之——拦截短信

转载请注明出处:http://blog.csdn.net/l1028386804/article/details/46994097 这里,向大家简单介绍通过BroadcastReceiver来拦截短信的方法 1.创建短信广播接收者SmsRecevier 这个类是BroadcastReceiver的子类,具体的拦截操作在这个类中实现,我在这里只是简单的介绍一下方法,把获取到的短信信息打印出来.具体的业务逻辑就要大家自己去实现了. 具体代码如下: package com.lyz.receiver;

Android 拦截短信

public class SMSMess extends BroadcastReceiver { @Override public void onReceive(Context arg0, Intent arg1) { Bundle b=arg1.getExtras(); if (b!=null){ //从data对象里获取所有的短信,并把每一条短信转成Object对象 Object[] pud_sms = (Object[])b.get("pdus"); //准备一个SmsMessa

手机卫士06_挂电话拦截短信,资产目录_来电去电_自定义吐司

1.1 反射调用系统隐藏api挂掉电话 Android 1.5之前可以通过 TelephonyManager,tm.endCall();//但是列表找不到 谷歌认为挂掉电话是危及手机根本功能的动作,所以隐藏了这个api 在1.5之后,要通过反射调用这一api才能实现 两个网站 ①www.greocide.com //搜索源码的网站 搜索TelephonyManager,查找版本最低的版本即可(越低越容易理解) 这个api被隐藏掉了,不能直接获取到TelephonyManager.对象. ②通过g

Android安全问题 抢先开机启动

导读:我们以如何抢先开机启动为例,来说明接收无序广播的静态广播接收器的接收顺序 (注意,文本只是陈述结果,所以叫结果篇,之后的文章再给出源码分析) 首先先说一下android中的广播和广播接收器 广播可以分为有序.无序和sticky共三种 广播接收器可以分为静态和动态两种 首先我们要明确两个问题1.接收无序广播的接收器接收到广播的顺序是有序的 2.接收无序广播的接收器也一样可以设置优先级的 这里主要说一下多个应用中的静态广播接收器(优先级都相同的情况下 )接收无序广播时的接收顺序 注意:这里主要

Android抢先截获短信(附源码)

之前在写通讯录应用时,将整体的代码写完后,自测时发现非常非常多的问题,其中一个非常重要严重的就是可以发出短信,但收不到任何的短信息,这搞的我好捉鸡啊!后来调试发现是由于没有收到短信的消息导致的,然后将自己手机中的QQ通讯录尝试着卸载掉,这时就可以收到了. 后来有时间了在网上查找相关资料,并且按照网上的理论编写了代码测试,解决了这个问题,在这里通过博客把解决的方法记录下来. 首先要知道广播分为无序,有序,sticky三种广播 无序广播应该最常用的,就是普通的广播,任何BroadcastReceiv

Android接收和发送短信

每一部手机都具有短信接收和发送功能,下面我们通过代码来实现接收和发送短信功能. 一.接收短信 1.创建内部广播接收器类,接收系统发出的短信广播 2.从获得的内容中解析出短信发送者和短信内容 3.在Activity中注册广播 4.添加接收短信权限 下面放上具体的代码 activity_main.xml文件用于显示短信发送者号码和显示短信内容 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout