您的位置:首页 > 移动开发 > Android开发

一种屏蔽系统下拉菜单的方式

2016-04-12 14:50 941 查看

一种屏蔽系统下拉菜单的方式

导语

Android操作系统下禁用通知栏下拉功能一般使用反射调用StatusBarManager类中函数实现,但该方式需应用具有系统权限。本文介绍的方式采用修改framework层,绕过系统权限检查的方式实现。

一、禁用通知栏下拉功能

查看系统源码: /frameworks/base/core/java/android/app/StatusBarManager.java

/**
* Disable some features in the status bar.  Pass the bitwise-or of the DISABLE_flags.
* To re-enable everything, pass {@link #DISABLE_NONE}.
*/
public void disable(int what) {
try {
final IStatusBarService svc = getService();
if (svc != null) {
svc.disable(what, mToken, mContext.getPackageName());
}
} catch (RemoteException ex) {
// system process is dead anyway.
throw new RuntimeException(ex);
}
}


根据其中 disable 函数,采用反射方式禁用下拉菜单,源码如下:

public static final int STATUS_BAR_DISABLE_EXPAND = 0x00010000;

public static final void disableStatusBar(Context ctx) {

Object sbservice = ctx.getSystemService("statusbar");

try {
Class<?> statusBarManager = Class
.forName("android.app.StatusBarManager");
Method collapse;
collapse = statusBarManager.getMethod("disable", int.class);
collapse.invoke(sbservice,
Integer.valueOf(STATUS_BAR_DISABLE_EXPAND));
} catch (Exception e) {
e.printStackTrace();
}
}


但是实际调用时会抛出异常信息,如下图所示:



异常显示必须配置 android.Manifest.permission.STATUS_BAR 权限,但必须系统应用才能配置该权限。怎样绕过系统权限的检测呢,下面将进行介绍。

二、怎样绕过 android.Manifest.permission.STATUS_BAR 权限检测

继续查看源码,查找 StatusBarManager.javadisable 实现方式

发现 /frameworks/base/services/java/com/android/server/StatusBarManagerService.java 中有该函数的具体实现。

public void disable(int what, IBinder token, String pkg) {
enforceStatusBar();

synchronized (mLock) {
disableLocked(what, token, pkg);
}
}


查看 enforceStatusBar 源码发现该函数,对 android.Manifest.permission.STATUS_BAR 权限进行了检测。

private void enforceStatusBar() {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR,
"StatusBarManagerService");
}


那么我们只要修改 disable 函数,取消其中关于 enforceStatusBar 调用,直接调用 disableLocked 函数禁用下拉通知,即可绕过权限的检测了。

三、framewok层修改

此步需要用到的工具:

baksmalismali下载地址

1、adb 连接入手机,将 /system/framework/services.jar 文件考出进行修改,此步骤需要 ROOT 权限。

2、使用 baksmaliserviec.jar 进行反编译。命令:java -jar baksmali.jar -o OUTDIR services.jar

3、在反编译生成的 smali 文件中找到 StatusBarManagerService.smali 进行修改。此步需要对smali文件格式有一定的了解,可参照网上相关教程这里不再详解。

.method public disable(ILandroid/os/IBinder;Ljava/lang/String;)V
.registers 6
.param p1, "what"    # I
.param p2, "token"    # Landroid/os/IBinder;
.param p3, "pkg"    # Ljava/lang/String;

.prologue
.line 143
invoke-direct {p0}, Lcom/android/server/StatusBarManagerService;->enforceStatusBar()V

.line 145
iget-object v1, p0, Lcom/android/server/StatusBarManagerService;->mLock:Ljava/lang/Object;

monitor-enter v1

.line 146
:try_start_6
invoke-direct {p0, p1, p2, p3}, Lcom/android/server/StatusBarManagerService;->disableLocked(ILandroid/os/IBinder;Ljava/lang/String;)V

.line 147
monitor-exit v1

.line 148
return-void

.line 147
:catchall_b
move-exception v0

monitor-exit v1
:try_end_d
.catchall {:try_start_6 .. :try_end_d} :catchall_b

throw v0
.end method


其中第143行,就是对 enforceStatusBar 函数的调用,这里删除相关的调用即可。

.line 143
invoke-direct {p0}, Lcom/android/server/StatusBarManagerService;->enforceStatusBar()V


修改后的 disable 函数如下:

.method public disable(ILandroid/os/IBinder;Ljava/lang/String;)V
.registers 6
.param p1, "what"    # I
.param p2, "token"    # Landroid/os/IBinder;
.param p3, "pkg"    # Ljava/lang/String;

.prologue
.line 145
iget-object v1, p0, Lcom/android/server/StatusBarManagerService;->mLock:Ljava/lang/Object;

monitor-enter v1

.line 146
:try_start_6
invoke-direct {p0, p1, p2, p3}, Lcom/android/server/StatusBarManagerService;->disableLocked(ILandroid/os/IBinder;Ljava/lang/String;)V

.line 147
monitor-exit v1

.line 148
return-void

.line 147
:catchall_b
move-exception v0

monitor-exit v1
:try_end_d
.catchall {:try_start_6 .. :try_end_d} :catchall_b

throw v0
.end method


4、使用 smali 对修改后的文件进行编译。命令:java -jar smali.jar SRCDIR -o OUTDIR\classes.dex

5、用压缩方式打开 services.jar,将生成的 classes.dex 复制进去替换同名文件。

6、再将完成修改的 services.jar 文件复制到手机 /system/framework/ 目录并替换源文件,整个framework层的修改就完成了,替换后一定记得修改 services.jar 文件权限并重启手机,默认权限为644。

四、结语

修改后使用之前反射的方式调用 disable 函数就不会再抛出异常,而且下拉栏也被成功禁用。

本文主要提供了一种绕过权限检测,禁用下拉菜单的思路,针对4.0以上的大多数系统都能完美实现。大家也可以根据该思路实现其他需要 framework 层修改的功能,具体实现就需要查阅相关系统源码了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android 操作系统