玩转Xposed

版权声明:本文为博主原创文章,未经博主允许不得转载!

1.啥是xposed

额,这篇文章主要是讲解如何使用xposed的,并没有对xposed的二次开发或自己整个xposed这种大神级框架。
那么啥是xposed的呢?自己google一下。。。


2.玩转xposed

1.禁止三方应用发送短信、彩信等

先来个简单的例子,这也是我第一次用xposed时写出来的代码,基于项目是公司的,所以只留简单的框架代码。

 //劫持应用发送短信 彩信   add by hxk
        //短短信
        Class clsIccSmsInterfaceManager = null;
        try {
            clsIccSmsInterfaceManager = Class.forName("com.android.internal.telephony.IccSmsInterfaceManager");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        XposedHelpers.findAndHookMethod(clsIccSmsInterfaceManager, "sendTextInternal",
                String.class,
                String.class,
                String.class,
                String.class,
                PendingIntent.class,
                PendingIntent.class,
                boolean.class,
                new SendTextInternal());


        //长短信
        XposedHelpers.findAndHookMethod(clsIccSmsInterfaceManager, "sendMultipartText",
                String.class,
                String.class,
                String.class,
                List.class,
                List.class,
                List.class,
                boolean.class,
                new SendMultipartText());

        XposedHelpers.findAndHookMethod(clsIccSmsInterfaceManager, "sendDataInternal",
                String.class,
                String.class,
                String.class,
                int.class,
                byte[].class,
                PendingIntent.class,
                PendingIntent.class,
                new SendDataInternal());

        //彩信
        Class smsManager = null;
        try {
            smsManager = Class.forName("android.telephony.SmsManager");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        XposedHelpers.findAndHookMethod(smsManager, "sendMultimediaMessage",
                Context.class,
                Uri.class,
                String.class,
                Bundle.class,
                PendingIntent.class,
                new SendMultimediaMessage());

SendDataInternal

public class SendDataInternal extends XC_MethodHook {
    public static String TAG = "pervent";

    @Override
    protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
        Log.e(TAG,"childeenmode:"+ChildrenModeTool.getChildrenMode());
        //开启儿童模式
        if (ChildrenModeTool.getChildrenMode()) {
            Log.d(TAG, " SendDataInternal param:" + param.getResult());
            param.setResult(null);
            Log.d(TAG, "SendDataInternal param1:" + param.getResult());
        }
    }

    @Override
    protected void afterHookedMethod(MethodHookParam param) throws Throwable {

    }

}

SendMultimediaMessage

public class SendMultimediaMessage extends XC_MethodHook {

    @Override
    protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
        if (ChildrenModeTool.getChildrenMode()) {
            Log.d("prevent","SendMultimediaMessage.param is null");
            param.args[2] = "";
        }

    }

    @Override
    protected void afterHookedMethod(MethodHookParam param) throws Throwable {

    }
}

SendMultipartText

public class SendMultipartText extends XC_MethodHook {
    public static String TAG = "pervent";

    @Override
    protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
        if (ChildrenModeTool.getChildrenMode()) {
            Log.d(TAG, " SendMultipartText param:" + param.getResult());
            param.setResult(null);
            Log.d(TAG, "SendMultipartText param1:" + param.getResult());
        }
    }

    @Override
    protected void afterHookedMethod(MethodHookParam param) throws Throwable {

    }

}

SendTextInternal

public class SendTextInternal extends XC_MethodHook {
    public static String TAG = "pervent";

    @Override
    protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
        if (ChildrenModeTool.getChildrenMode()) {
            Log.d(TAG, " SendTextInternal param:" + param.getResult());
            param.setResult(null);
            Log.d(TAG, "SendTextInternal param1:" + param.getResult());
        }
    }

    @Override
    protected void afterHookedMethod(MethodHookParam param) throws Throwable {

    }

}

额,乍一看咋这么简单呢,在儿童模式下,三方应用在也发不了短信,彩信以及一些data数据了,那么我们需要注意的就是三方应用发送短信的流程,就能轻松hook了(说笑的,hook一定要注意,一不小心,就把系统里一些进程给搞死了)。

2.Hook URL(拦截扣费,三方应用广告等)

通过xposed劫持url等,譬如转到自己指定的网址上,咳咳,我是不是说了不该说的东西了啊(坏笑)。咳咳,当然,也可以抓包支付宝、微信等常用支付网站的链接,加入黑名单,禁止扣费啥的,或者把微信支付、支付宝支付的启动页给拦截了(捂脸笑)!

    public void after(MethodHookParam param) {

        if (Methods.Application_attach.equals(method)) {
            context = (Application) param.thisObject;

            HookManager.getInstance().hookMethod(URL.class, "openConnection",
                    new HttpUrlConHandler(context, Methods.URL_openConnection, packageName));

            HookManager.getInstance().hookMethod(DefaultRequestDirector.class, "execute",
                    HttpHost.class, HttpRequest.class, HttpContext.class,
                    new HttpClientHandler(context, Methods.DefaultRequestDirector_execute, packageName));

            HookManager.getInstance().hookMethod(WebView.class, "loadUrl", String.class,
                    new WebViewHandler(context, Methods.WebView_loadUrl, packageName));
            HookManager.getInstance().hookMethod(WebView.class, "loadUrl", String.class, Map.class,
                    new WebViewHandler(context, Methods.WebView_loadUrl, packageName));
            HookManager.getInstance().hookMethod(WebView.class, "loadData", String.class, String.class, String.class,
                    new WebViewHandler(context, Methods.WebView_loadUrl, packageName));
            HookManager.getInstance().hookMethod(WebView.class, "loadDataWithBaseURL", String.class, String.class, String.class, String.class, String.class,
                    new WebViewHandler(context, Methods.WebView_loadUrl, packageName));

        }


    }

3.Activity的一些hook

最近腾讯的王者荣耀那么火,小编自己也控制不住,动不动就撸一局,小撸怡情,大撸伤身啊,一怒之下,把这款游戏的启动给禁了,点击桌面或其他调用时,把启动给截止了,让用户无法进入王者荣耀。下面来实现下禁止王者荣耀的启动,点击launcher的王者荣耀桌面图标时,弹出个禁止该应用启动Toast,咳咳(我后来换了ipad来玩了),这里只做一个简单的处理,想加其他实现细节的话可以自己扩展,例如应用加密,手机使用时控等都可以基于这个例子来拓展,废话少说,撸代码。

        Unhook unhook9 = XposedHelpers.findAndHookMethod("android.app.Instrumentation", Thread.currentThread().getContextClassLoader(),
                "execStartActivity", Context.class, IBinder.class, IBinder.class, Activity.class, Intent.class,
                int.class, Bundle.class, new XC_MethodHook() {

                    @Override
                    protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                        // Log.v(TAG, "Apps -- execStartActivity ..");
                        Context mContext = (Context) param.args[0];
                        Activity activity = (Activity) param.args[3];
                        Intent intent = (Intent) param.args[4];
                        hookExecStartActivity(param, mContext, activity, intent, "execStartActivity");
                    }
                });
        mUnhookList.add(unhook9);

hookExecStartActivity方法


    private synchronized static void hookExecStartActivity(XC_MethodHook.MethodHookParam param, Context who, Activity target, Intent intent, String tag) {
        if (who == null) {
            Log.e(Constant.LOGTAG, "execStartActivity, who context is null !");
            return;
        }

        String execStartPackageName = null;
        Context applicationContext = who.getApplicationContext();
        if (applicationContext == null) {
            applicationContext = who;
        }
        //添加个条件执行,例如在xx条件下,true只是一个展示
        if (true) {
            execStartPackageName = HookUtils.getExecStartPackageName(who, target, intent, tag);
            if (execStartPackageName != null) {
            //实际中这里应该从网络接口和数据库中获取
                if (execStartPackageName.equals("com.tencent.tmgp.sgame")) {
                    Toast.makeText(who, "还玩!被禁止了", Toast.LENGTH_SHORT).show();
                    //截断操作
                    param.setResult(null);
                    return;
                }

            }
            return;
        }


    }

HookUtils.java

/**
 * @author hxk 
*/
public class HookUtils { private static final String TAG = "HookUtils"; /** * 获取包名 * @param who * @param target * @param intent * @param tag * @return */ static String getExecStartPackageName(Context who, Activity target, Intent intent, String tag) { String execStartPackageName = null; do { if (intent != null) { if (intent.getComponent() != null) { execStartPackageName = intent.getComponent().getPackageName(); // Log.d(TAG, "1 intent.getComponent().getPackageName()."); break; } PackageManager pm = who.getPackageManager(); ResolveInfo info = pm.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY); if (info != null) { execStartPackageName = info.activityInfo.packageName; // Log.d(TAG, "2 pm.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY)."); break; } } if (target != null && target.getPackageName() != null) { execStartPackageName = target.getPackageName(); // Log.d(TAG, "3 target.getPackageName()."); break; } Log.e(TAG, tag + ", target activity or intent is null !!!"); } while (false); if (execStartPackageName == null) { Log.e(TAG, tag + ", execStartPackageName is null !!!"); return null; } else { Log.d(TAG, tag + ", execStartPackageName: " + execStartPackageName); } return execStartPackageName; } }

好了,这样在点击桌面上的王者荣耀时候,就会弹出”还玩!被禁止了”了,也进不去玩游戏了。(捂脸笑)。
是不是好简单?自己单独想的话,没人稍微指点下的话,想起来还是有点脑袋大的。这里需要注意的是Activity的启动过程,这里hook的是Instrumentation中的execStartActivity函数。启动过程里的具体的就不说了,一串方法链,一说又要整几篇文章才说的清楚。


3.xposed的相关

Xposed官网

Xposed-Github

你可能感兴趣的:(玩转Xposed)