SandHook: Cherry-pick from branch sandhook
e027b877732e90f41bf5ac48b5e652909ffc2140, 66d21874edb5b918ba16b2c8e3aebb80cc1558ff, 713e2e3b03038d87f2349a642d52a74c8695a6a9, eccdb67251c39910ff22f968597f9a309c9601b7, 9af84bdf02bd4321e9c1bd54b39d9638aa43a810, 68ce389a48c8bd5ae4eeefdbbc2e74363d103d89, dd7960c771a7c0ad453b5073df05c80a988ddb5e, 061288a6b835207c4e9e3948b366f2aba1d85d24, 8d2ea787e70e6e992581e54053f080aacafd9e25, 227fc5a43c94e8a0a976050fc1f2f43fdc9b0047
This commit is contained in:
parent
d546ecd81c
commit
d3cf2246ec
|
|
@ -12,4 +12,8 @@
|
||||||
|
|
||||||
#define ENTRY_CLASS_NAME "com.elderdrivers.riru.edxp.Main"
|
#define ENTRY_CLASS_NAME "com.elderdrivers.riru.edxp.Main"
|
||||||
|
|
||||||
|
#define CLASS_SAND_HOOK "com.swift.sandhook.SandHook"
|
||||||
|
|
||||||
|
#define CLASS_NEVER_CALL "com.swift.sandhook.ClassNeverCall"
|
||||||
|
|
||||||
#endif //CONFIG_H
|
#endif //CONFIG_H
|
||||||
|
|
@ -168,6 +168,29 @@ void loadDexAndInit(JNIEnv *env, const char *dexPath) {
|
||||||
} else {
|
} else {
|
||||||
LOGE("HookEntry class is null. %d", getpid());
|
LOGE("HookEntry class is null. %d", getpid());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//load lib sandhook
|
||||||
|
void* lib_sandhook;
|
||||||
|
if (sizeof(void*) == 8) {
|
||||||
|
lib_sandhook = dlopen("/system/lib64/libsandhook.edxp.so", RTLD_NOW);
|
||||||
|
} else {
|
||||||
|
lib_sandhook = dlopen("/system/lib/libsandhook.edxp.so", RTLD_NOW);
|
||||||
|
}
|
||||||
|
if (!lib_sandhook) {
|
||||||
|
LOGW("libsandhook open failed. %s", dlerror());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
bool* (*jni_load)(JNIEnv*, jclass, jclass) = reinterpret_cast<bool *(*)(JNIEnv *, jclass,
|
||||||
|
jclass)>(dlsym(lib_sandhook, "JNI_Load_Ex"));
|
||||||
|
|
||||||
|
jclass sandhook_class = findClassFromLoader(env, myClassLoader, CLASS_SAND_HOOK);
|
||||||
|
jclass nevercall_class = findClassFromLoader(env, myClassLoader, CLASS_NEVER_CALL);
|
||||||
|
if (!sandhook_class || !nevercall_class) { // fail-fast
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!jni_load(env, sandhook_class, nevercall_class)) {
|
||||||
|
LOGE("SandHook: HookEntry class error. %d", getpid());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
jstring getThrowableMessage(JNIEnv *env, jobject throwable) {
|
jstring getThrowableMessage(JNIEnv *env, jobject throwable) {
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ dependencies {
|
||||||
compileOnly files("libs/framework-stub.jar")
|
compileOnly files("libs/framework-stub.jar")
|
||||||
implementation project(':edxp-common')
|
implementation project(':edxp-common')
|
||||||
implementation project(':xposed-bridge')
|
implementation project(':xposed-bridge')
|
||||||
implementation 'com.swift.sandhook:hooklib:3.0.1'
|
implementation 'com.swift.sandhook:hooklib:3.2.2'
|
||||||
compileOnly project(':dexmaker')
|
compileOnly project(':dexmaker')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -60,8 +60,9 @@ TEMP_STUB_INFO = """
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
STUB_SIZES = [10,20,30,30,30,30,30,20,10,10,5,5,3]
|
STUB_SIZES_32 = [10,20,30,30,30,30,30,20,10,10,5,5,3]
|
||||||
HAS_BACKUP = False;
|
STUB_SIZES_64 = [10,20,30,30,30,30,50,50]
|
||||||
|
HAS_BACKUP = False
|
||||||
|
|
||||||
|
|
||||||
def getMethodId(args, index):
|
def getMethodId(args, index):
|
||||||
|
|
@ -126,20 +127,29 @@ def genCallOriginClass(is64Bit, args, index):
|
||||||
method = TEMP_STUB_CALL_ORIGIN_CLASS % (getCallOriginClassName(args, index), getMethodBackupName(index), genArgsListForCallOriginMethod(is64Bit, args))
|
method = TEMP_STUB_CALL_ORIGIN_CLASS % (getCallOriginClassName(args, index), getMethodBackupName(index), genArgsListForCallOriginMethod(is64Bit, args))
|
||||||
return method
|
return method
|
||||||
|
|
||||||
def genStubInfo():
|
def genStubInfo32():
|
||||||
hasStub = "true" if HAS_BACKUP else "false"
|
hasStub = "true" if HAS_BACKUP else "false"
|
||||||
stubSizes = ""
|
stubSizes = ""
|
||||||
for args in range(len(STUB_SIZES)):
|
for args in range(len(STUB_SIZES_32)):
|
||||||
if (args != 0):
|
if (args != 0):
|
||||||
stubSizes += ", "
|
stubSizes += ", "
|
||||||
stubSizes += str(STUB_SIZES[args])
|
stubSizes += str(STUB_SIZES_32[args])
|
||||||
|
return TEMP_STUB_INFO % (hasStub, stubSizes)
|
||||||
|
|
||||||
|
def genStubInfo64():
|
||||||
|
hasStub = "true" if HAS_BACKUP else "false"
|
||||||
|
stubSizes = ""
|
||||||
|
for args in range(len(STUB_SIZES_64)):
|
||||||
|
if (args != 0):
|
||||||
|
stubSizes += ", "
|
||||||
|
stubSizes += str(STUB_SIZES_64[args])
|
||||||
return TEMP_STUB_INFO % (hasStub, stubSizes)
|
return TEMP_STUB_INFO % (hasStub, stubSizes)
|
||||||
|
|
||||||
def gen32Stub(packageDir):
|
def gen32Stub(packageDir):
|
||||||
class_content = genStubInfo()
|
class_content = genStubInfo32()
|
||||||
class_name = STUB_FILE_NAME + "32"
|
class_name = STUB_FILE_NAME + "32"
|
||||||
for args in range(len(STUB_SIZES)):
|
for args in range(len(STUB_SIZES_32)):
|
||||||
for index in range(STUB_SIZES[args]):
|
for index in range(STUB_SIZES_32[args]):
|
||||||
class_content += """\n\n\t//stub of arg size %d, index %d""" % (args, index)
|
class_content += """\n\n\t//stub of arg size %d, index %d""" % (args, index)
|
||||||
class_content += genHookMethod(False, args, index)
|
class_content += genHookMethod(False, args, index)
|
||||||
if HAS_BACKUP:
|
if HAS_BACKUP:
|
||||||
|
|
@ -155,10 +165,10 @@ def gen32Stub(packageDir):
|
||||||
|
|
||||||
|
|
||||||
def gen64Stub(packageDir):
|
def gen64Stub(packageDir):
|
||||||
class_content = genStubInfo()
|
class_content = genStubInfo64()
|
||||||
class_name = STUB_FILE_NAME + "64"
|
class_name = STUB_FILE_NAME + "64"
|
||||||
for args in range(len(STUB_SIZES)):
|
for args in range(len(STUB_SIZES_64)):
|
||||||
for index in range(STUB_SIZES[args]):
|
for index in range(STUB_SIZES_64[args]):
|
||||||
class_content += """\n\n\t//stub of arg size %d, index %d""" % (args, index)
|
class_content += """\n\n\t//stub of arg size %d, index %d""" % (args, index)
|
||||||
class_content += genHookMethod(True, args, index)
|
class_content += genHookMethod(True, args, index)
|
||||||
if HAS_BACKUP:
|
if HAS_BACKUP:
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ import com.elderdrivers.riru.edxp.sandhook.core.HookMethodResolver;
|
||||||
import com.elderdrivers.riru.edxp.sandhook.entry.Router;
|
import com.elderdrivers.riru.edxp.sandhook.entry.Router;
|
||||||
import com.elderdrivers.riru.edxp.sandhook.proxy.BlackWhiteListProxy;
|
import com.elderdrivers.riru.edxp.sandhook.proxy.BlackWhiteListProxy;
|
||||||
import com.elderdrivers.riru.edxp.sandhook.proxy.NormalProxy;
|
import com.elderdrivers.riru.edxp.sandhook.proxy.NormalProxy;
|
||||||
|
import com.swift.sandhook.xposedcompat.XposedCompat;
|
||||||
import com.swift.sandhook.xposedcompat.methodgen.SandHookXposedBridge;
|
import com.swift.sandhook.xposedcompat.methodgen.SandHookXposedBridge;
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
|
@ -31,7 +32,12 @@ public class Main implements KeepAll {
|
||||||
HookMethodResolver.init();
|
HookMethodResolver.init();
|
||||||
Router.injectConfig();
|
Router.injectConfig();
|
||||||
InstallerChooser.setInstallerPackageName(getInstallerPkgName());
|
InstallerChooser.setInstallerPackageName(getInstallerPkgName());
|
||||||
SandHookXposedBridge.setLibPath();
|
SandHookXposedBridge.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setAppDataDir(String appDataDir) {
|
||||||
|
Main.appDataDir = appDataDir;
|
||||||
|
XposedCompat.appDataDir = appDataDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,15 @@
|
||||||
package com.elderdrivers.riru.edxp.sandhook.config;
|
package com.elderdrivers.riru.edxp.sandhook.config;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
import com.elderdrivers.riru.edxp.hook.HookProvider;
|
import com.elderdrivers.riru.edxp.hook.HookProvider;
|
||||||
import com.elderdrivers.riru.edxp.sandhook.dexmaker.DexMakerUtils;
|
import com.elderdrivers.riru.edxp.sandhook.dexmaker.DexMakerUtils;
|
||||||
|
import com.elderdrivers.riru.edxp.sandhook.dexmaker.DynamicBridge;
|
||||||
import com.elderdrivers.riru.edxp.sandhook.util.PrebuiltMethodsDeopter;
|
import com.elderdrivers.riru.edxp.sandhook.util.PrebuiltMethodsDeopter;
|
||||||
import com.swift.sandhook.xposedcompat.XposedCompat;
|
import com.swift.sandhook.xposedcompat.XposedCompat;
|
||||||
import com.swift.sandhook.xposedcompat.methodgen.SandHookXposedBridge;
|
import com.swift.sandhook.xposedcompat.methodgen.SandHookXposedBridge;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Member;
|
import java.lang.reflect.Member;
|
||||||
|
|
||||||
import de.robv.android.xposed.XposedBridge;
|
import de.robv.android.xposed.XposedBridge;
|
||||||
|
|
@ -13,12 +17,27 @@ import de.robv.android.xposed.XposedBridge;
|
||||||
public class SandHookProvider implements HookProvider {
|
public class SandHookProvider implements HookProvider {
|
||||||
@Override
|
@Override
|
||||||
public void hookMethod(Member method, XposedBridge.AdditionalHookInfo additionalInfo) {
|
public void hookMethod(Member method, XposedBridge.AdditionalHookInfo additionalInfo) {
|
||||||
|
if (SandHookXposedBridge.hooked(method) || DynamicBridge.hooked(method)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (method.getDeclaringClass() == Log.class) {
|
||||||
|
Log.e(XposedBridge.TAG, "some one hook Log!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
XposedCompat.hookMethod(method, additionalInfo);
|
XposedCompat.hookMethod(method, additionalInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object invokeOriginalMethod(Member method, long methodId, Object thisObject, Object[] args) throws Throwable {
|
public Object invokeOriginalMethod(Member method, long methodId, Object thisObject, Object[] args) throws Throwable {
|
||||||
return SandHookXposedBridge.invokeOriginalMethod(method, thisObject, args);
|
if (SandHookXposedBridge.hooked(method)) {
|
||||||
|
try {
|
||||||
|
return SandHookXposedBridge.invokeOriginalMethod(method, thisObject, args);
|
||||||
|
} catch (Throwable throwable) {
|
||||||
|
throw new InvocationTargetException(throwable);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return DynamicBridge.invokeOriginalMethod(method, thisObject, args);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import java.lang.reflect.Member;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
import de.robv.android.xposed.XposedBridge;
|
import de.robv.android.xposed.XposedBridge;
|
||||||
|
|
@ -20,7 +21,7 @@ import static com.elderdrivers.riru.edxp.sandhook.dexmaker.DexMakerUtils.shouldU
|
||||||
|
|
||||||
public final class DynamicBridge {
|
public final class DynamicBridge {
|
||||||
|
|
||||||
private static final HashMap<Member, Method> hookedInfo = new HashMap<>();
|
private static final ConcurrentHashMap<Member, Method> hookedInfo = new ConcurrentHashMap<>();
|
||||||
private static final HookerDexMaker dexMaker = new HookerDexMaker();
|
private static final HookerDexMaker dexMaker = new HookerDexMaker();
|
||||||
private static final AtomicBoolean dexPathInited = new AtomicBoolean(false);
|
private static final AtomicBoolean dexPathInited = new AtomicBoolean(false);
|
||||||
private static File dexDir;
|
private static File dexDir;
|
||||||
|
|
@ -33,6 +34,10 @@ public final class DynamicBridge {
|
||||||
dexPathInited.set(false);
|
dexPathInited.set(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean hooked(Member member) {
|
||||||
|
return hookedInfo.containsKey(member);
|
||||||
|
}
|
||||||
|
|
||||||
public static synchronized void hookMethod(Member hookMethod, XposedBridge.AdditionalHookInfo additionalHookInfo) {
|
public static synchronized void hookMethod(Member hookMethod, XposedBridge.AdditionalHookInfo additionalHookInfo) {
|
||||||
DexLog.d("hooking " + hookMethod);
|
DexLog.d("hooking " + hookMethod);
|
||||||
if (!checkMember(hookMethod)) {
|
if (!checkMember(hookMethod)) {
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,8 @@ import com.elderdrivers.riru.edxp.sandhook.entry.bootstrap.SysBootstrapHookInfo;
|
||||||
import com.elderdrivers.riru.edxp.sandhook.entry.bootstrap.SysInnerHookInfo;
|
import com.elderdrivers.riru.edxp.sandhook.entry.bootstrap.SysInnerHookInfo;
|
||||||
import com.elderdrivers.riru.edxp.sandhook.entry.bootstrap.WorkAroundHookInfo;
|
import com.elderdrivers.riru.edxp.sandhook.entry.bootstrap.WorkAroundHookInfo;
|
||||||
import com.elderdrivers.riru.edxp.sandhook.entry.hooker.SystemMainHooker;
|
import com.elderdrivers.riru.edxp.sandhook.entry.hooker.SystemMainHooker;
|
||||||
|
import com.swift.sandhook.SandHookConfig;
|
||||||
|
import com.swift.sandhook.xposedcompat.XposedCompat;
|
||||||
import com.swift.sandhook.xposedcompat.methodgen.SandHookXposedBridge;
|
import com.swift.sandhook.xposedcompat.methodgen.SandHookXposedBridge;
|
||||||
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
@ -21,6 +23,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import de.robv.android.xposed.XposedBridge;
|
import de.robv.android.xposed.XposedBridge;
|
||||||
import de.robv.android.xposed.XposedInit;
|
import de.robv.android.xposed.XposedInit;
|
||||||
|
|
||||||
|
import static de.robv.android.xposed.XposedInit.startsSystemServer;
|
||||||
|
|
||||||
public class Router {
|
public class Router {
|
||||||
|
|
||||||
public volatile static boolean forkCompleted = false;
|
public volatile static boolean forkCompleted = false;
|
||||||
|
|
@ -30,7 +34,7 @@ public class Router {
|
||||||
|
|
||||||
public static void prepare(boolean isSystem) {
|
public static void prepare(boolean isSystem) {
|
||||||
// this flag is needed when loadModules
|
// this flag is needed when loadModules
|
||||||
XposedInit.startsSystemServer = isSystem;
|
startsSystemServer = isSystem;
|
||||||
// InstallerChooser.setup();
|
// InstallerChooser.setup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -81,19 +85,22 @@ public class Router {
|
||||||
Router.class.getClassLoader(),
|
Router.class.getClassLoader(),
|
||||||
classLoader,
|
classLoader,
|
||||||
SysBootstrapHookInfo.class.getName());
|
SysBootstrapHookInfo.class.getName());
|
||||||
|
XposedCompat.addHookers(classLoader, SysBootstrapHookInfo.hookItems);
|
||||||
} else {
|
} else {
|
||||||
HookMain.doHookDefault(
|
HookMain.doHookDefault(
|
||||||
Router.class.getClassLoader(),
|
Router.class.getClassLoader(),
|
||||||
classLoader,
|
classLoader,
|
||||||
AppBootstrapHookInfo.class.getName());
|
AppBootstrapHookInfo.class.getName());
|
||||||
|
XposedCompat.addHookers(classLoader, AppBootstrapHookInfo.hookItems);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void startSystemServerHook() {
|
public static void startSystemServerHook() {
|
||||||
HookMain.doHookDefault(
|
// HookMain.doHookDefault(
|
||||||
Router.class.getClassLoader(),
|
// Router.class.getClassLoader(),
|
||||||
SystemMainHooker.systemServerCL,
|
// SystemMainHooker.systemServerCL,
|
||||||
SysInnerHookInfo.class.getName());
|
// SysInnerHookInfo.class.getName());
|
||||||
|
XposedCompat.addHookers(SystemMainHooker.systemServerCL, SysInnerHookInfo.hookItems);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void startWorkAroundHook() {
|
public static void startWorkAroundHook() {
|
||||||
|
|
@ -106,7 +113,8 @@ public class Router {
|
||||||
public static void onEnterChildProcess() {
|
public static void onEnterChildProcess() {
|
||||||
forkCompleted = true;
|
forkCompleted = true;
|
||||||
DynamicBridge.onForkPost();
|
DynamicBridge.onForkPost();
|
||||||
SandHookXposedBridge.onForkPost();
|
//enable compile in child process
|
||||||
|
//SandHook.enableCompiler(!XposedInit.startsSystemServer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void logD(String prefix) {
|
public static void logD(String prefix) {
|
||||||
|
|
@ -122,5 +130,6 @@ public class Router {
|
||||||
public static void injectConfig() {
|
public static void injectConfig() {
|
||||||
EdXpConfigGlobal.sConfig = new SandHookEdxpConfig();
|
EdXpConfigGlobal.sConfig = new SandHookEdxpConfig();
|
||||||
EdXpConfigGlobal.sHookProvider = new SandHookProvider();
|
EdXpConfigGlobal.sHookProvider = new SandHookProvider();
|
||||||
|
SandHookConfig.compiler = !startsSystemServer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,11 @@ import com.elderdrivers.riru.edxp.sandhook.entry.hooker.OnePlusWorkAroundHooker;
|
||||||
|
|
||||||
public class AppBootstrapHookInfo implements KeepMembers {
|
public class AppBootstrapHookInfo implements KeepMembers {
|
||||||
public static String[] hookItemNames = {
|
public static String[] hookItemNames = {
|
||||||
HandleBindAppHooker.class.getName(),
|
|
||||||
LoadedApkConstructorHooker.class.getName(),
|
|
||||||
OnePlusWorkAroundHooker.class.getName()
|
OnePlusWorkAroundHooker.class.getName()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public static Class[] hookItems = {
|
||||||
|
HandleBindAppHooker.class,
|
||||||
|
LoadedApkConstructorHooker.class
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,12 @@ import com.elderdrivers.riru.edxp.sandhook.entry.hooker.SystemMainHooker;
|
||||||
|
|
||||||
public class SysBootstrapHookInfo implements KeepMembers {
|
public class SysBootstrapHookInfo implements KeepMembers {
|
||||||
public static String[] hookItemNames = {
|
public static String[] hookItemNames = {
|
||||||
HandleBindAppHooker.class.getName(),
|
|
||||||
SystemMainHooker.class.getName(),
|
|
||||||
LoadedApkConstructorHooker.class.getName(),
|
|
||||||
OnePlusWorkAroundHooker.class.getName()
|
OnePlusWorkAroundHooker.class.getName()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public static Class[] hookItems = {
|
||||||
|
HandleBindAppHooker.class,
|
||||||
|
SystemMainHooker.class,
|
||||||
|
LoadedApkConstructorHooker.class
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,4 +7,8 @@ public class SysInnerHookInfo implements KeepMembers {
|
||||||
public static String[] hookItemNames = {
|
public static String[] hookItemNames = {
|
||||||
StartBootstrapServicesHooker.class.getName()
|
StartBootstrapServicesHooker.class.getName()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public static Class[] hookItems = {
|
||||||
|
StartBootstrapServicesHooker.class
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,4 +7,7 @@ public class WorkAroundHookInfo implements KeepMembers {
|
||||||
public static String[] hookItemNames = {
|
public static String[] hookItemNames = {
|
||||||
OnePlusWorkAroundHooker.class.getName()
|
OnePlusWorkAroundHooker.class.getName()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public static Class[] hookItems = {
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,16 @@ import com.elderdrivers.riru.common.KeepMembers;
|
||||||
import com.elderdrivers.riru.edxp.util.Utils;
|
import com.elderdrivers.riru.edxp.util.Utils;
|
||||||
import com.elderdrivers.riru.edxp.Main;
|
import com.elderdrivers.riru.edxp.Main;
|
||||||
import com.elderdrivers.riru.edxp.sandhook.entry.Router;
|
import com.elderdrivers.riru.edxp.sandhook.entry.Router;
|
||||||
|
import com.swift.sandhook.SandHook;
|
||||||
|
import com.swift.sandhook.annotation.HookClass;
|
||||||
|
import com.swift.sandhook.annotation.HookMethod;
|
||||||
|
import com.swift.sandhook.annotation.HookMethodBackup;
|
||||||
|
import com.swift.sandhook.annotation.HookMode;
|
||||||
|
import com.swift.sandhook.annotation.Param;
|
||||||
|
import com.swift.sandhook.annotation.SkipParamCheck;
|
||||||
|
import com.swift.sandhook.annotation.ThisObject;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
import de.robv.android.xposed.XposedBridge;
|
import de.robv.android.xposed.XposedBridge;
|
||||||
import de.robv.android.xposed.XposedHelpers;
|
import de.robv.android.xposed.XposedHelpers;
|
||||||
|
|
@ -21,15 +31,21 @@ import static com.elderdrivers.riru.edxp.util.ClassLoaderUtils.replaceParentClas
|
||||||
import static com.elderdrivers.riru.edxp.sandhook.entry.hooker.XposedBlackListHooker.BLACK_LIST_PACKAGE_NAME;
|
import static com.elderdrivers.riru.edxp.sandhook.entry.hooker.XposedBlackListHooker.BLACK_LIST_PACKAGE_NAME;
|
||||||
|
|
||||||
// normal process initialization (for new Activity, Service, BroadcastReceiver etc.)
|
// normal process initialization (for new Activity, Service, BroadcastReceiver etc.)
|
||||||
|
@HookClass(ActivityThread.class)
|
||||||
public class HandleBindAppHooker implements KeepMembers {
|
public class HandleBindAppHooker implements KeepMembers {
|
||||||
|
|
||||||
public static String className = "android.app.ActivityThread";
|
public static String className = "android.app.ActivityThread";
|
||||||
public static String methodName = "handleBindApplication";
|
public static String methodName = "handleBindApplication";
|
||||||
public static String methodSig = "(Landroid/app/ActivityThread$AppBindData;)V";
|
public static String methodSig = "(Landroid/app/ActivityThread$AppBindData;)V";
|
||||||
|
|
||||||
public static void hook(Object thiz, Object bindData) {
|
@HookMethodBackup("handleBindApplication")
|
||||||
|
@SkipParamCheck
|
||||||
|
static Method backup;
|
||||||
|
|
||||||
|
@HookMethod("handleBindApplication")
|
||||||
|
public static void hook(@ThisObject ActivityThread thiz, @Param("android.app.ActivityThread$AppBindData") Object bindData) throws Throwable {
|
||||||
if (XposedBlackListHooker.shouldDisableHooks("")) {
|
if (XposedBlackListHooker.shouldDisableHooks("")) {
|
||||||
backup(thiz, bindData);
|
SandHook.callOriginByBackup(backup, thiz, bindData);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
|
|
@ -80,7 +96,7 @@ public class HandleBindAppHooker implements KeepMembers {
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
Router.logE("error when hooking bindApp", t);
|
Router.logE("error when hooking bindApp", t);
|
||||||
} finally {
|
} finally {
|
||||||
backup(thiz, bindData);
|
SandHook.callOriginByBackup(backup, thiz, bindData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,14 @@ import android.util.Log;
|
||||||
|
|
||||||
import com.elderdrivers.riru.common.KeepMembers;
|
import com.elderdrivers.riru.common.KeepMembers;
|
||||||
import com.elderdrivers.riru.edxp.sandhook.entry.Router;
|
import com.elderdrivers.riru.edxp.sandhook.entry.Router;
|
||||||
|
import com.swift.sandhook.SandHook;
|
||||||
|
import com.swift.sandhook.annotation.HookClass;
|
||||||
|
import com.swift.sandhook.annotation.HookMethod;
|
||||||
|
import com.swift.sandhook.annotation.HookMethodBackup;
|
||||||
|
import com.swift.sandhook.annotation.SkipParamCheck;
|
||||||
|
import com.swift.sandhook.annotation.ThisObject;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
import de.robv.android.xposed.XposedBridge;
|
import de.robv.android.xposed.XposedBridge;
|
||||||
import de.robv.android.xposed.XposedHelpers;
|
import de.robv.android.xposed.XposedHelpers;
|
||||||
|
|
@ -19,6 +27,7 @@ import static com.elderdrivers.riru.edxp.util.ClassLoaderUtils.replaceParentClas
|
||||||
|
|
||||||
// when a package is loaded for an existing process, trigger the callbacks as well
|
// when a package is loaded for an existing process, trigger the callbacks as well
|
||||||
// ed: remove resources related hooking
|
// ed: remove resources related hooking
|
||||||
|
@HookClass(LoadedApk.class)
|
||||||
public class LoadedApkConstructorHooker implements KeepMembers {
|
public class LoadedApkConstructorHooker implements KeepMembers {
|
||||||
public static String className = "android.app.LoadedApk";
|
public static String className = "android.app.LoadedApk";
|
||||||
public static String methodName = "<init>";
|
public static String methodName = "<init>";
|
||||||
|
|
@ -27,20 +36,24 @@ public class LoadedApkConstructorHooker implements KeepMembers {
|
||||||
"Landroid/content/res/CompatibilityInfo;" +
|
"Landroid/content/res/CompatibilityInfo;" +
|
||||||
"Ljava/lang/ClassLoader;ZZZ)V";
|
"Ljava/lang/ClassLoader;ZZZ)V";
|
||||||
|
|
||||||
public static void hook(Object thiz, ActivityThread activityThread,
|
@HookMethodBackup
|
||||||
|
@SkipParamCheck
|
||||||
|
static Method backup;
|
||||||
|
|
||||||
|
@HookMethod
|
||||||
|
public static void hook(@ThisObject Object thiz, ActivityThread activityThread,
|
||||||
ApplicationInfo aInfo, CompatibilityInfo compatInfo,
|
ApplicationInfo aInfo, CompatibilityInfo compatInfo,
|
||||||
ClassLoader baseLoader, boolean securityViolation,
|
ClassLoader baseLoader, boolean securityViolation,
|
||||||
boolean includeCode, boolean registerPackage) {
|
boolean includeCode, boolean registerPackage) throws Throwable {
|
||||||
|
|
||||||
if (XposedBlackListHooker.shouldDisableHooks("")) {
|
if (XposedBlackListHooker.shouldDisableHooks("")) {
|
||||||
backup(thiz, activityThread, aInfo, compatInfo, baseLoader, securityViolation,
|
SandHook.callOriginByBackup(backup, thiz, activityThread, aInfo, compatInfo, baseLoader, securityViolation, includeCode, registerPackage);
|
||||||
includeCode, registerPackage);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Router.logD("LoadedApk#<init> starts");
|
Router.logD("LoadedApk#<init> starts");
|
||||||
backup(thiz, activityThread, aInfo, compatInfo, baseLoader, securityViolation,
|
SandHook.callOriginByBackup(backup, thiz, activityThread, aInfo, compatInfo, baseLoader, securityViolation, includeCode, registerPackage);
|
||||||
includeCode, registerPackage);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
LoadedApk loadedApk = (LoadedApk) thiz;
|
LoadedApk loadedApk = (LoadedApk) thiz;
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,14 @@ package com.elderdrivers.riru.edxp.sandhook.entry.hooker;
|
||||||
import com.elderdrivers.riru.common.KeepMembers;
|
import com.elderdrivers.riru.common.KeepMembers;
|
||||||
import com.elderdrivers.riru.edxp.Main;
|
import com.elderdrivers.riru.edxp.Main;
|
||||||
import com.elderdrivers.riru.edxp.sandhook.entry.Router;
|
import com.elderdrivers.riru.edxp.sandhook.entry.Router;
|
||||||
|
import com.swift.sandhook.annotation.HookClass;
|
||||||
|
import com.swift.sandhook.annotation.HookMethod;
|
||||||
|
import com.swift.sandhook.annotation.HookMethodBackup;
|
||||||
|
import com.swift.sandhook.annotation.SkipParamCheck;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
import dalvik.system.BaseDexClassLoader;
|
||||||
import de.robv.android.xposed.XposedBridge;
|
import de.robv.android.xposed.XposedBridge;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -21,12 +28,18 @@ import de.robv.android.xposed.XposedBridge;
|
||||||
* open of /dev/binder and we haven't found side effects yet.
|
* open of /dev/binder and we haven't found side effects yet.
|
||||||
* Other roms might share the same problems but not reported too.
|
* Other roms might share the same problems but not reported too.
|
||||||
*/
|
*/
|
||||||
|
@HookClass(BaseDexClassLoader.class)
|
||||||
public class OnePlusWorkAroundHooker implements KeepMembers {
|
public class OnePlusWorkAroundHooker implements KeepMembers {
|
||||||
|
|
||||||
public static String className = "dalvik.system.BaseDexClassLoader";
|
public static String className = "dalvik.system.BaseDexClassLoader";
|
||||||
public static String methodName = "inCompatConfigList";
|
public static String methodName = "inCompatConfigList";
|
||||||
public static String methodSig = "(ILjava/lang/String;)Z";
|
public static String methodSig = "(ILjava/lang/String;)Z";
|
||||||
|
|
||||||
|
@HookMethodBackup("inCompatConfigList")
|
||||||
|
@SkipParamCheck
|
||||||
|
static Method backup;
|
||||||
|
|
||||||
|
@HookMethod("inCompatConfigList")
|
||||||
public static boolean hook(int type, String packageName) {
|
public static boolean hook(int type, String packageName) {
|
||||||
if (XposedBridge.disableHooks || Router.forkCompleted) {
|
if (XposedBridge.disableHooks || Router.forkCompleted) {
|
||||||
return backup(type, packageName);
|
return backup(type, packageName);
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,15 @@ import android.os.Build;
|
||||||
|
|
||||||
import com.elderdrivers.riru.common.KeepMembers;
|
import com.elderdrivers.riru.common.KeepMembers;
|
||||||
import com.elderdrivers.riru.edxp.sandhook.entry.Router;
|
import com.elderdrivers.riru.edxp.sandhook.entry.Router;
|
||||||
|
import com.swift.sandhook.SandHook;
|
||||||
|
import com.swift.sandhook.annotation.HookMethod;
|
||||||
|
import com.swift.sandhook.annotation.HookMethodBackup;
|
||||||
|
import com.swift.sandhook.annotation.HookMode;
|
||||||
|
import com.swift.sandhook.annotation.HookReflectClass;
|
||||||
|
import com.swift.sandhook.annotation.SkipParamCheck;
|
||||||
|
import com.swift.sandhook.annotation.ThisObject;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
import de.robv.android.xposed.XC_MethodReplacement;
|
import de.robv.android.xposed.XC_MethodReplacement;
|
||||||
import de.robv.android.xposed.XposedBridge;
|
import de.robv.android.xposed.XposedBridge;
|
||||||
|
|
@ -15,15 +24,21 @@ import static com.elderdrivers.riru.edxp.util.ClassLoaderUtils.replaceParentClas
|
||||||
import static com.elderdrivers.riru.edxp.util.Utils.logD;
|
import static com.elderdrivers.riru.edxp.util.Utils.logD;
|
||||||
import static de.robv.android.xposed.XposedHelpers.findAndHookMethod;
|
import static de.robv.android.xposed.XposedHelpers.findAndHookMethod;
|
||||||
|
|
||||||
|
@HookReflectClass("com.android.server.SystemServer")
|
||||||
public class StartBootstrapServicesHooker implements KeepMembers {
|
public class StartBootstrapServicesHooker implements KeepMembers {
|
||||||
public static String className = "com.android.server.SystemServer";
|
public static String className = "com.android.server.SystemServer";
|
||||||
public static String methodName = "startBootstrapServices";
|
public static String methodName = "startBootstrapServices";
|
||||||
public static String methodSig = "()V";
|
public static String methodSig = "()V";
|
||||||
|
|
||||||
public static void hook(Object systemServer) {
|
@HookMethodBackup("startBootstrapServices")
|
||||||
|
@SkipParamCheck
|
||||||
|
static Method backup;
|
||||||
|
|
||||||
|
@HookMethod("startBootstrapServices")
|
||||||
|
public static void hook(@ThisObject Object systemServer) throws Throwable {
|
||||||
|
|
||||||
if (XposedBridge.disableHooks) {
|
if (XposedBridge.disableHooks) {
|
||||||
backup(systemServer);
|
SandHook.callOriginByBackup(backup, systemServer);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -56,7 +71,7 @@ public class StartBootstrapServicesHooker implements KeepMembers {
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
Router.logE("error when hooking startBootstrapServices", t);
|
Router.logE("error when hooking startBootstrapServices", t);
|
||||||
} finally {
|
} finally {
|
||||||
backup(systemServer);
|
SandHook.callOriginByBackup(backup, systemServer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,12 +5,20 @@ import android.app.ActivityThread;
|
||||||
import com.elderdrivers.riru.common.KeepMembers;
|
import com.elderdrivers.riru.common.KeepMembers;
|
||||||
import com.elderdrivers.riru.edxp.sandhook.entry.Router;
|
import com.elderdrivers.riru.edxp.sandhook.entry.Router;
|
||||||
import com.elderdrivers.riru.edxp.sandhook.util.PrebuiltMethodsDeopter;
|
import com.elderdrivers.riru.edxp.sandhook.util.PrebuiltMethodsDeopter;
|
||||||
|
import com.swift.sandhook.SandHook;
|
||||||
|
import com.swift.sandhook.annotation.HookClass;
|
||||||
|
import com.swift.sandhook.annotation.HookMethod;
|
||||||
|
import com.swift.sandhook.annotation.HookMethodBackup;
|
||||||
|
import com.swift.sandhook.annotation.HookMode;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
import de.robv.android.xposed.XposedBridge;
|
import de.robv.android.xposed.XposedBridge;
|
||||||
|
|
||||||
|
|
||||||
// system_server initialization
|
// system_server initialization
|
||||||
// ed: only support sdk >= 21 for now
|
// ed: only support sdk >= 21 for now
|
||||||
|
@HookClass(ActivityThread.class)
|
||||||
public class SystemMainHooker implements KeepMembers {
|
public class SystemMainHooker implements KeepMembers {
|
||||||
|
|
||||||
public static String className = "android.app.ActivityThread";
|
public static String className = "android.app.ActivityThread";
|
||||||
|
|
@ -19,12 +27,16 @@ public class SystemMainHooker implements KeepMembers {
|
||||||
|
|
||||||
public static ClassLoader systemServerCL;
|
public static ClassLoader systemServerCL;
|
||||||
|
|
||||||
public static ActivityThread hook() {
|
@HookMethodBackup("systemMain")
|
||||||
|
static Method backup;
|
||||||
|
|
||||||
|
@HookMethod("systemMain")
|
||||||
|
public static ActivityThread hook() throws Throwable {
|
||||||
if (XposedBridge.disableHooks) {
|
if (XposedBridge.disableHooks) {
|
||||||
return backup();
|
return (ActivityThread) SandHook.callOriginByBackup(backup, null);
|
||||||
}
|
}
|
||||||
Router.logD("ActivityThread#systemMain() starts");
|
Router.logD("ActivityThread#systemMain() starts");
|
||||||
ActivityThread activityThread = backup();
|
ActivityThread activityThread = (ActivityThread) SandHook.callOriginByBackup(backup, null);
|
||||||
try {
|
try {
|
||||||
// get system_server classLoader
|
// get system_server classLoader
|
||||||
systemServerCL = Thread.currentThread().getContextClassLoader();
|
systemServerCL = Thread.currentThread().getContextClassLoader();
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,7 @@ public class BlackWhiteListProxy {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void onForkPostCommon(boolean isSystemServer, String appDataDir, String niceName) {
|
private static void onForkPostCommon(boolean isSystemServer, String appDataDir, String niceName) {
|
||||||
Main.appDataDir = appDataDir;
|
Main.setAppDataDir(appDataDir);
|
||||||
Main.niceName = niceName;
|
Main.niceName = niceName;
|
||||||
final boolean isDynamicModulesMode = Main.isDynamicModulesEnabled();
|
final boolean isDynamicModulesMode = Main.isDynamicModulesEnabled();
|
||||||
ConfigManager.setDynamicModulesMode(isDynamicModulesMode);
|
ConfigManager.setDynamicModulesMode(isDynamicModulesMode);
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ public class NormalProxy {
|
||||||
|
|
||||||
public static void forkAndSpecializePost(int pid, String appDataDir, String niceName) {
|
public static void forkAndSpecializePost(int pid, String appDataDir, String niceName) {
|
||||||
// TODO consider processes without forkAndSpecializePost called
|
// TODO consider processes without forkAndSpecializePost called
|
||||||
Main.appDataDir = appDataDir;
|
Main.setAppDataDir(appDataDir);
|
||||||
Main.niceName = niceName;
|
Main.niceName = niceName;
|
||||||
Router.prepare(false);
|
Router.prepare(false);
|
||||||
Main.reopenFilesAfterForkNative();
|
Main.reopenFilesAfterForkNative();
|
||||||
|
|
@ -58,7 +58,7 @@ public class NormalProxy {
|
||||||
|
|
||||||
public static void forkSystemServerPost(int pid) {
|
public static void forkSystemServerPost(int pid) {
|
||||||
// in system_server process
|
// in system_server process
|
||||||
Main.appDataDir = getDataPathPrefix() + "android";
|
Main.setAppDataDir(getDataPathPrefix() + "android");
|
||||||
Main.niceName = "system_server";
|
Main.niceName = "system_server";
|
||||||
Router.prepare(true);
|
Router.prepare(true);
|
||||||
Main.reopenFilesAfterForkNative();
|
Main.reopenFilesAfterForkNative();
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,65 @@
|
||||||
package com.swift.sandhook.xposedcompat;
|
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.classloaders.ComposeClassLoader;
|
||||||
import com.swift.sandhook.xposedcompat.methodgen.SandHookXposedBridge;
|
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.FileUtils;
|
||||||
|
import com.swift.sandhook.xposedcompat.utils.ProcessUtils;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.lang.reflect.Member;
|
import java.lang.reflect.Member;
|
||||||
|
|
||||||
import de.robv.android.xposed.XposedBridge;
|
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 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
|
//try to use internal stub hooker & backup method to speed up hook
|
||||||
public static volatile boolean useInternalStub = true;
|
public static volatile boolean useInternalStub = true;
|
||||||
public static volatile boolean useNewDexMaker = true;
|
public static volatile boolean useNewCallBackup = true;
|
||||||
public static volatile boolean retryWhenCallOriginError = false;
|
public static volatile boolean retryWhenCallOriginError = false;
|
||||||
|
|
||||||
private static ClassLoader sandHookXposedClassLoader;
|
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) {
|
public static synchronized void hookMethod(Member hookMethod, XposedBridge.AdditionalHookInfo additionalHookInfo) {
|
||||||
SandHookXposedBridge.hookMethod(hookMethod, additionalHookInfo);
|
SandHookXposedBridge.hookMethod(hookMethod, additionalHookInfo);
|
||||||
}
|
}
|
||||||
|
|
@ -31,18 +73,37 @@ public class XposedCompat {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// public static boolean clearCache() {
|
public static boolean clearCache() {
|
||||||
// try {
|
try {
|
||||||
// FileUtils.delete(cacheDir);
|
FileUtils.delete(getCacheDir());
|
||||||
// cacheDir.mkdirs();
|
getCacheDir().mkdirs();
|
||||||
// return true;
|
return true;
|
||||||
// } catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
// return false;
|
return false;
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// public static void clearOatCache() {
|
public static void clearOatCache() {
|
||||||
// SandHookXposedBridge.clearOatFile();
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import com.swift.sandhook.SandHook;
|
||||||
import com.swift.sandhook.SandHookMethodResolver;
|
import com.swift.sandhook.SandHookMethodResolver;
|
||||||
import com.swift.sandhook.utils.ParamWrapper;
|
import com.swift.sandhook.utils.ParamWrapper;
|
||||||
import com.swift.sandhook.wrapper.BackupMethodStubs;
|
import com.swift.sandhook.wrapper.BackupMethodStubs;
|
||||||
|
import com.swift.sandhook.xposedcompat.XposedCompat;
|
||||||
import com.swift.sandhook.xposedcompat.utils.DexLog;
|
import com.swift.sandhook.xposedcompat.utils.DexLog;
|
||||||
|
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
|
|
@ -23,12 +24,15 @@ import static de.robv.android.xposed.XposedBridge.sHookedMethodCallbacks;
|
||||||
|
|
||||||
public class HookStubManager {
|
public class HookStubManager {
|
||||||
|
|
||||||
|
public static volatile boolean is64Bit;
|
||||||
|
//64bits arg0 - arg7 is in reg x1 - x7 and > 7 is in stack, but can not match
|
||||||
|
public final static int MAX_64_ARGS = 7;
|
||||||
|
|
||||||
public static int MAX_STUB_ARGS = 0;
|
public static int MAX_STUB_ARGS = 0;
|
||||||
|
|
||||||
public static int[] stubSizes;
|
public static int[] stubSizes;
|
||||||
|
|
||||||
public static boolean hasStubBackup = false;
|
public static boolean hasStubBackup;
|
||||||
|
|
||||||
public static AtomicInteger[] curUseStubIndexes;
|
public static AtomicInteger[] curUseStubIndexes;
|
||||||
|
|
||||||
|
|
@ -41,10 +45,11 @@ public class HookStubManager {
|
||||||
= sHookedMethodCallbacks;
|
= sHookedMethodCallbacks;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
Class stubClass = SandHook.is64Bit() ? MethodHookerStubs64.class : MethodHookerStubs32.class;
|
is64Bit = SandHook.is64Bit();
|
||||||
|
Class stubClass = is64Bit ? MethodHookerStubs64.class : MethodHookerStubs32.class;
|
||||||
stubSizes = (int[]) XposedHelpers.getStaticObjectField(stubClass, "stubSizes");
|
stubSizes = (int[]) XposedHelpers.getStaticObjectField(stubClass, "stubSizes");
|
||||||
Boolean hasBackup = (Boolean) XposedHelpers.getStaticObjectField(stubClass, "hasStubBackup");
|
Boolean hasBackup = (Boolean) XposedHelpers.getStaticObjectField(stubClass, "hasStubBackup");
|
||||||
hasStubBackup = hasBackup == null ? false : hasBackup;
|
hasStubBackup = hasBackup != null && (hasBackup && !XposedCompat.useNewCallBackup);
|
||||||
if (stubSizes != null && stubSizes.length > 0) {
|
if (stubSizes != null && stubSizes.length > 0) {
|
||||||
MAX_STUB_ARGS = stubSizes.length - 1;
|
MAX_STUB_ARGS = stubSizes.length - 1;
|
||||||
curUseStubIndexes = new AtomicInteger[MAX_STUB_ARGS + 1];
|
curUseStubIndexes = new AtomicInteger[MAX_STUB_ARGS + 1];
|
||||||
|
|
@ -89,6 +94,8 @@ public class HookStubManager {
|
||||||
needStubArgCount += parType.length;
|
needStubArgCount += parType.length;
|
||||||
if (needStubArgCount > MAX_STUB_ARGS)
|
if (needStubArgCount > MAX_STUB_ARGS)
|
||||||
return null;
|
return null;
|
||||||
|
if (is64Bit && needStubArgCount > MAX_64_ARGS)
|
||||||
|
return null;
|
||||||
for (Class par:parType) {
|
for (Class par:parType) {
|
||||||
if (!ParamWrapper.support(par))
|
if (!ParamWrapper.support(par))
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -98,7 +105,7 @@ public class HookStubManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized (HookStubManager.class) {
|
synchronized (HookStubManager.class) {
|
||||||
StubMethodsInfo stubMethodInfo = getStubMethodPair(SandHook.is64Bit(), needStubArgCount);
|
StubMethodsInfo stubMethodInfo = getStubMethodPair(is64Bit, needStubArgCount);
|
||||||
if (stubMethodInfo == null)
|
if (stubMethodInfo == null)
|
||||||
return null;
|
return null;
|
||||||
HookMethodEntity entity = new HookMethodEntity(origin, stubMethodInfo.hook, stubMethodInfo.backup);
|
HookMethodEntity entity = new HookMethodEntity(origin, stubMethodInfo.hook, stubMethodInfo.backup);
|
||||||
|
|
@ -180,7 +187,7 @@ public class HookStubManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Method getCallOriginMethod(int args, int index) {
|
public static Method getCallOriginMethod(int args, int index) {
|
||||||
Class stubClass = SandHook.is64Bit() ? MethodHookerStubs64.class : MethodHookerStubs32.class;
|
Class stubClass = is64Bit ? MethodHookerStubs64.class : MethodHookerStubs32.class;
|
||||||
String className = stubClass.getName();
|
String className = stubClass.getName();
|
||||||
className += "$";
|
className += "$";
|
||||||
className += getCallOriginClassName(args, index);
|
className += getCallOriginClassName(args, index);
|
||||||
|
|
@ -294,7 +301,6 @@ public class HookStubManager {
|
||||||
param.setResult(SandHook.callOriginMethod(originMethod, thiz, param.args));
|
param.setResult(SandHook.callOriginMethod(originMethod, thiz, param.args));
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
XposedBridge.log(e);
|
|
||||||
param.setThrowable(e);
|
param.setThrowable(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -365,7 +371,6 @@ public class HookStubManager {
|
||||||
try {
|
try {
|
||||||
param.setResult(SandHook.callOriginMethod(origin, thiz, param.args));
|
param.setResult(SandHook.callOriginMethod(origin, thiz, param.args));
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
XposedBridge.log(e);
|
|
||||||
param.setThrowable(e);
|
param.setThrowable(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -9,12 +9,15 @@ import com.swift.sandhook.xposedcompat.XposedCompat;
|
||||||
import com.swift.sandhook.xposedcompat.utils.DexLog;
|
import com.swift.sandhook.xposedcompat.utils.DexLog;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.Member;
|
import java.lang.reflect.Member;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import dalvik.system.InMemoryDexClassLoader;
|
||||||
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 external.com.android.dx.BinaryOp;
|
import external.com.android.dx.BinaryOp;
|
||||||
|
|
@ -218,7 +221,13 @@ public class HookerDexMaker implements HookMaker {
|
||||||
throw new IllegalArgumentException("dexDirPath should not be empty!!!");
|
throw new IllegalArgumentException("dexDirPath should not be empty!!!");
|
||||||
}
|
}
|
||||||
// Create the dex file and load it.
|
// Create the dex file and load it.
|
||||||
loader = mDexMaker.generateAndLoad(mAppClassLoader, new File(mDexDirPath), dexName);
|
try {
|
||||||
|
loader = mDexMaker.generateAndLoad(mAppClassLoader, new File(mDexDirPath), dexName);
|
||||||
|
} catch (IOException e) {
|
||||||
|
//can not write file
|
||||||
|
byte[] dexBytes = mDexMaker.generate();
|
||||||
|
loader = new InMemoryDexClassLoader(ByteBuffer.wrap(dexBytes), mAppClassLoader);
|
||||||
|
}
|
||||||
return loadHookerClass(loader, className);
|
return loadHookerClass(loader, className);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,12 +7,15 @@ import com.swift.sandhook.wrapper.HookWrapper;
|
||||||
import com.swift.sandhook.xposedcompat.hookstub.HookStubManager;
|
import com.swift.sandhook.xposedcompat.hookstub.HookStubManager;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.Member;
|
import java.lang.reflect.Member;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import dalvik.system.InMemoryDexClassLoader;
|
||||||
import de.robv.android.xposed.XposedBridge;
|
import de.robv.android.xposed.XposedBridge;
|
||||||
import de.robv.android.xposed.XposedHelpers;
|
import de.robv.android.xposed.XposedHelpers;
|
||||||
import external.com.android.dx.Code;
|
import external.com.android.dx.Code;
|
||||||
|
|
@ -172,7 +175,13 @@ public class HookerDexMakerNew implements HookMaker {
|
||||||
throw new IllegalArgumentException("dexDirPath should not be empty!!!");
|
throw new IllegalArgumentException("dexDirPath should not be empty!!!");
|
||||||
}
|
}
|
||||||
// Create the dex file and load it.
|
// Create the dex file and load it.
|
||||||
loader = mDexMaker.generateAndLoad(mAppClassLoader, new File(mDexDirPath), dexName);
|
try {
|
||||||
|
loader = mDexMaker.generateAndLoad(mAppClassLoader, new File(mDexDirPath), dexName);
|
||||||
|
} catch (IOException e) {
|
||||||
|
//can not write file
|
||||||
|
byte[] dexBytes = mDexMaker.generate();
|
||||||
|
loader = new InMemoryDexClassLoader(ByteBuffer.wrap(dexBytes), mAppClassLoader);
|
||||||
|
}
|
||||||
return loadHookerClass(loader, className);
|
return loadHookerClass(loader, className);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -233,7 +242,7 @@ public class HookerDexMakerNew implements HookMaker {
|
||||||
Code code = mDexMaker.declare(mHookMethodId, Modifier.PUBLIC | Modifier.STATIC);
|
Code code = mDexMaker.declare(mHookMethodId, Modifier.PUBLIC | Modifier.STATIC);
|
||||||
|
|
||||||
Local<Member> method = code.newLocal(memberTypeId);
|
Local<Member> method = code.newLocal(memberTypeId);
|
||||||
// Local<Method> backupMethod = code.newLocal(methodTypeId);
|
// Local<Method> backupMethod = code.newLocal(methodTypeId);
|
||||||
Local<Object> thisObject = code.newLocal(TypeId.OBJECT);
|
Local<Object> thisObject = code.newLocal(TypeId.OBJECT);
|
||||||
Local<Object[]> args = code.newLocal(objArrayTypeId);
|
Local<Object[]> args = code.newLocal(objArrayTypeId);
|
||||||
Local<Integer> actualParamSize = code.newLocal(TypeId.INT);
|
Local<Integer> actualParamSize = code.newLocal(TypeId.INT);
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ package com.swift.sandhook.xposedcompat.methodgen;
|
||||||
import android.os.Process;
|
import android.os.Process;
|
||||||
import android.os.Trace;
|
import android.os.Trace;
|
||||||
|
|
||||||
import com.elderdrivers.riru.edxp.Main;
|
|
||||||
import com.swift.sandhook.SandHook;
|
import com.swift.sandhook.SandHook;
|
||||||
import com.swift.sandhook.SandHookConfig;
|
import com.swift.sandhook.SandHookConfig;
|
||||||
import com.swift.sandhook.wrapper.HookWrapper;
|
import com.swift.sandhook.wrapper.HookWrapper;
|
||||||
|
|
@ -18,27 +17,23 @@ import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.Member;
|
import java.lang.reflect.Member;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
import de.robv.android.xposed.XposedBridge;
|
import de.robv.android.xposed.XposedBridge;
|
||||||
|
|
||||||
import static com.elderdrivers.riru.edxp.util.FileUtils.getDataPathPrefix;
|
|
||||||
import static com.elderdrivers.riru.edxp.util.FileUtils.getPackageName;
|
|
||||||
import static com.elderdrivers.riru.edxp.util.ProcessUtils.getCurrentProcessName;
|
|
||||||
|
|
||||||
public final class SandHookXposedBridge {
|
public final class SandHookXposedBridge {
|
||||||
|
|
||||||
private static final HashMap<Member, Method> hookedInfo = new HashMap<>();
|
private static final Map<Member, Method> hookedInfo = new ConcurrentHashMap<>();
|
||||||
private static HookMaker hookMaker = XposedCompat.useNewDexMaker ? new HookerDexMakerNew() : new HookerDexMaker();
|
private static HookMaker hookMaker = XposedCompat.useNewCallBackup ? new HookerDexMakerNew() : new HookerDexMaker();
|
||||||
private static final AtomicBoolean dexPathInited = new AtomicBoolean(false);
|
private static final AtomicBoolean dexPathInited = new AtomicBoolean(false);
|
||||||
private static File dexDir;
|
private static File dexDir;
|
||||||
|
|
||||||
public static Map<Member, HookMethodEntity> entityMap = new HashMap<>();
|
public static Map<Member,HookMethodEntity> entityMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
public static void onForkPost() {
|
public static boolean hooked(Member member) {
|
||||||
dexPathInited.set(false);
|
return hookedInfo.containsKey(member) || entityMap.containsKey(member);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static synchronized void hookMethod(Member hookMethod, XposedBridge.AdditionalHookInfo additionalHookInfo) {
|
public static synchronized void hookMethod(Member hookMethod, XposedBridge.AdditionalHookInfo additionalHookInfo) {
|
||||||
|
|
@ -53,8 +48,17 @@ public final class SandHookXposedBridge {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
setupDexCachePath();
|
if (dexPathInited.compareAndSet(false, true)) {
|
||||||
Trace.beginSection("SandHook-Xposed");
|
try {
|
||||||
|
String fixedAppDataDir = XposedCompat.getCacheDir().getAbsolutePath();
|
||||||
|
dexDir = new File(fixedAppDataDir, "/hookers/");
|
||||||
|
if (!dexDir.exists())
|
||||||
|
dexDir.mkdirs();
|
||||||
|
} catch (Throwable throwable) {
|
||||||
|
DexLog.e("error when init dex path", throwable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Trace.beginSection("SandXposed");
|
||||||
long timeStart = System.currentTimeMillis();
|
long timeStart = System.currentTimeMillis();
|
||||||
HookMethodEntity stub = null;
|
HookMethodEntity stub = null;
|
||||||
if (XposedCompat.useInternalStub) {
|
if (XposedCompat.useInternalStub) {
|
||||||
|
|
@ -65,7 +69,7 @@ public final class SandHookXposedBridge {
|
||||||
entityMap.put(hookMethod, stub);
|
entityMap.put(hookMethod, stub);
|
||||||
} else {
|
} else {
|
||||||
hookMaker.start(hookMethod, additionalHookInfo,
|
hookMaker.start(hookMethod, additionalHookInfo,
|
||||||
null, dexDir == null ? null : dexDir.getAbsolutePath());
|
hookMethod.getDeclaringClass().getClassLoader(), dexDir == null ? null : dexDir.getAbsolutePath());
|
||||||
hookedInfo.put(hookMethod, hookMaker.getCallBackupMethod());
|
hookedInfo.put(hookMethod, hookMaker.getCallBackupMethod());
|
||||||
}
|
}
|
||||||
DexLog.d("hook method <" + hookMethod.toString() + "> cost " + (System.currentTimeMillis() - timeStart) + " ms, by " + (stub != null ? "internal stub." : "dex maker"));
|
DexLog.d("hook method <" + hookMethod.toString() + "> cost " + (System.currentTimeMillis() - timeStart) + " ms, by " + (stub != null ? "internal stub." : "dex maker"));
|
||||||
|
|
@ -75,35 +79,18 @@ public final class SandHookXposedBridge {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void setupDexCachePath() {
|
public static void clearOatFile() {
|
||||||
// using file based DexClassLoader
|
String fixedAppDataDir = XposedCompat.getCacheDir().getAbsolutePath();
|
||||||
if (!dexPathInited.compareAndSet(false, true)) {
|
File dexOatDir = new File(fixedAppDataDir, "/hookers/oat/");
|
||||||
|
if (!dexOatDir.exists())
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
// we always choose to use device encrypted storage data on android N and later
|
FileUtils.delete(dexOatDir);
|
||||||
// in case some app is installing hooks before phone is unlocked
|
dexOatDir.mkdirs();
|
||||||
String fixedAppDataDir = getDataPathPrefix() + getPackageName(Main.appDataDir) + "/";
|
|
||||||
dexDir = new File(fixedAppDataDir, "/cache/sandxposed/"
|
|
||||||
+ getCurrentProcessName(Main.appProcessName).replace(":", "_") + "/");
|
|
||||||
dexDir.mkdirs();
|
|
||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
com.elderdrivers.riru.edxp.sandhook.dexmaker.DexLog.e("error when init dex path", throwable);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// public static void clearOatFile() {
|
|
||||||
// String fixedAppDataDir = XposedCompat.cacheDir.getAbsolutePath();
|
|
||||||
// File dexOatDir = new File(fixedAppDataDir, "/sandxposed/oat/");
|
|
||||||
// if (!dexOatDir.exists())
|
|
||||||
// return;
|
|
||||||
// try {
|
|
||||||
// FileUtils.delete(dexOatDir);
|
|
||||||
// dexOatDir.mkdirs();
|
|
||||||
// } catch (Throwable throwable) {
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
private static boolean checkMember(Member member) {
|
private static boolean checkMember(Member member) {
|
||||||
|
|
||||||
if (member instanceof Method) {
|
if (member instanceof Method) {
|
||||||
|
|
@ -124,37 +111,24 @@ public final class SandHookXposedBridge {
|
||||||
|
|
||||||
public static Object invokeOriginalMethod(Member method, Object thisObject, Object[] args)
|
public static Object invokeOriginalMethod(Member method, Object thisObject, Object[] args)
|
||||||
throws Throwable {
|
throws Throwable {
|
||||||
Method callBackup = hookedInfo.get(method);
|
return SandHook.callOriginMethod(method, thisObject, args);
|
||||||
if (callBackup == null) {
|
|
||||||
//method hook use internal stub
|
|
||||||
return SandHook.callOriginMethod(method, thisObject, args);
|
|
||||||
}
|
|
||||||
if (!Modifier.isStatic(callBackup.getModifiers())) {
|
|
||||||
throw new IllegalStateException("original method is not static, something must be wrong!");
|
|
||||||
}
|
|
||||||
callBackup.setAccessible(true);
|
|
||||||
if (args == null) {
|
|
||||||
args = new Object[0];
|
|
||||||
}
|
|
||||||
final int argsSize = args.length;
|
|
||||||
if (Modifier.isStatic(method.getModifiers())) {
|
|
||||||
return callBackup.invoke(null, args);
|
|
||||||
} else {
|
|
||||||
Object[] newArgs = new Object[argsSize + 1];
|
|
||||||
newArgs[0] = thisObject;
|
|
||||||
for (int i = 1; i < newArgs.length; i++) {
|
|
||||||
newArgs[i] = args[i - 1];
|
|
||||||
}
|
|
||||||
return callBackup.invoke(null, newArgs);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setLibPath() {
|
public static void init() {
|
||||||
if (Process.is64Bit()) {
|
if (Process.is64Bit()) {
|
||||||
SandHookConfig.libSandHookPath = "/system/lib64/libsandhook.edxp.so";
|
SandHookConfig.libSandHookPath = "/system/lib64/libsandhook.edxp.so";
|
||||||
} else {
|
} else {
|
||||||
SandHookConfig.libSandHookPath = "/system/lib/libsandhook.edxp.so";
|
SandHookConfig.libSandHookPath = "/system/lib/libsandhook.edxp.so";
|
||||||
}
|
}
|
||||||
|
SandHookConfig.libLoader = new SandHookConfig.LibLoader() {
|
||||||
|
@Override
|
||||||
|
public void loadLib() {
|
||||||
|
//do it in loadDexAndInit
|
||||||
|
}
|
||||||
|
};
|
||||||
|
SandHookConfig.DEBUG = true;
|
||||||
|
//in zygote disable compile
|
||||||
|
SandHookConfig.compiler = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,12 +7,16 @@ import java.lang.reflect.Member;
|
||||||
|
|
||||||
public class DexLog {
|
public class DexLog {
|
||||||
|
|
||||||
public static final String TAG = "SandXposed-dexmaker";
|
public static final String TAG = "SandXposed";
|
||||||
|
|
||||||
public static boolean DEBUG = true;
|
public static volatile boolean DEBUG = true;
|
||||||
|
|
||||||
public static int v(String s) {
|
public static int v(String s) {
|
||||||
return Log.v(TAG, s);
|
if (DEBUG) {
|
||||||
|
return Log.v(TAG, s);
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int i(String s) {
|
public static int i(String s) {
|
||||||
|
|
@ -25,26 +29,38 @@ public class DexLog {
|
||||||
|
|
||||||
public static void printMethodHookIn(Member member) {
|
public static void printMethodHookIn(Member member) {
|
||||||
if (DEBUG && member != null) {
|
if (DEBUG && member != null) {
|
||||||
Log.d("SandHook-Xposed", "method <" + member.toString() + "> hook in");
|
Log.d("SandHook", "method <" + member.toString() + "> hook in");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void printCallOriginError(Member member) {
|
public static void printCallOriginError(Member member) {
|
||||||
if (member != null) {
|
if (DEBUG && member != null) {
|
||||||
Log.e("SandHook-Xposed", "method <" + member.toString() + "> call origin error!");
|
Log.d("SandHook", "method <" + member.toString() + "> call origin error!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int w(String s) {
|
public static int w(String s) {
|
||||||
return Log.w(TAG, s);
|
if (DEBUG) {
|
||||||
|
return Log.w(TAG, s);
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int e(String s) {
|
public static int e(String s) {
|
||||||
return Log.e(TAG, s);
|
if (DEBUG) {
|
||||||
|
return Log.e(TAG, s);
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int e(String s, Throwable t) {
|
public static int e(String s, Throwable t) {
|
||||||
return Log.e(TAG, s, t);
|
if (DEBUG) {
|
||||||
|
return Log.e(TAG, s, t);
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,12 @@ import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.ResolveInfo;
|
import android.content.pm.ResolveInfo;
|
||||||
|
import android.os.Process;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
|
@ -18,10 +22,10 @@ public class ProcessUtils {
|
||||||
|
|
||||||
private static volatile String processName = null;
|
private static volatile String processName = null;
|
||||||
|
|
||||||
public static String getProcessName(Context context) {
|
public static String getProcessName() {
|
||||||
if (!TextUtils.isEmpty(processName))
|
if (!TextUtils.isEmpty(processName))
|
||||||
return processName;
|
return processName;
|
||||||
processName = doGetProcessName(context);
|
processName = getProcessName(Process.myPid());
|
||||||
return processName;
|
return processName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -41,8 +45,35 @@ public class ProcessUtils {
|
||||||
return context.getPackageName();
|
return context.getPackageName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 isMainProcess(Context context) {
|
public static boolean isMainProcess(Context context) {
|
||||||
String processName = getProcessName(context);
|
String processName = getProcessName();
|
||||||
String pkgName = context.getPackageName();
|
String pkgName = context.getPackageName();
|
||||||
if (!TextUtils.isEmpty(processName) && !TextUtils.equals(processName, pkgName)) {
|
if (!TextUtils.isEmpty(processName) && !TextUtils.equals(processName, pkgName)) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
libsandhook.edxp.so
|
|
||||||
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue