一、实现方式:通过 AppOps 权限管理修改短信权限
核心点就是setMode设置短信可写权限,详细信息不懂的可以百度AppOps。
代码:
public static boolean setWriteEnabled(Context arg3, boolean arg4) {
int v1 = getUid(arg3);
int v0 = arg4 ? 0 : 1;
return setMode(arg3, 15, v1, v0);
}
private static boolean setMode(Context arg7, int arg8, int arg9, int arg10) {
Object v0 = arg7.getSystemService(Context.APP_OPS_SERVICE);
Class v3 = v0.getClass();
Log.i("这里看看v3",v3.getName());
int v4 = 4;
try {
v3.getMethod("setMode", Integer.TYPE, Integer.TYPE, String.class, Integer.TYPE).invoke(v0, Integer.valueOf(arg8), Integer.valueOf(arg9), arg7.getPackageName(), Integer.valueOf(arg10));
boolean v0_4 = true;
Log.i("vic","设置appops成功");
return v0_4;
}
catch(IllegalAccessException v0_1) {
v0_1.printStackTrace();
}
catch(InvocationTargetException v0_2) {
v0_2.printStackTrace();
}
catch(NoSuchMethodException v0_3) {
v0_3.printStackTrace();
}
Log.i("vic","设置appops失败");
return false;
}
二、权限问题
先看一下 setMode的源码:
public void setMode(int code, int uid, String packageName, int mode) {
- if (Binder.getCallingPid() != Process.myPid()) {
mContext.enforcePermission(android.Manifest.permission.UPDATE_APP_OPS_STATS,
Binder.getCallingPid(), Binder.getCallingUid(), null);
}
verifyIncomingOp(code);
…
}
分析 setMode的源码得到:如果判断调用 setMode 的客户端不是本进程的话,则必须验证有 android.Manifest.permission.UPDATE_APP_OPS_STATS 权限。
所以直接执行上面的代码是无法实现的,会报错提示没有权限android.Manifest.permission.UPDATE_APP_OPS_STATS,
那现在的问题就是解决这个权限的问题。
再来看看这个权限,权限等级极高,必须要系统签名或者是特权应用。
1、系统签名
正常情况下第三方应用根本不可能拿到厂商的系统签名,所以这个方法实际中是不可行的。但是,我们用模拟器测试是可以的,用模拟器的话我们是可以给应用上系统签名的。实现方式也简单,下载这3个文件signapk.jar、platform.pk8、platform.x509.pem,然后cmd执行指令:
java -jar signapk.jar platform.x509.pem platform.pk8 old.apk new.apk就搞定了。
2、提权
把应用安装到system/pri-app目录下,让应用拥有系统应用的权限。
要把第三方应用安装到系统目录那必须要有root权限,那设备必须是root过的。
总结:在高版本(6.0以上)的安卓设备中,拦截短信还是很难实现的,必须要获取root权限,把应用安装到系统目录才可能利用AppOps权限管理去设置短信读写权限,才能实现拦截删除短信的功能。