// 定义包名,这个类属于com.iran.SmaliHelper包
package com.iran.SmaliHelper;
// 导入Android应用程序基类
import android.app.Application;
// 导入Android应用程序测试工具类
import android.app.Instrumentation;
// 导入Android上下文类
import android.content.Context;
// 导入应用程序信息类
import android.content.pm.ApplicationInfo;
// 导入包信息类
import android.content.pm.PackageInfo;
// 导入包管理器类
import android.content.pm.PackageManager;
// 导入Java反射相关的字段类
import java.lang.reflect.Field;
// 导入Java动态代理调用处理器接口
import java.lang.reflect.InvocationHandler;
// 导入Java反射方法类
import java.lang.reflect.Method;
// 导入Java动态代理类
import java.lang.reflect.Proxy;
// 导入Java数组列表类
import java.util.ArrayList;
// 定义一个最终类RemoveUpdate,继承自Application并实现InvocationHandler接口
// 这个类的主要作用是拦截和修改系统包管理器的行为
public final class RemoveUpdate extends Application implements InvocationHandler {
// 存储应用程序类名的私有字段
private String appClassName;
// 存储数据的私有字段
private String data;
// 存储系统包管理器对象的私有字段
private Object sPackageManager;
// 存储签名信息的二维字节数组
private byte[][] sign;
// 存储类型标识的私有字段
private String type;
// 构造函数,初始化各个字段的默认值
public RemoveUpdate() {
// 设置应用程序类名为"GKLBB"
this.appClassName = "GKLBB";
// 设置类型为"1",用于控制不同的拦截策略
this.type = "1";
// 初始化数据字段为空字符串
this.data = "";
}
// 重写attachBaseContext方法,在应用程序上下文附加时执行
@Override
protected void attachBaseContext(Context base) {
// 调用父类的attachBaseContext方法
super.attachBaseContext(base);
try {
// 通过反射获取ActivityThread类
Class<?> activityThreadClass = Class.forName("android.app.ActivityThread");
// 获取当前ActivityThread实例
Object currentActivityThread = activityThreadClass.getDeclaredMethod("currentActivityThread", new Class[0])
.invoke(null, new Object[0]);
// 获取ActivityThread类中的sPackageManager字段
Field sPackageManagerField = activityThreadClass.getDeclaredField("sPackageManager");
// 设置字段可访问(绕过private限制)
sPackageManagerField.setAccessible(true);
// 保存原始的包管理器对象
this.sPackageManager = sPackageManagerField.get(currentActivityThread);
// 获取IPackageManager接口类
Class<?> iPackageManagerInterface = Class.forName("android.content.pm.IPackageManager");
// 创建动态代理对象,用当前对象作为调用处理器
Object proxy = Proxy.newProxyInstance(
iPackageManagerInterface.getClassLoader(),
new Class[]{iPackageManagerInterface},
this
);
// 将代理对象设置到ActivityThread的sPackageManager字段中
sPackageManagerField.set(currentActivityThread, proxy);
// 获取PackageManager实例
PackageManager pm = base.getPackageManager();
// 获取PackageManager中的mPM字段
Field mPmField = pm.getClass().getDeclaredField("mPM");
// 设置字段可访问
mPmField.setAccessible(true);
// 将代理对象也设置到PackageManager的mPM字段中
mPmField.set(pm, proxy);
} catch (Exception e) {
// 如果出现异常,打印堆栈跟踪信息
e.printStackTrace();
}
}
// 重写onCreate方法,在应用程序创建时执行
@Override
public void onCreate() {
// 调用父类的onCreate方法
super.onCreate();
try {
// 获取当前ActivityThread实例
Object currentActivityThread = invokeStaticMethod("android.app.ActivityThread", "currentActivityThread", new Class[0], new Object[0]);
// 获取绑定的应用程序数据对象
Object mBoundApplication = getFieldObject("android.app.ActivityThread", currentActivityThread, "mBoundApplication");
// 从AppBindData中获取应用程序信息
ApplicationInfo appinfo_In_AppBindData = (ApplicationInfo) getFieldObject("android.app.ActivityThread$AppBindData", mBoundApplication, "appInfo");
// 获取已加载的APK信息
Object loadedApkInfo = getFieldObject("android.app.ActivityThread", currentActivityThread, "mPackages");
// 修改AppBindData中的应用程序类名
appinfo_In_AppBindData.className = this.appClassName;
// 获取LoadedApk中的应用程序信息
ApplicationInfo appinfo_In_LoadedApk = (ApplicationInfo) getFieldObject("android.app.LoadedApk", loadedApkInfo, "mApplicationInfo");
// 修改LoadedApk中的应用程序类名
appinfo_In_LoadedApk.className = this.appClassName;
// 获取旧的应用程序实例
Application oldApplication = (Application) getFieldObject("android.app.ActivityThread", currentActivityThread, "mInitialApplication");
// 获取所有应用程序列表
ArrayList<Application> mAllApplications = (ArrayList<Application>) getFieldObject("android.app.ActivityThread", currentActivityThread, "mAllApplications");
// 从列表中移除旧的应用程序实例
mAllApplications.remove(oldApplication);
// 再次获取LoadedApk中的应用程序信息(用于创建新应用程序)
ApplicationInfo appinfo_In_LoadedApk2 = (ApplicationInfo) getFieldObject("android.app.LoadedApk", loadedApkInfo, "mApplicationInfo");
// 创建新的应用程序实例
Application app = (Application) invokeMethod("android.app.LoadedApk", "makeApplication", loadedApkInfo,
new Class[]{boolean.class, Instrumentation.class},
new Object[]{false, null});
// 设置新的应用程序实例为初始应用程序
setFieldObject("android.app.ActivityThread", "mInitialApplication", currentActivityThread, app);
// 如果新应用程序实例不为空,调用其onCreate方法
if (app != null) {
app.onCreate();
}
} catch (Exception e) {
// 如果出现异常,打印堆栈跟踪信息
e.printStackTrace();
}
}
// 通过反射获取指定对象的字段值
public Object getFieldObject(String className, Object obj, String fieldName) {
try {
// 根据类名获取Class对象
Class<?> objClass = Class.forName(className);
// 获取指定名称的字段
Field field = objClass.getDeclaredField(fieldName);
// 设置字段可访问(绕过private等访问限制)
field.setAccessible(true);
// 返回字段的值
return field.get(obj);
} catch (SecurityException | NoSuchFieldException | IllegalArgumentException |
IllegalAccessException | ClassNotFoundException e) {
// 捕获各种可能的异常并打印堆栈信息
e.printStackTrace();
// 异常时返回null
return null;
}
}
// 通过反射获取指定类的静态字段值
public Object getStaticFieldObject(String className, String fieldName) {
try {
// 根据类名获取Class对象
Class<?> objClass = Class.forName(className);
// 获取指定名称的字段
Field field = objClass.getDeclaredField(fieldName);
// 设置字段可访问
field.setAccessible(true);
// 获取静态字段的值(传入null表示静态字段)
return field.get(null);
} catch (SecurityException | NoSuchFieldException | IllegalArgumentException |
IllegalAccessException | ClassNotFoundException e) {
// 捕获异常并打印堆栈信息
e.printStackTrace();
// 异常时返回null
return null;
}
}
// 通过反射设置指定对象的字段值
public void setFieldObject(String className, String fieldName, Object obj, Object fieldValue) {
try {
// 根据类名获取Class对象
Class<?> objClass = Class.forName(className);
// 获取指定名称的字段
Field field = objClass.getDeclaredField(fieldName);
// 设置字段可访问
field.setAccessible(true);
// 设置字段的值
field.set(obj, fieldValue);
} catch (SecurityException | NoSuchFieldException | IllegalArgumentException |
IllegalAccessException | ClassNotFoundException e) {
// 捕获异常并打印堆栈信息
e.printStackTrace();
}
}
// 通过反射设置指定类的静态字段值
public void setStaticObject(String className, String fieldName, Object fieldValue) {
try {
// 根据类名获取Class对象
Class<?> objClass = Class.forName(className);
// 获取指定名称的字段
Field field = objClass.getDeclaredField(fieldName);
// 设置字段可访问
field.setAccessible(true);
// 设置静态字段的值(传入null表示静态字段)
field.set(null, fieldValue);
} catch (SecurityException | NoSuchFieldException | IllegalArgumentException |
IllegalAccessException | ClassNotFoundException e) {
// 捕获异常并打印堆栈信息
e.printStackTrace();
}
}
// 通过反射调用指定对象的方法
public Object invokeMethod(String className, String methodName, Object obj, Class<?>[] paramTypes, Object[] params) {
try {
// 根据类名获取Class对象
Class<?> objClass = Class.forName(className);
// 根据方法名和参数类型获取Method对象
Method method = objClass.getDeclaredMethod(methodName, paramTypes);
// 设置方法可访问
method.setAccessible(true);
// 调用方法并返回结果
return method.invoke(obj, params);
} catch (Exception e) {
// 捕获异常并打印堆栈信息
e.printStackTrace();
// 异常时返回null
return null;
}
}
// 通过反射调用指定类的静态方法
public Object invokeStaticMethod(String className, String methodName, Class<?>[] paramTypes, Object[] params) {
try {
// 根据类名获取Class对象
Class<?> objClass = Class.forName(className);
// 根据方法名和参数类型获取Method对象
Method method = objClass.getDeclaredMethod(methodName, paramTypes);
// 设置方法可访问
method.setAccessible(true);
// 调用静态方法并返回结果(传入null表示静态方法)
return method.invoke(null, params);
} catch (Exception e) {
// 捕获异常并打印堆栈信息
e.printStackTrace();
// 异常时返回null
return null;
}
}
// 实现InvocationHandler接口的invoke方法,用于拦截包管理器的方法调用
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// 初始化返回结果
Object result = null;
// 如果类型为"1",执行版本码修改策略
if ("1".equals(this.type)) {
// 如果调用的是getPackageInfo方法且查询的是当前应用包名
if ("getPackageInfo".equals(method.getName()) &&
args[0].equals(getPackageName())) {
// 调用原始包管理器的方法
result = method.invoke(this.sPackageManager, args);
// 将返回的包信息转换为PackageInfo对象
PackageInfo info = (PackageInfo) result;
// 将版本码设置为最大整数值,用于绕过版本检查
info.versionCode = Integer.MAX_VALUE;
} else {
// 对于其他方法调用,直接转发给原始包管理器
result = method.invoke(this.sPackageManager, args);
}
} else if ("2".equals(this.type)) {
// 如果类型为"2",执行隐藏应用策略
if ("getInstalledPackages".equals(method.getName())) {
// 如果查询已安装包列表,返回空列表(隐藏所有应用)
result = new ArrayList<>();
} else if ("getPackageInfo".equals(method.getName())) {
// 如果查询包信息
if (!args[0].equals(getPackageName())) {
// 如果不是查询当前应用,将包名替换为"ccc"(不存在的包名)
args[0] = "ccc";
result = method.invoke(this.sPackageManager, args);
} else {
// 如果是查询当前应用,正常处理
result = method.invoke(this.sPackageManager, args);
}
} else if ("getApplicationInfo".equals(method.getName()) ||
"getPackageUid".equals(method.getName()) ||
"getPackageGids".equals(method.getName()) ||
"getApplicationEnabledSetting".equals(method.getName()) ||
"getText".equals(method.getName()) ||
"getResourcesForApplication".equals(method.getName())) {
// 对于这些应用信息相关的方法
if (!args[0].equals(getPackageName())) {
// 如果不是查询当前应用,将包名替换为"ccc"
args[0] = "ccc";
result = method.invoke(this.sPackageManager, args);
} else {
// 如果是查询当前应用,正常处理
result = method.invoke(this.sPackageManager, args);
}
} else if ("getApplicationBanner".equals(method.getName())) {
// 如果是获取应用横幅图标的方法
if (args[0] instanceof String && !args[0].equals(getPackageName())) {
// 如果参数是字符串且不是当前应用包名,替换为"ccc"
args[0] = "ccc";
result = method.invoke(this.sPackageManager, args);
} else {
// 否则正常处理
result = method.invoke(this.sPackageManager, args);
}
} else {
// 对于其他方法,直接转发给原始包管理器
result = method.invoke(this.sPackageManager, args);
}
} else {
// 如果类型不是"1"或"2",直接转发所有方法调用
result = method.invoke(this.sPackageManager, args);
}
// 返回处理结果
return result;
}
}
}