论坛首页 移动开发技术论坛

浅谈短、信彩信的拦截

浏览 2442 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2013-04-08  

 

关于Android平台上短、彩信的拦截,网上已经有不少介绍性的文章。那些文章大多是介绍具体的实现方法,其提供的方法并不一定能够成功拦截。今天我们就来详深入地介绍一下拦截短、彩信的内部原理,并分析一下拦截方法的优劣。

Android接收短、彩信的原理

正常的短信在到达手机后,根据不同的制式GSMCDMA被解析并封装成SmsMessage对象该对象会被SMSDispatcher进一步解析并分发。系统会将短信的formatpdu放到actionandroid.provider.Telephony.SMS_RECEIVEDIntent之后系统会将Intent以有序广播Orderd Broadcast的形式发出去。监听这两个广播的app收到广播后,通过对pdu的解析,就可以得到短信的具体内容。

彩信的情况与短信类似,只不过运营商首先会发一条WapPush短信。这类短信不包含彩信的具体内容,而是包含一条指向真实内容的URL地址。系统会将WapPush短信解析,提取“pduTypeheaderpduformat等信息放到actionandroid.provider.Telephony.WAP_PUSH_RECEIVEDIntent中。同样,系统会以有序广播的形式将Intent发出去。收到广播的appintent解析,并提取其中的URL。之后访问该URL地址并下载实际的彩信内容。

有序广播的原理

经过以上的分析,拦截短、彩信的关键就是拦截action为“android.provider.Telephony.SMS_RECEIVED”和“android.provider.Telephony.WAP_PUSH_RECEIVED”的广播。由于该广播是有序广播,所有Receiver 是按照顺序接受广播的。先收到广播的Receiver有权利终止该广播的传播。因此只要一个Receiver能够第一个收到广播并终止继续传播,那么就可以实现短、彩信的拦截。

这里简单介绍一下有序广播的传播方式。BroadcastReceiver 有静态和动态两种方式注册。

1.      静态注册:

静态注册是指在AndroidManifest.xml 中注册。方法如下:

 

 <receiver android:name=“.XXXMessageReceiver”>

            <intent-filter android:priority=“1000”>

                <action android:name=“android.provider.Telephony.SMS_RECEIVED” />

            </intent-filter>

        </receiver>

 

2.      动态注册:

     动态注册是通过调用Context类的register方法来注册。方法如下:

 

     registerReceiver(BroadcastReceiver receiver,

                                            IntentFilter filter);

     registerReceiver(BroadcastReceiver receiver,

                                            IntentFilter filter,

                                            String broadcastPermission,

                                            Handler scheduler);

 

注意,动态注册Receiver 的优先级是通过IntentFilter.setPriority(int)方法来设置的。当一个广播发生时,系统会将静态和动态的Receiver 按优先级(priority)进行排序,优先级越高越早处理。对于优先级相同的Receiver ,先处理动态的。

第三方解决方案

网上的通常解决方案是采用静态注册的方式注册BroadcastReceiver ,并设置一个较高的优先级,例如,10009999等。经过以上对于广播原理的分析,可以看出,这种方式其实并不能够保证接受者会第一时间被触发。比较好的实现方法需要注意两点:

1.      采用动态方式而非静态方式注册。监听系统开机广播,系统启动之后采用动态方式注册BroadcastReceiver 。这样可以保证在第一时间将需要的BroadcastReceiver注册成功;

2.      并将优先级设为最高。注意,系统的最高优先级不是网上所说的10009999,而是2147483647。这是int类型能够表示的最大数值。

做到这两点可以大大增加拦截的成功率。由于第三方app本身的局限性,即使采用优化过的方法,第三方app还是不能够保证拦截的成功率。例如,如果有两个app都采用动态注册的方式,都设置其优先级为最高。那么其中一个就会被另一个拦截。

系统级拦截方案

拦截短、彩信的根本方法还是需要在系统层面来解决。需要在系统提供一个专用的Service(类似于ActivityManagerServicePackageManagerService),用于判断收到的短信是否需要拦截。接口如下:

 

boolean needToBlockMsg(Intent intent)

 

系统在收到短信后,将短信内容组装到需要广播的Intent中。然后调用该接口判断是否需要拦截。如果需要拦截,则抛弃该短信,或者将其保存到特定的数据库中;如果不需要拦截,那么就照常发送广播。这样可以一劳永逸地解决短、彩信的拦截问题。

由于需要修改“/system/framework/framework.jar”之类的系统文件,第三方app是无法实现的,因此需要设备生产厂商的支持。

 

更多内容请关注http://blog.sina.com.cn/u/3194858670以及sina微博@安卓安全小分队

论坛首页 移动开发技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics