110 lines
3.8 KiB
Java
110 lines
3.8 KiB
Java
package com.swift.sandhook.xposedcompat;
|
|
|
|
import android.annotation.SuppressLint;
|
|
import android.os.Process;
|
|
import android.text.TextUtils;
|
|
|
|
import com.swift.sandhook.SandHook;
|
|
import com.swift.sandhook.xposedcompat.classloaders.ComposeClassLoader;
|
|
import com.swift.sandhook.xposedcompat.methodgen.SandHookXposedBridge;
|
|
import com.swift.sandhook.xposedcompat.utils.ApplicationUtils;
|
|
import com.swift.sandhook.xposedcompat.utils.FileUtils;
|
|
import com.swift.sandhook.xposedcompat.utils.ProcessUtils;
|
|
|
|
import java.io.File;
|
|
import java.lang.reflect.Member;
|
|
|
|
import de.robv.android.xposed.XposedBridge;
|
|
|
|
import static com.elderdrivers.riru.edxp.util.ProcessUtils.PER_USER_RANGE;
|
|
import static com.swift.sandhook.xposedcompat.utils.FileUtils.IS_USING_PROTECTED_STORAGE;
|
|
|
|
public class XposedCompat {
|
|
|
|
public static volatile String appDataDir;
|
|
|
|
// TODO initialize these variables
|
|
public static volatile File cacheDir;
|
|
public static volatile ClassLoader classLoader;
|
|
|
|
//try to use internal stub hooker & backup method to speed up hook
|
|
public static volatile boolean useInternalStub = true;
|
|
public static volatile boolean useNewCallBackup = true;
|
|
public static volatile boolean retryWhenCallOriginError = false;
|
|
|
|
private static ClassLoader sandHookXposedClassLoader;
|
|
|
|
public static void addHookers(ClassLoader classLoader, Class[] hookers) {
|
|
if (hookers == null)
|
|
return;
|
|
for (Class hooker:hookers) {
|
|
try {
|
|
SandHook.addHookClass(classLoader, hooker);
|
|
} catch (Throwable throwable) {}
|
|
}
|
|
}
|
|
|
|
public static File getCacheDir() {
|
|
if (cacheDir == null) {
|
|
String fixedAppDataDir = getDataPathPrefix() + getPackageName(appDataDir) + "/";
|
|
cacheDir = new File(fixedAppDataDir, "/cache/sandhook/"
|
|
+ ProcessUtils.getProcessName().replace(":", "_") + "/");
|
|
}
|
|
return cacheDir;
|
|
}
|
|
|
|
public static ClassLoader getClassLoader() {
|
|
if (classLoader == null) {
|
|
classLoader = getSandHookXposedClassLoader(ApplicationUtils.currentApplication().getClassLoader(), XposedCompat.class.getClassLoader());
|
|
}
|
|
return classLoader;
|
|
}
|
|
|
|
public static synchronized void hookMethod(Member hookMethod, XposedBridge.AdditionalHookInfo additionalHookInfo) {
|
|
SandHookXposedBridge.hookMethod(hookMethod, additionalHookInfo);
|
|
}
|
|
|
|
public static ClassLoader getSandHookXposedClassLoader(ClassLoader appOriginClassLoader, ClassLoader sandBoxHostClassLoader) {
|
|
if (sandHookXposedClassLoader != null) {
|
|
return sandHookXposedClassLoader;
|
|
} else {
|
|
sandHookXposedClassLoader = new ComposeClassLoader(sandBoxHostClassLoader, appOriginClassLoader);
|
|
return sandHookXposedClassLoader;
|
|
}
|
|
}
|
|
|
|
public static boolean clearCache() {
|
|
try {
|
|
FileUtils.delete(getCacheDir());
|
|
getCacheDir().mkdirs();
|
|
return true;
|
|
} catch (Throwable throwable) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public static void clearOatCache() {
|
|
SandHookXposedBridge.clearOatFile();
|
|
}
|
|
|
|
public static String getPackageName(String dataDir) {
|
|
if (TextUtils.isEmpty(dataDir)) {
|
|
return "";
|
|
}
|
|
int lastIndex = dataDir.lastIndexOf("/");
|
|
if (lastIndex < 0) {
|
|
return dataDir;
|
|
}
|
|
return dataDir.substring(lastIndex + 1);
|
|
}
|
|
|
|
// FIXME: Although multi-users is considered here, but compat mode doesn't support other users' apps on Oreo and later yet.
|
|
@SuppressLint("SdCardPath")
|
|
public static String getDataPathPrefix() {
|
|
int userId = Process.myUid() / PER_USER_RANGE;
|
|
String format = IS_USING_PROTECTED_STORAGE ? "/data/user_de/%d/" : "/data/user/%d/";
|
|
return String.format(format, userId);
|
|
}
|
|
|
|
}
|