直接上代码
public class HookGetAllPackages {
// 有泄露 用application 防止多次注册代理
static Context context;
//获取安装列表检测
public static void hookDelegate(Context scontext) throws Exception {
if (context == scontext) {
return;
} else {
context = scontext;
}
Log.e("loadContext", "successed 2");
final PackageManager packageManager = context.getPackageManager();
final Object iPackageManager = getBinderObject(packageManager);
Class IPackageManagercls = Class.forName("android.content.pm.IPackageManager");
Object iPackageManagerProxy = Proxy.newProxyInstance(packageManager.getClass().getClassLoader(), new Class[]{IPackageManagercls}, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// if(!method.getName().equals("toStirng")){
// XposedHookUtilOPPOFindxFix.printStackLog(method.getName());
// }
// Log.e("loadContext",method.getName());
Log.e("loadContext", method.getName());
return method.invoke(iPackageManager, args);
}
});
Field sServiceFiled = packageManager.getClass().getDeclaredField("mPM");
sServiceFiled.setAccessible(true);
sServiceFiled.set(packageManager, iPackageManagerProxy);
Log.e("loadContext", "successed 3");
}
public static Object getBinderObject(final PackageManager packageManager) throws Exception {
return getFieldValue(packageManager, "mPM");
}
public static Object getFieldValue(Object object, String fieldName) throws IllegalAccessException, NoSuchFieldException {
Field field = getDeclaredField(object, fieldName);
if (field == null) {
throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + object + "]");
}
makeAccessible(field);
Object result = null;
result = field.get(object);
return result;
}
public static void makeAccessible(Field field) {
if (!Modifier.isPublic(field.getModifiers())) {
field.setAccessible(true);
}
}
public static Field getDeclaredField(Object object, String filedName) throws NoSuchFieldException {
for (Class<?> superClass = object.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()) {
return superClass.getDeclaredField(filedName);
}
return null;
}
//获取已安装列表 方法
public static ArrayList<PackageInfo> getAllPackages(final Context context) {
final ArrayList<PackageInfo> packages = new ArrayList<>();
final PackageManager packageManager = context.getPackageManager();
try {
//高版本需要 hidden api 绕过
final List<String> allPackages = (List<String>)
invokeMethod(getBinderObject(packageManager), "getAllPackages", null, null);
packages.ensureCapacity(allPackages.size());
for (final String packageName : allPackages) {
Log.i("loadContext", packageName);
// try {
// final PackageInfo info = packageManager.getPackageInfo(packageName, PackageManager.MATCH_UNINSTALLED_PACKAGES);
// Log.i(TAG, info.packageName);
// packages.add(info);
// } catch (final PackageManager.NameNotFoundException e) {
// Log.e(TAG, "NameNotFoundException" + packageName);
// } catch (final Exception e) {
// Log.e(TAG, packageName, e);
// }
}
} catch (final InvocationTargetException e) {
Log.e("loadContext", e.getTargetException().getMessage());
packages.addAll(packageManager.getInstalledPackages(PackageManager.MATCH_UNINSTALLED_PACKAGES));
} catch (final Exception e) {
e.printStackTrace();
}
return packages;
}
public static Object invokeMethod(Object object, String methodName, Class<?>[] parameterTypes,
Object[] parameters) throws InvocationTargetException {
Log.i("loadContext", object.getClass().getName());
Method method = getDeclaredMethod(object, methodName, parameterTypes);
if (method == null) {
throw new IllegalArgumentException("Could not find method [" + methodName + "] on target [" + object + "]");
}
method.setAccessible(true);
try {
return method.invoke(object, parameters);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
public static Method getDeclaredMethod(Object object, String methodName, Class<?>[] parameterTypes) {
for (Class<?> superClass = object.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()) {
try {
return superClass.getDeclaredMethod(methodName, parameterTypes);
} catch (NoSuchMethodException e) {
//Method 不在当前类定义, 继续向上转型
}
}
return null;
}
}