上一篇部落格 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,
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsISO3EDMyUDNzIDNxYDM1EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
點選發送按鈕後,
通過Xposed Installer觀看背景日志資訊,如下:
工程源碼,下載下傳