项目地址 完整项目见MIUICustom
注意:该模块仅测试于手机管家
(5.4.0
、5.6.0
、7.2.1
),其他版本未测试。
如果模块未生效,可自行反编译apk,查找并替换Hook点,自行编译Xposed模块。
概述 每次修改系统设置(设置通知使用权、允许app安装未知应用、开启无障碍功能等),都会有10秒倒计时,使用起来很不方便。
于是考虑使用Frida
绕过倒计时,并开发Xposed
模块。
倒计时类型 主要有以下两种:
查看前台Activity:
1 adb shell dumpsys activity activities | findstr "mFocused"
可以发现两个对话框都来自手机管家,分别对应:com.miui.permcenter.privacymanager.SpecialPermissionInterceptActivity
com.miui.permcenter.install.AdbInputApplyActivity
后者已经有分析文章了,见MIUI 12稳定版系统中的开发者选项限制解除 。 也可以直接改配置文件,见需root,无需xp和frida,miui开发者选项限制解除
7.2.1 Hook点 com.miui.permcenter.privacymanager.InterceptBaseFragment
的n
函数,主动调用d
函数。
Frida脚本验证 1 2 3 4 5 6 Java.perform(function ( ) { Java.use("com.miui.permcenter.privacymanager.InterceptBaseFragment" ).n.overload() .implementation = function ( ) { this .d(true ); }; })
5.6.0 Hook点 com.miui.permcenter.privacymanager.f
的n
函数,主动调用d
函数。
快速定位 搜索SpecialPermissionInterceptActivity
类,定位到判断函数(开头调用getStringExtra("permName")
)。
1 2 3 4 5 6 7 8 9 10 11 protected void r () { int v0 = d.a(((Activity)this ).getIntent().getStringExtra("permName" )); if (v0 == -1 ) { ((Activity)this ).finish(); } t v1 = this .getSupportFragmentManager().b(); g v0_1 = d.c(v0) ? g.a(((Activity)this ).getIntent()) : h.a(((Activity)this ).getIntent()); v1.b(0x1020002 , v0_1); v1.b(); }
进入三元运算符的返回值类g v0_1
,查看其父类f
,搜索setOnClickListener
,该函数即为Hook点(n
)
1 2 3 4 5 6 7 8 9 10 11 public void n () { Button v0 = this .btnConfirm; if (v0 != null ) { v0.setOnClickListener(this .e); } Button v0_1 = this .c; if (v0_1 != null ) { v0_1.setOnClickListener(this .e); } }
查看this.e
的实现代码,即可找到主动调用函数名(d
)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 @Override public void onClick (View arg3) { boolean v0; f v3; if (arg3.getId() == 0x7F0B041A ) { v3 = this .a; v0 = true ; v3.d(v0); return ; } if (arg3.getId() == 0x7F0B041E ) { v3 = this .a; v0 = false ; v3.d(v0); return ; } this .a.h(arg3.getId()); }
Frida脚本 1 2 3 4 5 6 Java.perform(function ( ) { Java.use("com.miui.permcenter.privacymanager.f" ).n.overload() .implementation = function ( ) { this .d(true ); }; })
分析5.4.0 从/system/priv-app/SecurityCenter/
提取手机管家apk(版本号5.4.0
),使用JEB打开,定位到该Activity:
1 2 3 4 5 6 7 8 9 protected void onCreate (Bundle bundle) { super .onCreate(bundle); Window window = this .getWindow(); window.setBackgroundDrawable(new ColorDrawable(this .getResources().getColor(0x7F060599 ))); window.setLayout(-1 , -1 ); window.addFlags(4 ); this .a(); this .b(); }
其他函数 a
函数反射调用setNavigationBarColor
,设置导航栏颜色b
函数根据permName
的值,显示不同的窗口(-1则直接退出):
1 2 3 4 5 6 7 8 9 10 11 private void b () { int permName = c.a(this .getIntent().getStringExtra("permName" )); if (permName == -1 ) { this .finish(); } FragmentTransaction fragmentTransaction = this .getFragmentManager().beginTransaction(); e fragment = c.gt5(permName) ? e.a(this .getIntent()) : f.a(this .getIntent()); fragmentTransaction.replace(0x1020002 , ((Fragment)fragment)); fragmentTransaction.commitAllowingStateLoss(); }
查看com.miui.permcenter.privacymanager.m.c
类,其中包含权限数组:
1 c.d = Arrays.asList(new String[]{"perm_notification" , "perm_install_unknown" , "perm_app_statistics" , "perm_device_manager" , "miui_open_debug" , "miui_barrier_free" , "miui_close_optimization" , "oaid_close" });
可得到以下对应关系:
permName
功能
0
通知使用权
1
安装未知应用
2
使用情况访问权限
3
设备管理应用
4
打开USB调试模式
5
无障碍功能
6
关闭MIUI优化
7
开启OEM解锁
核心函数 查看f.a
函数:
1 2 3 4 5 6 7 8 9 10 public static f a (Intent intent) { f fragment = new f(); Bundle bundle = new Bundle(); if (intent != null ) { bundle.putString("permName" , intent.getStringExtra("permName" )); } fragment.setArguments(bundle); return fragment; }
f
类继承自d
类,且在c
函数中设置了按钮的OnClickListener
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 protected View.OnClickListener e;public d () { this .e = new d.a(this ); } public void c () { Button btnConfirm = this .b; if (btnConfirm != null ) { btnConfirm.setOnClickListener(this .e); } Button btnCancel = this .c; if (btnCancel != null ) { btnCancel.setOnClickListener(this .e); } }
查看com.miui.permcenter.privacymanager.d$a
的onClick
函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public void onClick (View view) { boolean v0; d fragment; if (view.getId() == 0x7F0B03F9 ) { fragment = this .a; v0 = true ; fragment.a(v0); return ; } if (view.getId() == 0x7F0B03FD ) { fragment = this .a; v0 = false ; fragment.a(v0); return ; } this .a.b(view.getId()); }
判断点击的按钮是确认还是取消,最终调用a
函数,确认传入true
,取消传入false
1 2 3 4 public void a (boolean flag) { this .getActivity().setResult(flag ? -1 : 0 ); this .getActivity().finish(); }
绕过 Hook com.miui.permcenter.privacymanager.d.c
函数(即设置OnClickListener
的函数),替换其实现,直接调用a
函数,传入true
即可
Frida 1 2 3 4 5 6 Java.perform(function ( ) { Java.use("com.miui.permcenter.privacymanager.d" ).c.overload() .implementation = function ( ) { this .a(true ); }; })
Xposed 反射调用a
函数即可
1 2 3 4 5 6 7 8 findAndHookMethod("com.miui.permcenter.privacymanager.d" , lpparam.classLoader, "c" , new XC_MethodReplacement() { @Override protected Object replaceHookedMethod (MethodHookParam param) throws Throwable { Method mtdA = param.thisObject.getClass().getDeclaredMethod("a" , boolean .class); mtdA.invoke(param.thisObject, true ); return null ; } });
参考 MIUI9绕开联网和插卡打开未知来源