wordpress 圖片連接插件福建seo
把之前寫的Xposed相關(guān)文章合并到一塊,方便查閱
目錄
- 多進(jìn)程App的Hook問題
- XposedHelper中的靜態(tài)變量
- demo的AndroidManifest.xml的測試核心代碼
- 結(jié)論
- 限制handleLoadPackage被單個進(jìn)程多次執(zhí)行的問題
- 多dex Hook問題
- 為應(yīng)用增加權(quán)限
- 利用Xposed刪除權(quán)限
- 參考
- Hook框架集錦
- 原始思維導(dǎo)圖文件下載
多進(jìn)程App的Hook問題
以及App中單個方法被多個模塊Hook時的Hook代碼優(yōu)先級問題
XposedHelper中的靜態(tài)變量
demo的AndroidManifest.xml的測試核心代碼
<activityandroid:name=".ProcessActivity"android:process=":process"></activity>//私有進(jìn)程<activityandroid:name=".PublicProcessActivity"android:process="com.publicProcess">//公共進(jìn)程</activity>
結(jié)論
以下"所有進(jìn)程"都包括應(yīng)用內(nèi)創(chuàng)建的私有進(jìn)程和公共進(jìn)程
經(jīng)過測試[測試代碼過多就不貼了],得出結(jié)論:
1.所有進(jìn)程的創(chuàng)建都會執(zhí)行而且會多次執(zhí)行handleLoadPackage函數(shù);
2.每個進(jìn)程都會重新創(chuàng)建一個fieldCache,methodCache,constructorCache靜態(tài)變量;
3.若兩個模塊Hook了當(dāng)前App的同一個函數(shù)則beforeHookedMethod執(zhí)行順序是按Xposed框架私有目錄下conf/modules.list的順序執(zhí)行的,afterHookedMethod則與beforeHookedMethod執(zhí)行順序相反[測試數(shù)據(jù)是這樣的,具體真實情況就不太想探究了,應(yīng)該90%正確],舉個例子:
模塊A和模塊B同時Hook了應(yīng)用C的方法D,modules.list中模塊A比模塊B的順序靠前,則Hook代碼執(zhí)行順序為:
A->beforeHookedMethod,B->beforeHookedMethod,D,B->afterHookedMethod,A->afterHookedMethod
4.lpparam.isFirstApplication并不是僅僅在主進(jìn)程執(zhí)行handleLoadPackage函數(shù)時才會置為true,在所有進(jìn)程執(zhí)行該函數(shù)時都會置為true[測試數(shù)據(jù)是這樣的,具體真實情況就不太想探究了,應(yīng)該90%正確];
5.在App的一個進(jìn)程A中對某函數(shù)進(jìn)行Hook只會影響進(jìn)程A執(zhí)行該函數(shù),不會影響該App其它未被Hook的進(jìn)程執(zhí)行該函數(shù)。
限制handleLoadPackage被單個進(jìn)程多次執(zhí)行的問題
/***防止重復(fù)執(zhí)行Hook代碼* @param flag 判斷標(biāo)識,針對不同Hook代碼分別進(jìn)行判斷* @return 是否已經(jīng)注入Hook代碼*/private boolean isInjecter(String flag) {try {if (TextUtils.isEmpty(flag)) return false;Field methodCacheField = XposedHelpers.class.getDeclaredField("methodCache");methodCacheField.setAccessible(true);HashMap<String, Method> methodCache = (HashMap<String, Method>) methodCacheField.get(null);Method method=XposedHelpers.findMethodBestMatch(Application.class,"onCreate");String key=String.format("%s#%s",flag,method.getName());if (methodCache.containsKey(key)) return true;methodCache.put(key, method);return false;} catch (Throwable e) {e.printStackTrace();}return false;}
在handleLoadPackage做判斷
@Keeppublic void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) {if (isInjecter(this.getClass().getName())) {return;}//hook代碼
}
多dex Hook問題
//解決多dex問題public static void findHideDex(final OnFindDexListener listener) {XposedBridge.hookAllMethods(ContextWrapper.class, "attachBaseContext", new XC_MethodHook() {public void beforeHookedMethod(MethodHookParam param) {ClassLoader classLoader = ((Context) param.args[0]).getClassLoader();if (classLoader == null) return;if (listener != null) listener.onFind(classLoader);}});XposedBridge.hookAllConstructors(ClassLoader.class, new XC_MethodHook() {public void beforeHookedMethod(MethodHookParam param) {ClassLoader classLoader = (ClassLoader) param.args[0];if (classLoader == null) return;if (listener != null) listener.onFind(classLoader);}});}
public interface OnFindDexListener {void onFind(ClassLoader classLoader);}
為應(yīng)用增加權(quán)限
利用Xposed刪除權(quán)限
這個已經(jīng)有人實現(xiàn)了,就是Xposed的作者,我們就先來研究研究他是怎么實現(xiàn)的,先上他的實現(xiàn)代碼
public class PackagePermissions extends BroadcastReceiver {private final Object pmSvc;private final Map<String, Object> mPackages;private final Object mSettings;@SuppressWarnings("unchecked")public PackagePermissions(Object pmSvc) {this.pmSvc = pmSvc;this.mPackages = (Map<String, Object>) getObjectField(pmSvc, "mPackages");this.mSettings = getObjectField(pmSvc, "mSettings");}/*這個函數(shù)主要hook了 PackageManager 服務(wù)(負(fù)責(zé)系統(tǒng)中Package的管理,應(yīng)用程序的安裝、卸載、信息查詢),實現(xiàn)了通過監(jiān)聽我們自己發(fā)出的廣播,攔截權(quán)限授予功能來進(jìn)行修改apk的權(quán)限的*/public static void initHooks() {try {final Class<?> clsPMS = findClass("com.android.server.pm.PackageManagerService", XposedMod.class.getClassLoader());//獲取這個PackageManager類//注冊監(jiān)聽廣播,監(jiān)聽我們的設(shè)置更改,以實現(xiàn)立即應(yīng)用設(shè)置findAndHookMethod(clsPMS, "systemReady", new XC_MethodHook() {@Overrideprotected void afterHookedMethod(MethodHookParam param)throws Throwable {Context mContext = (Context) getObjectField(param.thisObject, "mContext");//這個應(yīng)該是系統(tǒng)的上下文,具體待研究mContext.registerReceiver(new PackagePermissions(param.thisObject),new IntentFilter(Common.MY_PACKAGE_NAME + ".UPDATE_PERMISSIONS"),Common.MY_PACKAGE_NAME + ".BROADCAST_PERMISSION",null);//注冊廣播}});//攔截PackageManager類中的grantPermissionsLPw函數(shù)findAndHookMethod(clsPMS, "grantPermissionsLPw", "android.content.pm.PackageParser$Package", boolean.class,new XC_MethodHook() {@SuppressWarnings("unchecked")@Overrideprotected void beforeHookedMethod(MethodHookParam param) throws Throwable {String pkgName = (String) getObjectField(param.args[0], "packageName");if (!XposedMod.isActive(pkgName) || !XposedMod.prefs.getBoolean(pkgName + Common.PREF_REVOKEPERMS, false))return;Set<String> disabledPermissions = XposedMod.prefs.getStringSet(pkgName + Common.PREF_REVOKELIST, null);if (disabledPermissions == null || disabledPermissions.isEmpty())return;ArrayList<String> origRequestedPermissions = (ArrayList<String>) getObjectField(param.args[0], "requestedPermissions");param.setObjectExtra("orig_requested_permissions", origRequestedPermissions);ArrayList<String> newRequestedPermissions = new ArrayList<String>(origRequestedPermissions.size());for (String perm: origRequestedPermissions) {if (!disabledPermissions.contains(perm))newRequestedPermissions.add(perm);else// you requested those internet permissions? I didn't read that, sorryLog.w(Common.TAG, "Not granting permission " + perm+ " to package " + pkgName+ " because you think it should not have it");}setObjectField(param.args[0], "requestedPermissions", newRequestedPermissions);}@SuppressWarnings("unchecked")@Overrideprotected void afterHookedMethod(MethodHookParam param) throws Throwable {// restore requested permissions if they were modifiedArrayList<String> origRequestedPermissions = (ArrayList<String>) param.getObjectExtra("orig_requested_permissions");if (origRequestedPermissions != null)setObjectField(param.args[0], "requestedPermissions", origRequestedPermissions);}});} catch (Throwable e) {XposedBridge.log(e);}}@Overridepublic void onReceive(Context context, Intent intent) {try {// The app broadcasted a request to update settings for a running app// Validate the action being requestedif (!Common.ACTION_PERMISSIONS.equals(intent.getExtras().getString("action")))return;String pkgName = intent.getExtras().getString("Package");boolean killApp = intent.getExtras().getBoolean("Kill", false);XposedMod.prefs.reload();Object pkgInfo;synchronized (mPackages) {pkgInfo = mPackages.get(pkgName);callMethod(pmSvc, "grantPermissionsLPw", pkgInfo, true);callMethod(mSettings, "writeLPr");}// Apply new permissions if neededif (killApp) {try {ApplicationInfo appInfo = (ApplicationInfo) getObjectField(pkgInfo, "applicationInfo");if (Build.VERSION.SDK_INT <= 18)callMethod(pmSvc, "killApplication", pkgName, appInfo.uid);elsecallMethod(pmSvc, "killApplication", pkgName, appInfo.uid, "apply App Settings");} catch (Throwable t) {XposedBridge.log(t);}}} catch (Throwable t) {XposedBridge.log(t);}}
}
這段代碼的地址
參考
1.AppSettingshook權(quán)限代碼
2.Android5.1.1源碼 - 添加應(yīng)用權(quán)限
Hook框架集錦
原始思維導(dǎo)圖文件下載
ProcessOn:Android-Hook框架集錦.pos