在小米手机上,每次安装一个自己的插件总需要打开安全中心进行root权限授权,非常的麻烦,总共需要电5次确认,每次需要等5秒
因为插件开发的需求,希望重启计算机时候判断是否已经root,未root则自动提权root,所以我查了一些supersu的授权机制,经启发想到小米是否也是如此,通过数据库的方式进行授权管理,如果是的话,那结合xposed,这个授权功能就很轻松实现了。
分析步骤:
1.打开安排小米:安全中心->root权限管理,pc执行命令
adb shell dumpsys activity top
返回结果:判断出当前应用包名是
com.miui.securitycenter
TASK com.miui.securitycenter id=340
ACTIVITY com.miui.securitycenter/com.miui.permcenter.root.RootManagementActivity be58eac pid=5036
Local Activity d6b28df State:
mResumed=true mStopped=false mFinished=false
mChangingConfigurations=false
mCurrentConfig={1.0 460mcc1mnc zh_CN ldltr sw360dp w360dp h572dp 480dpi nrml port finger -keyb/v/h -nav/h s.5 themeChanged=0 themeChangedFlags=0}
mLoadersStarted=true
Loader Manager 88e892c:
Active Loaders:
#113: LoaderInfo{683fff5 #113 : g{aaed18a}}
mId=113 mArgs=null
mCallbacks=com.miui.permcenter.root.RootManagementActivity@d6b28df
mLoader=g{aaed18a id=113}
mId=113 mListener=LoaderInfo{683fff5 #113 : g{aaed18a}}
mStarted=true mContentChanged=false mProcessingChange=false
mHaveData=true mDeliveredData=true
mData=[com.miui.permcenter.root.b@b0373fb]
mStarted=true mReportNextStart=false mDestroyed=false
mRetaining=false mRetainingStarted=false mListenerRegistered=true
FragmentManager misc state:
mHost=android.app.Activity$HostCallbacks@cf10c18
mContainer=android.app.Activity$HostCallbacks@cf10c18
mCurState=5 mStateSaved=false mDestroyed=false
ViewRoot:
mAdded=true mRemoved=false
mConsumeBatchedInputScheduled=false
mConsumeBatchedInputImmediatelyScheduled=false
mPendingInputEventCount=0
2. adb shell 登录手机, su切换root帐号,cd /system/priv-app ,ls -al 显示系统应用包列表,这一般放小米扩张定制的apk,用户在手机中是无法删除的。
很不错,一步就发现和安全相关的包名:SecurityCenter,完整路径:
复制到sdcard,cp /system/priv-app/SecurityCenter/SecurityCenter.apk /sdcard/Download/
电脑重新开一个命令行窗口,然后adb pull /sdcard/Download/SecurityCenter.apk /tmp 拷贝apk到电脑的/tmp目录,使用jadx对apk进行逆向静态分析,因为我们知道了之前activity的名称,所以jadx打开后,搜索root权限管理的activity页面关键词 “允许2个应用使用ROOT权限” ,所以这的关键词是“个应用使用ROOT权限” ,哈,非常顺利找到了。
<plurals name="hints_get_root_enable_title">
<item quantity="other">允许%d个应用使用ROOT权限</item>
</plurals>
查找hints_get_root_enable_title 定位出 RootManagementActivity就是我们的目标位置,这个和之前dumpsys activity top得到的activity是完全一致,所以可以判定就是这了。我们在真实场景点击,总是提示“确定允许x x x请求系统最高管理权限吗?” 这个下一步->下一步->下一步->确定是我们最总需要确定的代码位置,所以再次搜索 得到
<string name="root_apply_step_1">确定允许%s请求系统最高管理权限吗?</string>
查找到了只有在RootApplyActivity中使用
private String m1975a(int i, CharSequence charSequence) {
switch (i) {
case 1:
return getString(R.string.root_apply_step_1, new Object[]{charSequence});
case 2:
return getString(R.string.root_apply_step_2, new Object[]{charSequence});
case 3:
return getString(R.string.root_apply_step_3, new Object[]{charSequence});
case 4:
return getString(R.string.root_apply_step_4, new Object[]{charSequence});
case 5:
return getString(R.string.root_apply_step_5, new Object[]{charSequence});
default:
return null;
}
}
分析代码,确认那步后触发的逻辑是
C1132g.bR(this).m1998a(512, 3, this.mPkgName);
public void m1997a(long j, int i, int i2, String... strArr) {
Bundle bundle = new Bundle();
bundle.putLong("extra_permission", 512);
bundle.putInt("extra_action", 3);
bundle.putStringArray("extra_package", pack);
bundle.putInt("extra_flags", i2);
this.mContentResolver.call(C1126a.CONTENT_URI, String.valueOf(6), null, bundle);
} public void m1998a(long j, int i, String... strArr) {
m1997a(512, 3, 0, packname);
}
这使用了android的ipc机制ContentProvider服务进行了授权,那这个ContentProvider的提供者又是哪个apk呢?我们通过C1126a.CONTENT_URI知道了提供者的地址content://com.lbe.security.miui.permmgr,一般来说,寻找类似的包名就可以了,我们手机上也能发现存在该包名的应用/data/data/com.lbe.security.miui
但是没找到这个apk,不过通过类似名字,运气再次爆棚,发现了这个地址是/system/priv-app/AuthManager/AuthManager.apk pull到电脑再次用jadx分析,确定就是这个apk提供了授权db的操作,参考意思代码分析方式,略过查找代码的过程,最终定位
com.lbe.security.service.provider.PermissionManagerProvider.updatePackagePermission 所以xposed hook自动授权root的代码就如下
XposedHelpers.findAndHookMethod("com.lbe.security.service.provider.PermissionManagerProvider", classLoader, "onCreate",
new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
XposedBridge.log("--hook PermissionManagerProvider ok~~~~~~~ -- ");
//(String packageName, long permId, int action, boolean apply, boolean isSuggest, boolean kill)
//设置root权限,取消root权限把3改成1
XposedHelpers.callMethod(param.thisObject,
"updatePackagePermission",
PACKAGE_NAME,512, 3, true, false, false
);
XposedBridge.log(">> autoAuthorizeRoot ok~ ");
}
});
ok 到此结束,顺利完成任务!!