Remove useless code (Abandon support for Android 8.1) (#21)

This commit is contained in:
Nullptr 2021-09-07 20:38:10 +08:00 committed by GitHub
parent 14ab3bbd56
commit 4b75a17a24
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 15 additions and 247 deletions

View File

@ -4,7 +4,6 @@ import static android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE;
import static org.lsposed.lspd.service.ConfigFileManager.loadModule;
import android.app.ActivityThread;
import android.app.Application;
import android.app.LoadedApk;
import android.content.Context;
import android.content.pm.ApplicationInfo;
@ -44,7 +43,6 @@ import java.util.Objects;
import java.util.zip.ZipFile;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
import hidden.HiddenApiBridge;
@ -53,17 +51,13 @@ import hidden.HiddenApiBridge;
*/
@SuppressWarnings("unused")
public class LSPApplication extends ApplicationServiceClient {
private static final String ORIGINAL_APPLICATION_NAME_ASSET_PATH = "original_application_name.ini";
private static final String ORIGINAL_SIGNATURE_ASSET_PATH = "original_signature_info.ini";
private static final String USE_MANAGER_CONTROL_PATH = "use_manager.ini";
private static final String TAG = "LSPatch";
private static boolean useManager;
private static String originalApplicationName = null;
private static String originalSignature = null;
private static Application sOriginalApplication = null;
private static ManagerResolver managerResolver = null;
private static ClassLoader appClassLoader;
private static Object activityThread;
final static public int FIRST_APP_ZYGOTE_ISOLATED_UID = 90000;
@ -91,7 +85,6 @@ public class LSPApplication extends ApplicationServiceClient {
}
useManager = Boolean.parseBoolean(Objects.requireNonNull(FileUtils.readTextFromAssets(context, USE_MANAGER_CONTROL_PATH)));
originalApplicationName = FileUtils.readTextFromAssets(context, ORIGINAL_APPLICATION_NAME_ASSET_PATH);
originalSignature = FileUtils.readTextFromAssets(context, ORIGINAL_SIGNATURE_ASSET_PATH);
if (useManager) try {
@ -100,13 +93,11 @@ public class LSPApplication extends ApplicationServiceClient {
Log.e(TAG, "Failed to instantiate manager resolver", e);
}
XLog.d(TAG, "original application class " + originalApplicationName);
XLog.d(TAG, "original signature info " + originalSignature);
instance = new LSPApplication();
serviceClient = instance;
try {
initAppClassLoader(context);
disableProfile(context);
loadModules(context);
Main.forkPostCommon(false, context.getDataDir().toString(), ActivityThread.currentProcessName());
@ -210,20 +201,6 @@ public class LSPApplication extends ApplicationServiceClient {
super();
}
private static boolean isApplicationProxied() {
return originalApplicationName != null && !originalApplicationName.isEmpty() && !("android.app.Application").equals(originalApplicationName);
}
private static void initAppClassLoader(Context context) {
try {
Object mBoundApplication = XposedHelpers.getObjectField(getActivityThread(), "mBoundApplication");
Object loadedApkObj = XposedHelpers.getObjectField(mBoundApplication, "info");
appClassLoader = (ClassLoader) XposedHelpers.getObjectField(loadedApkObj, "mClassLoader");
} catch (Throwable e) {
Log.e(TAG, "initAppClassLoader", e);
}
}
private static int getTranscationId(String clsName, String trasncationName) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
Field field = Class.forName(clsName).getDeclaredField(trasncationName);
field.setAccessible(true);
@ -232,7 +209,7 @@ public class LSPApplication extends ApplicationServiceClient {
private static void byPassSignature(Context context) throws ClassNotFoundException, IllegalAccessException, NoSuchFieldException {
final int TRANSACTION_getPackageInfo = getTranscationId("android.content.pm.IPackageManager$Stub", "TRANSACTION_getPackageInfo");
XposedHelpers.findAndHookMethod("android.os.BinderProxy", appClassLoader, "transact", int.class, Parcel.class, Parcel.class, int.class, new XC_MethodHook() {
XposedHelpers.findAndHookMethod("android.os.BinderProxy", null, "transact", int.class, Parcel.class, Parcel.class, int.class, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
try {
@ -294,13 +271,6 @@ public class LSPApplication extends ApplicationServiceClient {
}
private static void doHook(Context context) throws IllegalAccessException, ClassNotFoundException, IOException, NoSuchFieldException {
if (isApplicationProxied()) {
hookContextImplSetOuterContext();
hookInstallContentProviders();
hookActivityAttach();
hookServiceAttach();
}
// hookApplicationStub();
int bypassLv = fetchSigbypassLv(context);
if (bypassLv >= Constants.SIGBYPASS_LV_PM) {
byPassSignature(context);
@ -339,89 +309,6 @@ public class LSPApplication extends ApplicationServiceClient {
return 0;
}
private static void hookApplicationStub() {
try {
Class<?> appStub = XposedHelpers.findClass("org.lsposed.lspatch.appstub.LSPApplicationStub", appClassLoader);
XposedHelpers.findAndHookMethod(appStub, "onCreate", new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
instance.onCreate();
}
});
XposedHelpers.findAndHookMethod(appStub, "attachBaseContext", Context.class, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
instance.attachBaseContext((Context) param.args[0]);
}
});
} catch (Throwable e) {
Log.e(TAG, "hookApplicationStub", e);
}
}
private static void hookContextImplSetOuterContext() {
try {
XposedHelpers.findAndHookMethod("android.app.ContextImpl", appClassLoader, "setOuterContext", Context.class, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
replaceApplicationParam(param.args);
}
});
} catch (Throwable e) {
Log.e(TAG, "hookContextImplSetOuterContext", e);
}
}
private static void hookInstallContentProviders() {
try {
XposedBridge.hookAllMethods(XposedHelpers.findClass("android.app.ActivityThread", appClassLoader), "installContentProviders", new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
replaceApplicationParam(param.args);
}
});
} catch (Throwable e) {
Log.e(TAG, "hookInstallContextProviders", e);
}
}
private static void hookActivityAttach() {
try {
XposedBridge.hookAllMethods(XposedHelpers.findClass("android.app.Activity", appClassLoader), "attach", new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
replaceApplicationParam(param.args);
}
});
} catch (Throwable e) {
Log.e(TAG, "hookActivityAttach", e);
}
}
private static void hookServiceAttach() {
try {
XposedBridge.hookAllMethods(XposedHelpers.findClass("android.app.Service", appClassLoader), "attach", new XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
replaceApplicationParam(param.args);
}
});
} catch (Throwable e) {
Log.e(TAG, "hookServiceAttach", e);
}
}
private static void replaceApplicationParam(Object[] args) {
if (args == null || args.length == 0) {
return;
}
for (Object para : args) {
if (para instanceof LSPApplication) {
para = sOriginalApplication;
}
}
}
private static Object getActivityThread() {
if (activityThread == null) {
try {
@ -433,89 +320,6 @@ public class LSPApplication extends ApplicationServiceClient {
return activityThread;
}
protected void attachBaseContext(Context base) {
if (isApplicationProxied()) {
modifyApplicationInfoClassName();
attachOrignalBaseContext(base);
setLoadedApkField(base);
}
}
private void attachOrignalBaseContext(Context base) {
try {
XposedHelpers.callMethod(sOriginalApplication, "attachBaseContext", base);
} catch (Throwable e) {
Log.e(TAG, "attachOriginalBaseContext", e);
}
}
private void setLoadedApkField(Context base) {
try {
Class<?> contextImplClass = Class.forName("android.app.ContextImpl");
Object contextImpl = XposedHelpers.callStaticMethod(contextImplClass, "getImpl", base);
Object loadedApk = XposedHelpers.getObjectField(contextImpl, "mPackageInfo");
XposedHelpers.setObjectField(sOriginalApplication, "mLoadedApk", loadedApk);
} catch (Throwable e) {
Log.e(TAG, "setLoadedApkField", e);
}
}
public void onCreate() {
if (isApplicationProxied()) {
// replaceApplication();
replaceLoadedApkApplication();
replaceActivityThreadApplication();
sOriginalApplication.onCreate();
}
}
private void replaceLoadedApkApplication() {
try {
// replace LoadedApk.java makeApplication() mActivityThread.mAllApplications.add(app);
ArrayList<Application> list = (ArrayList<Application>) XposedHelpers.getObjectField(getActivityThread(), "mAllApplications");
list.add(sOriginalApplication);
Object mBoundApplication = XposedHelpers.getObjectField(getActivityThread(), "mBoundApplication"); // AppBindData
Object loadedApkObj = XposedHelpers.getObjectField(mBoundApplication, "info"); // info
// replace LoadedApk.java makeApplication() mApplication = app;
XposedHelpers.setObjectField(loadedApkObj, "mApplication", sOriginalApplication);
} catch (Throwable e) {
Log.e(TAG, "replaceLoadedApkApplication", e);
}
}
private void replaceActivityThreadApplication() {
try {
XposedHelpers.setObjectField(getActivityThread(), "mInitialApplication", sOriginalApplication);
} catch (Throwable e) {
Log.e(TAG, "replaceActivityThreadApplication", e);
}
}
private Application createOriginalApplication() {
if (sOriginalApplication == null) {
try {
sOriginalApplication = (Application) appClassLoader.loadClass(originalApplicationName).newInstance();
} catch (Throwable e) {
Log.e(TAG, "createOriginalApplication", e);
}
}
return sOriginalApplication;
}
private void modifyApplicationInfoClassName() {
try {
Object mBoundApplication = XposedHelpers.getObjectField(getActivityThread(), "mBoundApplication"); // AppBindData
Object applicationInfoObj = XposedHelpers.getObjectField(mBoundApplication, "appInfo"); // info
XposedHelpers.setObjectField(applicationInfoObj, "className", originalApplicationName);
} catch (Throwable e) {
Log.e(TAG, "modifyApplicationInfoClassName", e);
}
}
public static Context createAppContext() {
try {

View File

@ -1,15 +1,13 @@
package org.lsposed.lspatch.appstub;
import android.annotation.SuppressLint;
import android.app.Application;
import android.content.Context;
import android.util.Log;
import java.io.ByteArrayOutputStream;
import java.lang.reflect.Method;
@SuppressLint("UnsafeDynamicallyLoadedCode")
public class LSPApplicationStub extends Application {
public class LSPApplicationStub {
private static byte[] dex = null;
@ -40,14 +38,4 @@ public class LSPApplicationStub extends Application {
Log.e("LSPatch", "load lspd error", e);
}
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(base);
}
}

View File

@ -83,10 +83,8 @@ public class LSPatch {
private List<String> modules = new ArrayList<>();
private static final String PROXY_APP_COMPONENT_FACTORY = "org.lsposed.lspatch.appstub.LSPAppComponentFactoryStub";
private static final String PROXY_APPLICATION = "org.lsposed.lspatch.appstub.LSPApplicationStub";
private static final String APP_COMPONENT_FACTORY_ASSET_PATH = "assets/original_app_component_factory.ini";
private static final String APPLICATION_NAME_ASSET_PATH = "assets/original_application_name.ini";
private static final String SIGNATURE_INFO_ASSET_PATH = "assets/original_signature_info.ini";
private static final String USE_MANAGER_CONTROL_PATH = "assets/use_manager.ini";
private static final String ORIGINAL_APK_ASSET_PATH = "assets/origin_apk.bin";
@ -213,16 +211,13 @@ public class LSPatch {
throw new PatchError("Provided file is not a valid apk");
// parse the app main application full name from the manifest file
ManifestParser.Triple triple = ManifestParser.parseManifestFile(manifestEntry.open());
if (triple == null)
ManifestParser.Pair pair = ManifestParser.parseManifestFile(manifestEntry.open());
if (pair == null)
throw new PatchError("Failed to parse AndroidManifest.xml");
String applicationName = triple.applicationName == null ? "" : triple.applicationName;
String appComponentFactory = triple.appComponentFactory == null ? "" : triple.appComponentFactory;
String appComponentFactory = pair.appComponentFactory == null ? "" : pair.appComponentFactory;
if (verbose) {
System.out.println("original application name: " + applicationName);
if (verbose)
System.out.println("original appComponentFactory class: " + appComponentFactory);
}
System.out.println("Patching apk...");
// modify manifest
@ -235,15 +230,6 @@ public class LSPatch {
// save original appComponentFactory name to asset file even its empty
try (var is = new ByteArrayInputStream(appComponentFactory.getBytes(StandardCharsets.UTF_8))) {
dstZFile.add(APP_COMPONENT_FACTORY_ASSET_PATH, is);
} catch (Throwable e) {
throw new PatchError("Error when saving appComponentFactory class", e);
}
// save original main application name to asset file even its empty
try (var is = new ByteArrayInputStream(applicationName.getBytes(StandardCharsets.UTF_8))) {
dstZFile.add(APPLICATION_NAME_ASSET_PATH, is);
} catch (Throwable e) {
throw new PatchError("Error when saving application name", e);
}
if (verbose)
@ -312,7 +298,7 @@ public class LSPatch {
System.out.println("Creating nested apk link...");
for (var moduleFile : modules) {
final var moduleManifest = new ManifestParser.Triple[]{null};
final var moduleManifest = new ManifestParser.Pair[]{null};
try (var nested = dstZFile.addNestedZip((module) -> {
var manifest = module.get(ANDROID_MANIFEST_XML);
if (manifest == null) {
@ -361,7 +347,6 @@ public class LSPatch {
if (!modules.isEmpty())
property.addApplicationAttribute(new AttributeItem("extractNativeLibs", true));
property.addApplicationAttribute(new AttributeItem(NodeValue.Application.DEBUGGABLE, debuggableFlag));
//property.addApplicationAttribute(new AttributeItem(NodeValue.Application.NAME, PROXY_APPLICATION));
property.addApplicationAttribute(new AttributeItem("appComponentFactory", PROXY_APP_COMPONENT_FACTORY));
// TODO: replace query_all with queries -> manager
property.addUsesPermission("android.permission.QUERY_ALL_PACKAGES");

View File

@ -14,10 +14,9 @@ import wind.v1.XmlPullParserException;
*/
public class ManifestParser {
public static Triple parseManifestFile(InputStream is) throws IOException {
public static Pair parseManifestFile(InputStream is) throws IOException {
AXmlResourceParser parser = new AXmlResourceParser();
String packageName = null;
String applicationName = null;
String appComponentFactory = null;
try {
parser.open(is);
@ -40,19 +39,13 @@ public class ManifestParser {
}
}
if ("application".equals(name)) {
if ("name".equals(attrName)) {
applicationName = parser.getAttributeValue(i);
}
if ("appComponentFactory".equals(attrName)) {
appComponentFactory = parser.getAttributeValue(i);
}
}
if (packageName != null && packageName.length() > 0 &&
applicationName != null && applicationName.length() > 0 &&
appComponentFactory != null && appComponentFactory.length() > 0) {
return new Triple(packageName, applicationName, appComponentFactory);
return new Pair(packageName, appComponentFactory);
}
}
} else if (type == XmlPullParser.END_TAG) {
@ -62,27 +55,25 @@ public class ManifestParser {
} catch (XmlPullParserException | IOException e) {
return null;
}
return new Triple(packageName, applicationName, appComponentFactory);
return new Pair(packageName, appComponentFactory);
}
/**
* Get the package name and the main application name from the manifest file
*/
public static Triple parseManifestFile(String filePath) throws IOException {
public static Pair parseManifestFile(String filePath) throws IOException {
File file = new File(filePath);
try (var is = new FileInputStream(file)) {
return parseManifestFile(is);
}
}
public static class Triple {
public static class Pair {
public String packageName;
public String applicationName;
public String appComponentFactory;
public Triple(String packageName, String applicationName, String appComponentFactory) {
public Pair(String packageName, String appComponentFactory) {
this.packageName = packageName;
this.applicationName = applicationName;
this.appComponentFactory = appComponentFactory;
}
}