Skip to content

Commit

Permalink
Move sandhook cache to /data/misc
Browse files Browse the repository at this point in the history
Close #681
  • Loading branch information
LoveSy authored and kotori2 committed Dec 24, 2020
1 parent c84c09b commit 9553af5
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

public interface HookMaker {
void start(Member member, XposedBridge.AdditionalHookInfo hookInfo,
ClassLoader appClassLoader, String dexDirPath) throws Exception;
ClassLoader appClassLoader) throws Exception;
Method getHookMethod();
Method getBackupMethod();
Method getCallBackupMethod();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
package com.swift.sandhook.xposedcompat.methodgen;

import android.text.TextUtils;

import com.elderdrivers.riru.edxp.config.ConfigManager;
import com.swift.sandhook.SandHook;
import com.swift.sandhook.SandHookMethodResolver;
import com.swift.sandhook.wrapper.HookWrapper;
import com.swift.sandhook.xposedcompat.XposedCompat;
import com.swift.sandhook.xposedcompat.utils.DexLog;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
Expand All @@ -33,8 +31,10 @@
import static com.swift.sandhook.xposedcompat.utils.DexMakerUtils.MD5;
import static com.swift.sandhook.xposedcompat.utils.DexMakerUtils.autoBoxIfNecessary;
import static com.swift.sandhook.xposedcompat.utils.DexMakerUtils.autoUnboxIfNecessary;
import static com.swift.sandhook.xposedcompat.utils.DexMakerUtils.canCache;
import static com.swift.sandhook.xposedcompat.utils.DexMakerUtils.createResultLocals;
import static com.swift.sandhook.xposedcompat.utils.DexMakerUtils.getObjTypeIdIfPrimitive;
import static com.swift.sandhook.xposedcompat.utils.DexMakerUtils.getSha1Hex;

public class HookerDexMaker implements HookMaker {

Expand Down Expand Up @@ -110,7 +110,6 @@ public class HookerDexMaker implements HookMaker {
private Method mHookMethod;
private Method mBackupMethod;
private Method mCallBackupMethod;
private String mDexDirPath;

private static TypeId<?>[] getParameterTypeIds(Class<?>[] parameterTypes, boolean isStatic) {
int parameterSize = parameterTypes.length;
Expand Down Expand Up @@ -141,7 +140,7 @@ private static Class<?>[] getParameterTypes(Class<?>[] parameterTypes, boolean i
}

public void start(Member member, XposedBridge.AdditionalHookInfo hookInfo,
ClassLoader appClassLoader, String dexDirPath) throws Exception {
ClassLoader appClassLoader) throws Exception {
if (member instanceof Method) {
Method method = (Method) member;
mIsStatic = Modifier.isStatic(method.getModifiers());
Expand Down Expand Up @@ -174,7 +173,6 @@ public void start(Member member, XposedBridge.AdditionalHookInfo hookInfo,
}
mMember = member;
mHookInfo = hookInfo;
mDexDirPath = dexDirPath;
if (appClassLoader == null
|| appClassLoader.getClass().getName().equals("java.lang.BootClassLoader")) {
mAppClassLoader = this.getClass().getClassLoader();
Expand All @@ -190,7 +188,7 @@ public void start(Member member, XposedBridge.AdditionalHookInfo hookInfo,
HookWrapper.HookEntity hookEntity = null;
//try load cache first
try {
ClassLoader loader = mDexMaker.loadClassDirect(mAppClassLoader, new File(mDexDirPath), dexName);
ClassLoader loader = mDexMaker.loadClassDirect(mAppClassLoader, new File(ConfigManager.getCachePath("")), dexName);
if (loader != null) {
hookEntity = loadHookerClass(loader, className);
}
Expand All @@ -217,13 +215,12 @@ private HookWrapper.HookEntity doMake(String className, String dexName) throws E
generateHookMethod();

ClassLoader loader;
if (TextUtils.isEmpty(mDexDirPath)) {
throw new IllegalArgumentException("dexDirPath should not be empty!!!");
}
// Create the dex file and load it.
try {
loader = mDexMaker.generateAndLoad(mAppClassLoader, new File(mDexDirPath), dexName, true);
} catch (IOException e) {
if (canCache) {
loader = mDexMaker.generateAndLoad(mAppClassLoader, new File(ConfigManager.getCachePath("")), dexName, true);
File dexFile = new File(ConfigManager.getCachePath(dexName));
dexFile.setWritable(true, false);
dexFile.setReadable(true, false);
} else {
//can not write file
byte[] dexBytes = mDexMaker.generate();
loader = new InMemoryDexClassLoader(ByteBuffer.wrap(dexBytes), mAppClassLoader);
Expand All @@ -245,7 +242,7 @@ private HookWrapper.HookEntity loadHookerClass(ClassLoader loader, String classN
}

private String getClassName(Member originMethod) {
return CLASS_NAME_PREFIX + "_" + MD5(originMethod.toString());
return CLASS_NAME_PREFIX + "_" + getSha1Hex(originMethod.toString());
}

public Method getHookMethod() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.swift.sandhook.xposedcompat.methodgen;

import android.text.TextUtils;

import com.elderdrivers.riru.edxp.config.ConfigManager;
import com.swift.sandhook.SandHook;
import com.swift.sandhook.wrapper.HookWrapper;
import com.swift.sandhook.xposedcompat.hookstub.HookStubManager;
Expand All @@ -28,8 +27,10 @@
import static com.swift.sandhook.xposedcompat.utils.DexMakerUtils.MD5;
import static com.swift.sandhook.xposedcompat.utils.DexMakerUtils.autoBoxIfNecessary;
import static com.swift.sandhook.xposedcompat.utils.DexMakerUtils.autoUnboxIfNecessary;
import static com.swift.sandhook.xposedcompat.utils.DexMakerUtils.canCache;
import static com.swift.sandhook.xposedcompat.utils.DexMakerUtils.createResultLocals;
import static com.swift.sandhook.xposedcompat.utils.DexMakerUtils.getObjTypeIdIfPrimitive;
import static com.swift.sandhook.xposedcompat.utils.DexMakerUtils.getSha1Hex;

public class HookerDexMakerNew implements HookMaker {

Expand Down Expand Up @@ -70,7 +71,6 @@ public class HookerDexMakerNew implements HookMaker {
private Class<?> mHookClass;
private Method mHookMethod;
private Method mBackupMethod;
private String mDexDirPath;

private static TypeId<?>[] getParameterTypeIds(Class<?>[] parameterTypes, boolean isStatic) {
int parameterSize = parameterTypes.length;
Expand Down Expand Up @@ -101,7 +101,7 @@ private static Class<?>[] getParameterTypes(Class<?>[] parameterTypes, boolean i
}

public void start(Member member, XposedBridge.AdditionalHookInfo hookInfo,
ClassLoader appClassLoader, String dexDirPath) throws Exception {
ClassLoader appClassLoader) throws Exception {
if (member instanceof Method) {
Method method = (Method) member;
mIsStatic = Modifier.isStatic(method.getModifiers());
Expand Down Expand Up @@ -134,7 +134,6 @@ public void start(Member member, XposedBridge.AdditionalHookInfo hookInfo,
}
mMember = member;
mHookInfo = hookInfo;
mDexDirPath = dexDirPath;
if (appClassLoader == null
|| appClassLoader.getClass().getName().equals("java.lang.BootClassLoader")) {
mAppClassLoader = this.getClass().getClassLoader();
Expand All @@ -150,7 +149,7 @@ public void start(Member member, XposedBridge.AdditionalHookInfo hookInfo,
HookWrapper.HookEntity hookEntity = null;
//try load cache first
try {
ClassLoader loader = mDexMaker.loadClassDirect(mAppClassLoader, new File(mDexDirPath), dexName);
ClassLoader loader = mDexMaker.loadClassDirect(mAppClassLoader, new File(ConfigManager.getCachePath("")), dexName);
if (loader != null) {
hookEntity = loadHookerClass(loader, className);
}
Expand All @@ -171,14 +170,17 @@ private HookWrapper.HookEntity doMake(String className, String dexName) throws E
generateBackupMethod();

ClassLoader loader;
if (TextUtils.isEmpty(mDexDirPath)) {
if (!canCache) {
byte[] dexBytes = mDexMaker.generate();
loader = new InMemoryDexClassLoader(ByteBuffer.wrap(dexBytes), mAppClassLoader);
return loadHookerClass(loader, className);
}
// Create the dex file and load it.
try {
loader = mDexMaker.generateAndLoad(mAppClassLoader, new File(mDexDirPath), dexName, true);
loader = mDexMaker.generateAndLoad(mAppClassLoader, new File(ConfigManager.getCachePath("")), dexName, true);
File dexFile = new File(ConfigManager.getCachePath(dexName));
dexFile.setWritable(true, false);
dexFile.setReadable(true, false);
} catch (IOException e) {
//can not write file
byte[] dexBytes = mDexMaker.generate();
Expand All @@ -203,7 +205,7 @@ private void setup(Class mHookClass) {
}

private String getClassName(Member originMethod) {
return CLASS_NAME_PREFIX + "_" + MD5(originMethod.toString());
return CLASS_NAME_PREFIX + "_" + getSha1Hex(originMethod.toString());
}

public Method getHookMethod() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,10 @@ public final class SandHookXposedBridge {

private static final Map<Member, Method> hookedInfo = new ConcurrentHashMap<>();
private static HookMaker defaultHookMaker = XposedCompat.useNewCallBackup ? new HookerDexMakerNew() : new HookerDexMaker();
private static final AtomicBoolean dexPathInited = new AtomicBoolean(false);
private static File dexDir;

public static Map<Member, HookMethodEntity> entityMap = new ConcurrentHashMap<>();

public static void onForkPost() {
dexPathInited.set(false);
XposedCompat.onForkProcess();
}

Expand All @@ -61,16 +58,6 @@ public static synchronized void hookMethod(Member hookMethod, XposedBridge.Addit
Yahfa.recordHooked(hookMethod); // in case static method got reset.

try {
if (dexPathInited.compareAndSet(false, true)) {
try {
String fixedAppDataDir = XposedCompat.getCacheDir().getAbsolutePath();
dexDir = new File(fixedAppDataDir, "/hookers/");
if (!dexDir.exists())
dexDir.mkdirs();
} catch (Throwable throwable) {
Log.e("SandHook", "error when init dex path", throwable);
}
}
Trace.beginSection("SandXposed");
long timeStart = System.currentTimeMillis();
HookMethodEntity stub = null;
Expand All @@ -89,8 +76,7 @@ public static synchronized void hookMethod(Member hookMethod, XposedBridge.Addit
}
hookMaker.start(hookMethod, additionalHookInfo,
ClassLoaderUtils.createProxyClassLoader(
hookMethod.getDeclaringClass().getClassLoader()),
dexDir == null ? null : dexDir.getAbsolutePath());
hookMethod.getDeclaringClass().getClassLoader()));
hookedInfo.put(hookMethod, hookMaker.getCallBackupMethod());
}
DexLog.d("hook method <" + hookMethod.toString() + "> cost " + (System.currentTimeMillis() - timeStart) + " ms, by " + (stub != null ? "internal stub" : "dex maker"));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
package com.swift.sandhook.xposedcompat.utils;
import com.elderdrivers.riru.edxp.config.ConfigManager;
import com.elderdrivers.riru.edxp.util.Utils;

import java.io.File;
import java.lang.reflect.Method;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
Expand All @@ -12,6 +17,15 @@

public class DexMakerUtils {

public static boolean canCache = true;

static {
File cacheDir = new File(ConfigManager.getCachePath(""));
if(!cacheDir.canRead() || !cacheDir.canWrite()) {
Utils.logW("Cache disabled");
canCache = false;
}
}

private static volatile Method addInstMethod, specMethod;

Expand Down Expand Up @@ -221,4 +235,20 @@ public static String MD5(String source) {
}
return source;
}

public static String getSha1Hex(String text) {
final MessageDigest digest;
try {
digest = MessageDigest.getInstance("SHA-1");
byte[] result = digest.digest(text.getBytes(StandardCharsets.UTF_8));
StringBuilder sb = new StringBuilder();
for (byte b : result) {
sb.append(String.format("%02x", b));
}
return sb.toString();
} catch (Exception e) {
DexLog.e("error hashing target method: " + text, e);
}
return "";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.elderdrivers.riru.edxp.util.Utils;

import java.io.File;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.HashMap;
import java.util.Map;
Expand Down Expand Up @@ -224,7 +225,7 @@ public static String getSha1Hex(String text) {
final MessageDigest digest;
try {
digest = MessageDigest.getInstance("SHA-1");
byte[] result = digest.digest(text.getBytes("UTF-8"));
byte[] result = digest.digest(text.getBytes(StandardCharsets.UTF_8));
StringBuilder sb = new StringBuilder();
for (byte b : result) {
sb.append(String.format("%02x", b));
Expand Down

0 comments on commit 9553af5

Please sign in to comment.