Remove useless code (Abandon support for Android 8.1) (#21)
This commit is contained in:
parent
14ab3bbd56
commit
4b75a17a24
|
|
@ -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 {
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue