Xposed实现短信拦截

最近在玩Xposed,然后刚好要实现个功能,收到短信的时候自动将短信的内容打印到log中,其实也算是短信拦截的一种了。然后做的时候遇见了一点坑,就写一下记录下来,当时做的时候参考了这个博客的内容。写的也很清楚,包括发短信的原理啥的,但是真正做的时候有点小问题,也研究了一下,这里就改编了一些,顺便说一下自己的一些理解。

Hook包名

啥也不说,先上代码。

import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam;


public class HookManager implements IXposedHookLoadPackage {

   // private static final String SMSPACKAGENAME = "com.google.android.talk";
    private static final String SMSPACKAGENAME = "com.android.mms"


    public void handleLoadPackage(LoadPackageParam lpparam) throws Throwable {


        if (lpparam.appInfo != null && lpparam.isFirstApplication
                && (SMSPACKAGENAME.equals(lpparam.packageName)))
        {
            XposedBridge.log("Loaded App:" + lpparam.packageName);
            Logger.log("Loaded App:" + lpparam.packageName);
            HookSmsMessage.GetHookSmsMessage(lpparam);
        }
    }
}

这段代码只是先获取包名,有一点需要注意的是那个注释的地方,并不是没用的,在参考的那篇博客中,要hook的包名是“com.android.mms”,但是经过测试,原生的nexus手机接收短信的包并不是这个包,仔细一看,原生手机有个接收短信的应用叫“环聊”,查了一下,这个包实际为“com.google.andriod.talk”,也就是注释掉的那句话。也就是说,如果用普通手机去hook的话,用com.android.mms,但是如果用原生手机去hook的话,就要把注释放开了,换成com.google.andriod.talk

Hook类和方法

还是先放代码



import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.callbacks.XC_LoadPackage;
import static de.robv.android.xposed.XposedHelpers.findAndHookMethod;

public class HookSmsMessage {


    private static final String class_name = "com.android.internal.telephony.gsm.SmsMessage$PduParser";

    public static void GetHookSmsMessage(XC_LoadPackage.LoadPackageParam lpparam) {


        findAndHookMethod(class_name, lpparam.classLoader, "getUserDataUCS2", int.class, new XC_MethodHook() {

            protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                Logger.log("beforeHookedMethod");
                // this will be called before the clock was updated by the original method
            }

            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                // this will be called after the clock was updated by the original method
                try {
                    String message = param.getResult().toString();
                    Logger.log("the message is : " + message);
                    //新增其他操作
                } catch (Exception e) {
                    XposedBridge.log(e);
                }
            }
        });
    }
 }

代码也很清楚,那篇参考的博客说的也很清楚,这里是接收短信的时候系统会调用com.android.internal.telephony.gsm.SmsMessage$PduParser类中的getUserDataUCS2方法,然后在这个方法执行后进行hook,我这里的操作是log打印,当然有其他的操作也可以在这里加上。这段代码在原生手机nexus上实测有效,同时在普通的手机上测试也有效,当然有一个出现问题的地方,也是走过的比较坑的地方,下面就来说一下。

双卡接收短信

这里在测试的时候发现了一个问题,当时笔者使用的是中兴的一个电信定制的手机双卡的手机进行测试的,发现当插入移动卡的时候这个拦截短信的程序好使,而插入电信卡的时候,这个程序并不好使,同时xposed的日志显示找不到这个方法(Not Fount Method)。

然后经过查找一些资料,发现那个插卡的卡槽,有一个下面写着gsm,这个卡是移动(联通没测过,应该也行)可以使用的,而这个时候,看一下我们的代码,我们hook的类名刚好叫gsm.SmsMessage,所以很明显,这个类是专门给gsm用的。

然后另一个卡槽,只能电信卡用,下面写着cdma,所以自然,我们要找的包肯定是关于cdma的包,这里笔者找的了一个包叫com.android.internal.telephony.cdma.SmsMessage,这个就是cdma卡进行接收短信的包了。这里贴一下cdma包的API源码。看一下果然发现没有getUserDataUCS2这样的方法了,当然xposed会报错找不到该方法。至于cdma卡hook的时候是什么方法,笔者也没有继续做下去,刚刚上面把cdma源码链接附上去了,有兴趣的小伙伴可以自己研究一下,当然成功的话可以在下面留言告诉我一下:-)

总结

xposed的短信拦截要注意手机的机型,有些深度定制的机型会改掉一些包名或者方法名,其次要注意双卡和单卡的问题,尤其是电信的卡。差不多就酱~o~

你可能感兴趣的:(Xposed)