基于xposed的短信拦截

来源:互联网 发布:信鸽血统软件 编辑:程序博客网 时间:2024/05/16 05:38

上一篇博客 Android操作系统MMS保护方案 已经详细地介绍了有关MMS的概念,并且从Android操作系统源码的角度分析了发送端与MMS相关的类,并且给出了相应的保护方案,这里给出该方案的具体实现方法。
经过上一篇博客的分析,已经知道,对于发送时的Client端,需要重点关注的类是com.android.mms.data包中的类WorkingMessage,该类用来管理当前正在编辑的消息,它从创建,草稿到发送完成后一直存在,只要打开了编辑信息的页面就会创建一个WorkingMessage,直到退出编辑页面。该类中封装了代表短信内容的属性和相关的处理方法,可以认为是framework层上最原始的短信产生的源头。 在Android系统MMS的client端,该类定义了一个标识短信内容的属性变量,通过调用send方法来实现短信的发送。


因此,要想实现从短信产生的源头进行拦截,可以考虑拦截WorkingMessage类的send方法,获取到其mText属性变量的内容,通过对该内容进行加密处理就可以实现对敏感短信信息的保护。其中,对于mText属性变量的获取,可以调用XposedHelpers的findField方法来实现,获取后将获取的内容整合成字节流的形式,通过对字节流的每一位的加密出来来实现加密。下面给出具体的编码思路。
Xposed框架的使用方法,在上一篇博客 Xposed框架 已经给出了详细的介绍。下面利用Xposed提供的jar文件,进行开发。注意,用Eclipse或者MyEclipse生成的Android工程文件,默认的库文件是放在libs文件夹下的,此时需要将libs文件夹修改为lib,否则Xposed框架会报一个无法访问的错误。本例子仅仅作为一个后台拦截的例子,不需要什么界面,因此直接定义核心类Hook.java即可。在AndroidManifest.xml文件中添加如下配置:

<!-- xposed支持 -->        <meta-data            android:name="xposedmodule"            android:value="true" />        <meta-data            android:name="xposedminversion"            android:value="30" />        <meta-data            android:name="xposeddescription"            android:value="拦截WorkingMessage的send方法进行加密" />

该配置放在application的节点下,与activity同级;
同时,在assets文件夹下定义访问入口xposed_init文件,内容书写为核心hook类的存放路径。
核心hook类Hook.java实现如下:

package com.example.xposed_time02;import java.lang.reflect.Field;import android.text.SpannableStringBuilder;import de.robv.android.xposed.IXposedHookLoadPackage;import de.robv.android.xposed.XC_MethodHook;import de.robv.android.xposed.XposedBridge;import de.robv.android.xposed.XposedHelpers;import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam;/** * @author Li Jiansong * @date:2015-5-9  下午8:39:33 * @version : * */public class Hooker implements IXposedHookLoadPackage{    private static final String PNAME="com.android.mms";    @Override    public void handleLoadPackage(LoadPackageParam lpparam) throws Throwable {        // TODO Auto-generated method stub        if(!lpparam.packageName.equals(PNAME)){            //XposedBridge.log("无法找到"+PNAME);            return ;        }        XposedBridge.log("----------目前在包com.android.mms.data中------------");        final Class<?> clazz=XposedHelpers.findClass(                "com.android.mms.data.WorkingMessage", lpparam.classLoader);        XposedHelpers.findAndHookMethod(clazz, "send", String.class,                new XC_MethodHook(){            @Override            protected void beforeHookedMethod(MethodHookParam param)                    throws Throwable {                // TODO Auto-generated method stub                //super.beforeHookedMethod(param);                XposedBridge.log("----开始拦截send方法-------");                Field f=XposedHelpers.findField(clazz, "mText");                SpannableStringBuilder text=(SpannableStringBuilder) f.get(param.thisObject);                String origMsg=text.toString();                //简单加密运算                char array[]=origMsg.toCharArray();//获取字符数组                for(int i=0;i<array.length;i++){                    array[i]=(char) (array[i]^20000);//对每个数组元素进行异或运算                }                String secretMsg=new String(array);                f.set(param.thisObject,"原始短信内容:"+origMsg+"\n"+"加密后内容:"+secretMsg);                XposedBridge.log("------成功拦截send方法并进行加密------");            }        });    }}

注:这里主要利用XposedHelpers的findField方法来获取mText的内容,用到了java的反射机制,加密的方法也很简单,没用到什么高端的加密算法,只是将获取的内容整合成字节流的形式,通过对字节流的每一位与20000进行异或运算,加密过程比较简单。对于商业级别的保护,可以采用一些高级的加密算法,将加密模块单独作为一个模块分离出去即可。
安装后,在Xposed Installer中激活该模块并重启手机,测试如下:
随意编辑一段短信内容发给10086,
这里写图片描述
点击发送按钮后,
这里写图片描述
通过Xposed Installer观看后台日志信息,如下:
这里写图片描述
工程源码,下载

1 0