在小米手機上,每次安裝一個自己的插件總需要打開安全中心進行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 到此結束,順利完成任務!!