天天看點

基于xposed的短信攔截

上一篇部落格 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=;i<array.length;i++){
                    array[i]=(char) (array[i]^);//對每個數組元素進行異或運算
                }
                String secretMsg=new String(array);
                f.set(param.thisObject,"原始短信内容:"+origMsg+"\n"+"加密後内容:"+secretMsg);
                XposedBridge.log("------成功攔截send方法并進行加密------");
            }
        });
    }
}
           

注:這裡主要利用XposedHelpers的findField方法來擷取mText的内容,用到了java的反射機制,加密的方法也很簡單,沒用到什麼高端的加密算法,隻是将擷取的内容整合成位元組流的形式,通過對位元組流的每一位與20000進行異或運算,加密過程比較簡單。對于商業級别的保護,可以采用一些進階的加密算法,将加密子產品單獨作為一個子產品分離出去即可。

安裝後,在Xposed Installer中激活該子產品并重新開機手機,測試如下:

随意編輯一段短信内容發給10086,

基于xposed的短信攔截

點選發送按鈕後,

基于xposed的短信攔截

通過Xposed Installer觀看背景日志資訊,如下:

基于xposed的短信攔截

工程源碼,下載下傳