Commit 786ed74f authored by swift_gan's avatar swift_gan

tweak xposed loadModule

parent 87f376ea
package com.swift.sandhook.xposedcompat; package com.swift.sandhook.xposedcompat;
import android.app.Application;
import android.content.Context; import android.content.Context;
import android.content.pm.ApplicationInfo;
import com.swift.sandhook.xposedcompat.classloaders.ComposeClassLoader;
import com.swift.sandhook.xposedcompat.classloaders.XposedClassLoader;
import com.swift.sandhook.xposedcompat.utils.ApplicationUtils;
import com.swift.sandhook.xposedcompat.utils.ProcessUtils;
import java.io.File; import java.io.File;
import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedInit;
import de.robv.android.xposed.callbacks.XC_LoadPackage;
public class XposedCompat { public class XposedCompat {
public static File cacheDir; public static File cacheDir;
public static Context context; public static Context context;
public static ClassLoader classLoader; public static ClassLoader classLoader;
public static boolean isFirstApplication; public static boolean isFirstApplication;
private static ClassLoader sandHookXposedClassLoader;
public static void loadModule(String apkPath, ClassLoader classLoader) {
XposedInit.loadModule(apkPath, classLoader);
}
public static void addXposedModuleCallback(IXposedHookLoadPackage module) {
XposedBridge.hookLoadPackage(new IXposedHookLoadPackage.Wrapper(module));
}
public static void callXposedModuleInit() throws Throwable {
//prepare LoadPackageParam
XC_LoadPackage.LoadPackageParam packageParam = new XC_LoadPackage.LoadPackageParam(XposedBridge.sLoadedPackageCallbacks);
Application application = ApplicationUtils.currentApplication();
if (application != null) {
if (packageParam.processName == null) {
packageParam.processName = ProcessUtils.getProcessName(application);
}
if (packageParam.classLoader == null) {
packageParam.classLoader = application.getClassLoader();
}
if (packageParam.appInfo == null) {
packageParam.appInfo = application.getApplicationInfo();
}
if (cacheDir == null) {
application.getCacheDir();
}
}
XC_LoadPackage.callAll(packageParam);
}
public static ClassLoader getSandHookXposedClassLoader(ClassLoader appOriginClassLoader, ClassLoader sandBoxHostClassLoader) {
if (sandHookXposedClassLoader != null) {
return sandHookXposedClassLoader;
} else {
ClassLoader xposedClassLoader = getXposedClassLoader(sandBoxHostClassLoader);
sandHookXposedClassLoader = new ComposeClassLoader(xposedClassLoader, appOriginClassLoader);
return sandHookXposedClassLoader;
}
}
private static XposedClassLoader xposedClassLoader;
public static synchronized ClassLoader getXposedClassLoader(ClassLoader hostClassLoader) {
if (xposedClassLoader == null) {
xposedClassLoader = new XposedClassLoader(hostClassLoader);
}
return xposedClassLoader;
}
} }
package com.swift.sandhook.xposedcompat.classloaders;
/**
* Created by weishu on 17/11/30.
*/
public class ComposeClassLoader extends ClassLoader {
private final ClassLoader mAppClassLoader;
public ComposeClassLoader(ClassLoader parent, ClassLoader appClassLoader) {
super(parent);
mAppClassLoader = appClassLoader;
}
@Override
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
Class clazz = null;
try {
clazz = mAppClassLoader.loadClass(name);
} catch (ClassNotFoundException e) {
// IGNORE.
}
if (clazz == null) {
clazz = super.loadClass(name, resolve);
}
if (clazz == null) {
throw new ClassNotFoundException();
}
return clazz;
}
}
package com.swift.sandhook.xposedcompat.classloaders;
/**
* XposedClassLoader: make sure load xposed class in sandhook
*/
public class XposedClassLoader extends ClassLoader {
private ClassLoader mHostClassLoader;
public XposedClassLoader(ClassLoader hostClassLoader) {
super(ClassLoader.getSystemClassLoader()); // parent is BootClassLoader
mHostClassLoader = hostClassLoader;
}
@Override
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
if (name.startsWith("de.robv.android.xposed") || name.startsWith("android")) {
return mHostClassLoader.loadClass(name);
}
return super.loadClass(name, resolve);
}
}
package com.swift.sandhook.xposedcompat.methodgen; package com.swift.sandhook.xposedcompat.methodgen;
import com.swift.sandhook.xposedcompat.XposedCompat; import com.swift.sandhook.xposedcompat.XposedCompat;
import com.swift.sandhook.xposedcompat.utils.DexLog;
import com.swift.sandhook.xposedcompat.utils.FileUtils;
import java.io.File; import java.io.File;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
......
...@@ -25,11 +25,11 @@ import java.util.concurrent.atomic.AtomicLong; ...@@ -25,11 +25,11 @@ import java.util.concurrent.atomic.AtomicLong;
import de.robv.android.xposed.XC_MethodHook; import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedBridge; import de.robv.android.xposed.XposedBridge;
import static com.swift.sandhook.xposedcompat.methodgen.DexMakerUtils.autoBoxIfNecessary; import static com.swift.sandhook.xposedcompat.utils.DexMakerUtils.autoBoxIfNecessary;
import static com.swift.sandhook.xposedcompat.methodgen.DexMakerUtils.autoUnboxIfNecessary; import static com.swift.sandhook.xposedcompat.utils.DexMakerUtils.autoUnboxIfNecessary;
import static com.swift.sandhook.xposedcompat.methodgen.DexMakerUtils.createResultLocals; import static com.swift.sandhook.xposedcompat.utils.DexMakerUtils.createResultLocals;
import static com.swift.sandhook.xposedcompat.methodgen.DexMakerUtils.getObjTypeIdIfPrimitive; import static com.swift.sandhook.xposedcompat.utils.DexMakerUtils.getObjTypeIdIfPrimitive;
import static com.swift.sandhook.xposedcompat.methodgen.DexMakerUtils.moveException; import static com.swift.sandhook.xposedcompat.utils.DexMakerUtils.moveException;
public class HookerDexMaker { public class HookerDexMaker {
......
package com.swift.sandhook.xposedcompat.methodgen;
import android.os.Process;
import android.text.TextUtils;
//import com.elderdrivers.riru.xposed.Main;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
public class ProcessUtils {
public static String getCurrentProcessName() {
String prettyName = null;//Main.sAppProcessName;
if (!TextUtils.isEmpty(prettyName)) {
return prettyName;
}
return getProcessName(Process.myPid());
}
/**
* a common solution from https://stackoverflow.com/a/21389402
* <p>
* use {@link com.elderdrivers.riru.xposed.Main#sAppProcessName} to get current process name
*/
public static String getProcessName(int pid) {
BufferedReader cmdlineReader = null;
try {
cmdlineReader = new BufferedReader(new InputStreamReader(
new FileInputStream(
"/proc/" + pid + "/cmdline"),
"iso-8859-1"));
int c;
StringBuilder processName = new StringBuilder();
while ((c = cmdlineReader.read()) > 0) {
processName.append((char) c);
}
return processName.toString();
} catch (Throwable throwable) {
DexLog.w("getProcessName: " + throwable.getMessage());
} finally {
try {
if (cmdlineReader != null) {
cmdlineReader.close();
}
} catch (Throwable throwable) {
DexLog.e("getProcessName: " + throwable.getMessage());
}
}
return "";
}
public static boolean isLastPidAlive(File lastPidFile) {
String lastPidInfo = FileUtils.readLine(lastPidFile);
try {
String[] split = lastPidInfo.split(":", 2);
return checkProcessAlive(Integer.parseInt(split[0]), split[1]);
} catch (Throwable throwable) {
DexLog.w("error when check last pid " + lastPidFile + ": " + throwable.getMessage());
return false;
}
}
public static void saveLastPidInfo(File lastPidFile, int pid, String processName) {
try {
if (!lastPidFile.exists()) {
lastPidFile.getParentFile().mkdirs();
lastPidFile.createNewFile();
}
} catch (Throwable throwable) {
}
FileUtils.writeLine(lastPidFile, pid + ":" + processName);
}
public static boolean checkProcessAlive(int pid, String processName) {
String existsPrcName = getProcessName(pid);
DexLog.w("checking pid alive: " + pid + ", " + processName + ", processName=" + existsPrcName);
return existsPrcName.equals(processName);
}
}
package com.swift.sandhook.xposedcompat.utils;
import android.app.Application;
import java.lang.reflect.Method;
public class ApplicationUtils {
private static Class classActivityThread;
private static Method currentApplicationMethod;
static Application application;
public static Application currentApplication() {
if (application != null)
return application;
if (currentApplicationMethod == null) {
try {
classActivityThread = Class.forName("android.app.ActivityThread");
currentApplicationMethod = classActivityThread.getDeclaredMethod("currentApplication");
} catch (Exception e) {
e.printStackTrace();
}
}
if (currentApplicationMethod == null)
return null;
try {
application = (Application) currentApplicationMethod.invoke(null);
} catch (Exception e) {
}
return application;
}
}
package com.swift.sandhook.xposedcompat.utils;
import android.os.Build;
import android.util.ArrayMap;
import com.swift.sandhook.xposedcompat.BuildConfig;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import dalvik.system.PathClassLoader;
public class ClassLoaderUtils {
public static final String DEXPATH = "/system/framework/edxposed.dex:/system/framework/eddalvikdx.dex:/system/framework/eddexmaker.dex";
public static void replaceParentClassLoader(ClassLoader appClassLoader) {
if (appClassLoader == null) {
DexLog.e("appClassLoader is null, you might be kidding me?");
return;
}
try {
ClassLoader curCL = ClassLoaderUtils.class.getClassLoader();
ClassLoader parent = appClassLoader;
ClassLoader lastChild = appClassLoader;
while (parent != null) {
ClassLoader tmp = parent.getParent();
if (tmp == curCL) {
DexLog.d("replacing has been done before, skip.");
return;
}
if (tmp == null) {
DexLog.d("before replacing =========================================>");
dumpClassLoaders(appClassLoader);
Field parentField = ClassLoader.class.getDeclaredField("parent");
parentField.setAccessible(true);
parentField.set(curCL, parent);
parentField.set(lastChild, curCL);
DexLog.d("after replacing ==========================================>");
dumpClassLoaders(appClassLoader);
}
lastChild = parent;
parent = tmp;
}
} catch (Throwable throwable) {
DexLog.e("error when replacing class loader.", throwable);
}
}
private static void dumpClassLoaders(ClassLoader classLoader) {
if (BuildConfig.DEBUG) {
while (classLoader != null) {
DexLog.d(classLoader + " =>");
classLoader = classLoader.getParent();
}
}
}
public static List<ClassLoader> getAppClassLoader() {
List<ClassLoader> cacheLoaders = new ArrayList<>(0);
try {
DexLog.d("start getting app classloader");
Class appLoadersClass = Class.forName("android.app.ApplicationLoaders");
Field loadersField = appLoadersClass.getDeclaredField("gApplicationLoaders");
loadersField.setAccessible(true);
Object loaders = loadersField.get(null);
Field mLoaderMapField = loaders.getClass().getDeclaredField("mLoaders");
mLoaderMapField.setAccessible(true);
ArrayMap<String, ClassLoader> mLoaderMap = (ArrayMap<String, ClassLoader>) mLoaderMapField.get(loaders);
DexLog.d("mLoaders size = " + mLoaderMap.size());
cacheLoaders = new ArrayList<>(mLoaderMap.values());
} catch (Exception ex) {
DexLog.e("error get app class loader.", ex);
}
return cacheLoaders;
}
private static HashSet<ClassLoader> classLoaders = new HashSet<>();
public static boolean addPathToClassLoader(ClassLoader classLoader) {
if (!(classLoader instanceof PathClassLoader)) {
DexLog.w(classLoader + " is not a BaseDexClassLoader!!!");
return false;
}
if (classLoaders.contains(classLoader)) {
DexLog.d(classLoader + " has been hooked before");
return true;
}
try {
PathClassLoader baseDexClassLoader = (PathClassLoader) classLoader;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
//baseDexClassLoader.addDexPath(DEXPATH);
} else {
DexUtils.injectDexAtFirst(DEXPATH, baseDexClassLoader);
}
classLoaders.add(classLoader);
return true;
} catch (Throwable throwable) {
DexLog.e("error when addPath to ClassLoader: " + classLoader, throwable);
}
return false;
}
}
package com.swift.sandhook.xposedcompat.methodgen; package com.swift.sandhook.xposedcompat.utils;
import android.util.Log; import android.util.Log;
......
package com.swift.sandhook.xposedcompat.methodgen; package com.swift.sandhook.xposedcompat.utils;
import com.android.dx.Code; import com.android.dx.Code;
import com.android.dx.Local; import com.android.dx.Local;
import com.android.dx.TypeId; import com.android.dx.TypeId;
......
package com.swift.sandhook.xposedcompat.utils;
import android.annotation.TargetApi;
import android.os.Build;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import dalvik.system.BaseDexClassLoader;
import dalvik.system.DexClassLoader;
/**
* For 6.0 only.
*/
@TargetApi(Build.VERSION_CODES.M)
public class DexUtils {
public static void injectDexAtFirst(String dexPath, BaseDexClassLoader classLoader) throws NoSuchFieldException, IllegalAccessException, ClassNotFoundException {
DexClassLoader dexClassLoader = new DexClassLoader(dexPath, null, dexPath, classLoader);
Object baseDexElements = getDexElements(getPathList(classLoader));
Object newDexElements = getDexElements(getPathList(dexClassLoader));
Object allDexElements = combineArray(newDexElements, baseDexElements);
Object pathList = getPathList(classLoader);
setField(pathList, pathList.getClass(), "dexElements", allDexElements);
}
private static Object getDexElements(Object paramObject)
throws IllegalArgumentException, NoSuchFieldException, IllegalAccessException {
return getField(paramObject, paramObject.getClass(), "dexElements");
}
private static Object getPathList(Object baseDexClassLoader)
throws IllegalArgumentException, NoSuchFieldException, IllegalAccessException, ClassNotFoundException {
return getField(baseDexClassLoader, Class.forName("dalvik.system.BaseDexClassLoader"), "pathList");
}
private static Object combineArray(Object firstArray, Object secondArray) {
Class<?> localClass = firstArray.getClass().getComponentType();
int firstArrayLength = Array.getLength(firstArray);
int allLength = firstArrayLength + Array.getLength(secondArray);
Object result = Array.newInstance(localClass, allLength);
for (int k = 0; k < allLength; ++k) {
if (k < firstArrayLength) {
Array.set(result, k, Array.get(firstArray, k));
} else {
Array.set(result, k, Array.get(secondArray, k - firstArrayLength));
}
}
return result;
}
public static Object getField(Object obj, Class<?> cl, String field)
throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
Field localField = cl.getDeclaredField(field);
localField.setAccessible(true);
return localField.get(obj);
}
public static void setField(Object obj, Class<?> cl, String field, Object value)
throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
Field localField = cl.getDeclaredField(field);
localField.setAccessible(true);
localField.set(obj, value);
}
}
\ No newline at end of file
package com.swift.sandhook.xposedcompat.methodgen; package com.swift.sandhook.xposedcompat.utils;
import android.os.Build; import android.os.Build;
import android.text.TextUtils; import android.text.TextUtils;
......
package com.swift.sandhook.xposedcompat; package com.swift.sandhook.xposedcompat.utils;
import android.app.ActivityManager; import android.app.ActivityManager;
import android.content.Context; import android.content.Context;
......
package de.robv.android.xposed; package de.robv.android.xposed;
//import android.annotation.SuppressLint; import android.annotation.SuppressLint;
//import android.app.AndroidAppHelper; import android.os.Build;
//import android.os.Build; import android.util.Log;
//import android.text.TextUtils;
//import android.util.Log; import java.io.BufferedReader;
// import java.io.File;
//import com.android.internal.os.ZygoteInit; import java.io.IOException;
//import com.elderdrivers.riru.xposed.BuildConfig; import java.io.InputStream;
//import com.elderdrivers.riru.xposed.entry.Router; import java.io.InputStreamReader;
//import com.elderdrivers.riru.xposed.util.Utils; import java.util.HashSet;
// import java.util.concurrent.atomic.AtomicBoolean;
//import java.io.BufferedReader; import java.util.zip.ZipEntry;
//import java.io.File; import java.util.zip.ZipFile;
//import java.io.IOException;
//import java.io.InputStream; import dalvik.system.DexFile;
//import java.io.InputStreamReader; import dalvik.system.PathClassLoader;
//import java.util.HashSet; import de.robv.android.xposed.services.BaseService;
//import java.util.concurrent.atomic.AtomicBoolean;
//import java.util.zip.ZipEntry; import static de.robv.android.xposed.XposedHelpers.closeSilently;
//import java.util.zip.ZipFile;
//
//import dalvik.system.DexFile;
//import dalvik.system.PathClassLoader;
//import de.robv.android.xposed.services.BaseService;
//
//import static com.elderdrivers.riru.xposed.entry.hooker.XposedBlackListHooker.BLACK_LIST_PACKAGE_NAME;
//import static de.robv.android.xposed.XposedHelpers.closeSilently;
//import static de.robv.android.xposed.XposedHelpers.findClass;
//import static de.robv.android.xposed.XposedHelpers.findFieldIfExists;
//import static de.robv.android.xposed.XposedHelpers.setStaticBooleanField;
//import static de.robv.android.xposed.XposedHelpers.setStaticLongField;
public final class XposedInit { public final class XposedInit {
// private static final String TAG = XposedBridge.TAG; private static final String TAG = XposedBridge.TAG;
// private static boolean startsSystemServer = false; private static boolean startsSystemServer = false;
// private static final String startClassName = ""; // ed: no support for tool process anymore private static final String startClassName = ""; // ed: no support for tool process anymore
//
// public static final String INSTALLER_PACKAGE_NAME = "com.solohsu.android.edxp.manager"; public static final String INSTALLER_PACKAGE_NAME = "com.solohsu.android.edxp.manager";
// public static final String INSTALLER_LEGACY_PACKAGE_NAME = "de.robv.android.xposed.installer"; public static final String INSTALLER_LEGACY_PACKAGE_NAME = "de.robv.android.xposed.installer";
// @SuppressLint("SdCardPath") @SuppressLint("SdCardPath")
// public static final String INSTALLER_DATA_BASE_DIR = Build.VERSION.SDK_INT >= 24 public static final String INSTALLER_DATA_BASE_DIR = Build.VERSION.SDK_INT >= 24
// ? "/data/user_de/0/" + INSTALLER_PACKAGE_NAME + "/" ? "/data/user_de/0/" + INSTALLER_PACKAGE_NAME + "/"
// : "/data/data/" + INSTALLER_PACKAGE_NAME + "/"; : "/data/data/" + INSTALLER_PACKAGE_NAME + "/";
// private static final String INSTANT_RUN_CLASS = "com.android.tools.fd.runtime.BootstrapApplication"; private static final String INSTANT_RUN_CLASS = "com.android.tools.fd.runtime.BootstrapApplication";
// // TODO not supported yet // TODO not supported yet
// private static boolean disableResources = true; private static boolean disableResources = true;
// private static final String[] XRESOURCES_CONFLICTING_PACKAGES = {"com.sygic.aura"}; private static final String[] XRESOURCES_CONFLICTING_PACKAGES = {"com.sygic.aura"};
//
// private XposedInit() { private XposedInit() {
// } }
//
// private static volatile AtomicBoolean bootstrapHooked = new AtomicBoolean(false); private static volatile AtomicBoolean bootstrapHooked = new AtomicBoolean(false);
//
// /** /**
// * Hook some methods which we want to create an easier interface for developers. * Hook some methods which we want to create an easier interface for developers.
// */ */
// /*package*/ /*package*/
// public static void initForZygote(boolean isSystem) throws Throwable { // public static void initForZygote(boolean isSystem) throws Throwable {
// if (!bootstrapHooked.compareAndSet(false, true)) { // if (!bootstrapHooked.compareAndSet(false, true)) {
// return; // return;
...@@ -77,175 +65,166 @@ public final class XposedInit { ...@@ -77,175 +65,166 @@ public final class XposedInit {
// } // }
// } // }
// } // }
//
// /*package*/ /*package*/
// static void hookResources() throws Throwable { static void hookResources() throws Throwable {
// // ed: not for now // ed: not for now
// } }
//
// private static boolean needsToCloseFilesForFork() { private static boolean needsToCloseFilesForFork() {
// // ed: we always start to do our work after forking finishes // ed: we always start to do our work after forking finishes
// return false; return false;
// } }
//
// /** /**
// * Try to load all modules defined in <code>INSTALLER_DATA_BASE_DIR/conf/modules.list</code> * Try to load all modules defined in <code>INSTALLER_DATA_BASE_DIR/conf/modules.list</code>
// */ */
// private static volatile AtomicBoolean modulesLoaded = new AtomicBoolean(false); private static volatile AtomicBoolean modulesLoaded = new AtomicBoolean(false);
//
// public static void loadModules() throws IOException { public static void loadModules() throws IOException {
// if (!modulesLoaded.compareAndSet(false, true)) { if (!modulesLoaded.compareAndSet(false, true)) {
// return; return;
// } }
// final String filename = INSTALLER_DATA_BASE_DIR + "conf/modules.list"; final String filename = INSTALLER_DATA_BASE_DIR + "conf/modules.list";
// BaseService service = SELinuxHelper.getAppDataFileService(); BaseService service = SELinuxHelper.getAppDataFileService();
// if (!service.checkFileExists(filename)) { if (!service.checkFileExists(filename)) {
// Log.e(TAG, "Cannot load any modules because " + filename + " was not found"); Log.e(TAG, "Cannot load any modules because " + filename + " was not found");
// return; return;
// } }
//
// ClassLoader topClassLoader = XposedBridge.BOOTCLASSLOADER; ClassLoader topClassLoader = XposedBridge.BOOTCLASSLOADER;
// ClassLoader parent; ClassLoader parent;
// while ((parent = topClassLoader.getParent()) != null) { while ((parent = topClassLoader.getParent()) != null) {
// topClassLoader = parent; topClassLoader = parent;
// } }
//
// InputStream stream = service.getFileInputStream(filename); InputStream stream = service.getFileInputStream(filename);
// BufferedReader apks = new BufferedReader(new InputStreamReader(stream)); BufferedReader apks = new BufferedReader(new InputStreamReader(stream));
// String apk; String apk;
// while ((apk = apks.readLine()) != null) { while ((apk = apks.readLine()) != null) {
// loadModule(apk, topClassLoader); loadModule(apk, topClassLoader);
// } }
// apks.close(); apks.close();
// } }
//
//
// /** /**
// * Load a module from an APK by calling the init(String) method for all classes defined * Load a module from an APK by calling the init(String) method for all classes defined
// * in <code>assets/xposed_init</code>. * in <code>assets/xposed_init</code>.
// */ */
// private static void loadModule(String apk, ClassLoader topClassLoader) { public static void loadModule(String apk, ClassLoader topClassLoader) {
// if (BuildConfig.DEBUG)
// Log.i(TAG, "Loading modules from " + apk); if (!new File(apk).exists()) {
// Log.e(TAG, " File does not exist");
// if (!TextUtils.isEmpty(apk) && apk.contains(BLACK_LIST_PACKAGE_NAME)) { return;
// if (BuildConfig.DEBUG) }
// Log.i(TAG, "We are going to take over black list's job...");
// return; DexFile dexFile;
// } try {
// dexFile = new DexFile(apk);
// if (!new File(apk).exists()) { } catch (IOException e) {
// Log.e(TAG, " File does not exist"); Log.e(TAG, " Cannot load module", e);
// return; return;
// } }
//
// DexFile dexFile; if (dexFile.loadClass(INSTANT_RUN_CLASS, topClassLoader) != null) {
// try { Log.e(TAG, " Cannot load module, please disable \"Instant Run\" in Android Studio.");
// dexFile = new DexFile(apk); closeSilently(dexFile);
// } catch (IOException e) { return;
// Log.e(TAG, " Cannot load module", e); }
// return;
// } if (dexFile.loadClass(XposedBridge.class.getName(), topClassLoader) != null) {
// Log.e(TAG, " Cannot load module:");
// if (dexFile.loadClass(INSTANT_RUN_CLASS, topClassLoader) != null) { Log.e(TAG, " The Xposed API classes are compiled into the module's APK.");
// Log.e(TAG, " Cannot load module, please disable \"Instant Run\" in Android Studio."); Log.e(TAG, " This may cause strange issues and must be fixed by the module developer.");
// closeSilently(dexFile); Log.e(TAG, " For details, see: http://api.xposed.info/using.html");
// return; closeSilently(dexFile);
// } return;
// }
// if (dexFile.loadClass(XposedBridge.class.getName(), topClassLoader) != null) {
// Log.e(TAG, " Cannot load module:"); closeSilently(dexFile);
// Log.e(TAG, " The Xposed API classes are compiled into the module's APK.");
// Log.e(TAG, " This may cause strange issues and must be fixed by the module developer."); ZipFile zipFile = null;
// Log.e(TAG, " For details, see: http://api.xposed.info/using.html"); InputStream is;
// closeSilently(dexFile); try {
// return; zipFile = new ZipFile(apk);
// } ZipEntry zipEntry = zipFile.getEntry("assets/xposed_init");
// if (zipEntry == null) {
// closeSilently(dexFile); Log.e(TAG, " assets/xposed_init not found in the APK");
// closeSilently(zipFile);
// ZipFile zipFile = null; return;
// InputStream is; }
// try { is = zipFile.getInputStream(zipEntry);
// zipFile = new ZipFile(apk); } catch (IOException e) {
// ZipEntry zipEntry = zipFile.getEntry("assets/xposed_init"); Log.e(TAG, " Cannot read assets/xposed_init in the APK", e);
// if (zipEntry == null) { closeSilently(zipFile);
// Log.e(TAG, " assets/xposed_init not found in the APK"); return;
// closeSilently(zipFile); }
// return;
// } ClassLoader mcl = new PathClassLoader(apk, XposedInit.class.getClassLoader());
// is = zipFile.getInputStream(zipEntry); BufferedReader moduleClassesReader = new BufferedReader(new InputStreamReader(is));
// } catch (IOException e) { try {
// Log.e(TAG, " Cannot read assets/xposed_init in the APK", e); String moduleClassName;
// closeSilently(zipFile); while ((moduleClassName = moduleClassesReader.readLine()) != null) {
// return; moduleClassName = moduleClassName.trim();
// } if (moduleClassName.isEmpty() || moduleClassName.startsWith("#"))
// continue;
// ClassLoader mcl = new PathClassLoader(apk, XposedInit.class.getClassLoader());
// BufferedReader moduleClassesReader = new BufferedReader(new InputStreamReader(is)); try {
// try { Log.i(TAG, " Loading class " + moduleClassName);
// String moduleClassName; Class<?> moduleClass = mcl.loadClass(moduleClassName);
// while ((moduleClassName = moduleClassesReader.readLine()) != null) {
// moduleClassName = moduleClassName.trim(); if (!IXposedMod.class.isAssignableFrom(moduleClass)) {
// if (moduleClassName.isEmpty() || moduleClassName.startsWith("#")) Log.e(TAG, " This class doesn't implement any sub-interface of IXposedMod, skipping it");
// continue; continue;
// } else if (disableResources && IXposedHookInitPackageResources.class.isAssignableFrom(moduleClass)) {
// try { Log.e(TAG, " This class requires resource-related hooks (which are disabled), skipping it.");
// if (BuildConfig.DEBUG) continue;
// Log.i(TAG, " Loading class " + moduleClassName); }
// Class<?> moduleClass = mcl.loadClass(moduleClassName);
// final Object moduleInstance = moduleClass.newInstance();
// if (!IXposedMod.class.isAssignableFrom(moduleClass)) {
// Log.e(TAG, " This class doesn't implement any sub-interface of IXposedMod, skipping it"); if (true) {
// continue;
// } else if (disableResources && IXposedHookInitPackageResources.class.isAssignableFrom(moduleClass)) { //fake
// Log.e(TAG, " This class requires resource-related hooks (which are disabled), skipping it."); if (moduleInstance instanceof IXposedHookZygoteInit) {
// continue; IXposedHookZygoteInit.StartupParam param = new IXposedHookZygoteInit.StartupParam();
// } param.modulePath = apk;
// param.startsSystemServer = false;
// final Object moduleInstance = moduleClass.newInstance(); ((IXposedHookZygoteInit) moduleInstance).initZygote(param);
// if (XposedBridge.isZygote) { }
// if (moduleInstance instanceof IXposedHookZygoteInit) {
// IXposedHookZygoteInit.StartupParam param = new IXposedHookZygoteInit.StartupParam(); if (moduleInstance instanceof IXposedHookLoadPackage)
// param.modulePath = apk; XposedBridge.hookLoadPackage(new IXposedHookLoadPackage.Wrapper((IXposedHookLoadPackage) moduleInstance));
// param.startsSystemServer = startsSystemServer;
// ((IXposedHookZygoteInit) moduleInstance).initZygote(param); //not support now
// } //so off
// if (moduleInstance instanceof IXposedHookInitPackageResources) {
// if (moduleInstance instanceof IXposedHookLoadPackage) throw new UnsupportedOperationException("can not hook resource!");
// XposedBridge.hookLoadPackage(new IXposedHookLoadPackage.Wrapper((IXposedHookLoadPackage) moduleInstance)); //XposedBridge.hookInitPackageResources(new IXposedHookInitPackageResources.Wrapper((IXposedHookInitPackageResources) moduleInstance));
// }
// if (moduleInstance instanceof IXposedHookInitPackageResources) } else {
// XposedBridge.hookInitPackageResources(new IXposedHookInitPackageResources.Wrapper((IXposedHookInitPackageResources) moduleInstance)); //not support now
// } else { //so off
// if (moduleInstance instanceof IXposedHookCmdInit) { if (moduleInstance instanceof IXposedHookCmdInit) {
throw new UnsupportedOperationException("can not hook cmd!");
// IXposedHookCmdInit.StartupParam param = new IXposedHookCmdInit.StartupParam(); // IXposedHookCmdInit.StartupParam param = new IXposedHookCmdInit.StartupParam();
// param.modulePath = apk; // param.modulePath = apk;
// param.startClassName = startClassName; // param.startClassName = startClassName;
// ((IXposedHookCmdInit) moduleInstance).initCmdApp(param); // ((IXposedHookCmdInit) moduleInstance).initCmdApp(param);
// } }
// } }
// } catch (Throwable t) { } catch (Throwable t) {
// Log.e(TAG, " Failed to load class " + moduleClassName, t); Log.e(TAG, " Failed to load class " + moduleClassName, t);
// } }
// } }
// } catch (IOException e) { } catch (IOException e) {
// Log.e(TAG, " Failed to load module from " + apk, e); Log.e(TAG, " Failed to load module from " + apk, e);
// } finally { } finally {
// closeSilently(is); closeSilently(is);
// closeSilently(zipFile); closeSilently(zipFile);
// } }
// } }
//
// public final static HashSet<String> loadedPackagesInProcess = new HashSet<>(1); public final static HashSet<String> loadedPackagesInProcess = new HashSet<>(1);
//
// public static void logD(String prefix) {
// Utils.logD(String.format("%s: pkg=%s, prc=%s", prefix, AndroidAppHelper.currentPackageName(),
// AndroidAppHelper.currentProcessName()));
// }
//
// public static void logE(String prefix, Throwable throwable) {
// Utils.logE(String.format("%s: pkg=%s, prc=%s", prefix, AndroidAppHelper.currentPackageName(),
// AndroidAppHelper.currentProcessName()), throwable);
// }
} }
...@@ -2,7 +2,7 @@ package de.robv.android.xposed.callbacks; ...@@ -2,7 +2,7 @@ package de.robv.android.xposed.callbacks;
import android.content.pm.ApplicationInfo; import android.content.pm.ApplicationInfo;
import com.swift.sandhook.xposedcompat.ProcessUtils; import com.swift.sandhook.xposedcompat.utils.ProcessUtils;
import com.swift.sandhook.xposedcompat.XposedCompat; import com.swift.sandhook.xposedcompat.XposedCompat;
import de.robv.android.xposed.IXposedHookLoadPackage; import de.robv.android.xposed.IXposedHookLoadPackage;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment