版权声明:本文为博主原创文章,未经博主允许不得转载!
额,这篇文章主要是讲解如何使用xposed的,并没有对xposed的二次开发或自己整个xposed这种大神级框架。
那么啥是xposed的呢?自己google一下。。。
先来个简单的例子,这也是我第一次用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一定要注意,一不小心,就把系统里一些进程给搞死了)。
通过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));
}
}
最近腾讯的王者荣耀那么火,小编自己也控制不住,动不动就撸一局,小撸怡情,大撸伤身啊,一怒之下,把这款游戏的启动给禁了,点击桌面或其他调用时,把启动给截止了,让用户无法进入王者荣耀。下面来实现下禁止王者荣耀的启动,点击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函数。启动过程里的具体的就不说了,一串方法链,一说又要整几篇文章才说的清楚。
Xposed官网
Xposed-Github