Commit 60fd35cd authored by swift_gan's avatar swift_gan

fix param parser

parent f65fd71c
......@@ -204,6 +204,10 @@ public class SandHook {
return getObjectNative(threadSelf, address);
}
public static boolean canGetObjectAddress() {
return Unsafe.support();
}
public static long getObjectAddress(Object object) {
return Unsafe.getObjectAddress(object);
}
......
......@@ -35,7 +35,7 @@ public class ParamWrapper {
} else if (objectType == char.class) {
return (char)address;
} else if (objectType == boolean.class) {
return address == 0;
return address != 0;
} else {
throw new RuntimeException("unknown type: " + objectType.toString());
}
......@@ -57,7 +57,7 @@ public class ParamWrapper {
} else if (objectType == char.class) {
return (char)address;
} else if (objectType == boolean.class) {
return address == 0;
return address != 0;
} else {
throw new RuntimeException("unknown type: " + objectType.toString());
}
......@@ -87,7 +87,7 @@ public class ParamWrapper {
} else if (objectType == char.class) {
return (char)object;
} else if (objectType == boolean.class) {
return object == Boolean.TRUE ? 0 : 1;
return object == Boolean.TRUE ? 1 : 0;
} else {
throw new RuntimeException("unknown type: " + objectType.toString());
}
......@@ -111,7 +111,7 @@ public class ParamWrapper {
} else if (objectType == char.class) {
return (char)object;
} else if (objectType == boolean.class) {
return object == Boolean.TRUE ? 0 : 1;
return object == Boolean.TRUE ? 1 : 0;
} else {
throw new RuntimeException("unknown type: " + objectType.toString());
}
......
......@@ -19,6 +19,7 @@ package com.swift.sandhook.utils;
import android.util.Log;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public final class Unsafe {
private static final String TAG = "Unsafe";
......@@ -26,6 +27,13 @@ public final class Unsafe {
private static Object unsafe;
private static Class unsafeClass;
private static Method arrayBaseOffsetMethod,
arrayIndexScaleMethod,
getIntMethod,
getLongMethod;
private volatile static boolean supported = false;
static {
try {
unsafeClass = Class.forName("sun.misc.Unsafe");
......@@ -41,6 +49,20 @@ public final class Unsafe {
Log.w(TAG, "Unsafe not found o.O");
}
}
if (unsafe != null) {
try {
arrayBaseOffsetMethod = unsafeClass.getDeclaredMethod("arrayBaseOffset", Class.class);
arrayIndexScaleMethod = unsafeClass.getDeclaredMethod("arrayIndexScale", Class.class);
getIntMethod = unsafeClass.getDeclaredMethod("getInt", Object.class, long.class);
getLongMethod = unsafeClass.getDeclaredMethod("getLong", Object.class, long.class);
supported = true;
} catch (Exception e) {
}
}
}
public static boolean support() {
return supported;
}
private Unsafe() {
......@@ -49,7 +71,7 @@ public final class Unsafe {
@SuppressWarnings("unchecked")
public static int arrayBaseOffset(Class cls) {
try {
return (int) unsafeClass.getDeclaredMethod("arrayBaseOffset", Class.class).invoke(unsafe, cls);
return (int) arrayBaseOffsetMethod.invoke(unsafe, cls);
} catch (Exception e) {
Log.w(TAG, e);
return 0;
......@@ -59,17 +81,7 @@ public final class Unsafe {
@SuppressWarnings("unchecked")
public static int arrayIndexScale(Class cls) {
try {
return (int) unsafeClass.getDeclaredMethod("arrayIndexScale", Class.class).invoke(unsafe, cls);
} catch (Exception e) {
Log.w(TAG, e);
return 0;
}
}
@SuppressWarnings("unchecked")
public static long objectFieldOffset(Field field) {
try {
return (long) unsafeClass.getDeclaredMethod("objectFieldOffset", Field.class).invoke(unsafe, field);
return (int) arrayIndexScaleMethod.invoke(unsafe, cls);
} catch (Exception e) {
Log.w(TAG, e);
return 0;
......@@ -79,7 +91,7 @@ public final class Unsafe {
@SuppressWarnings("unchecked")
public static int getInt(Object array, long offset) {
try {
return (int) unsafeClass.getDeclaredMethod("getInt", Object.class, long.class).invoke(unsafe, array, offset);
return (int) getIntMethod.invoke(unsafe, array, offset);
} catch (Exception e) {
Log.w(TAG, e);
return 0;
......@@ -89,39 +101,13 @@ public final class Unsafe {
@SuppressWarnings("unchecked")
public static long getLong(Object array, long offset) {
try {
return (long) unsafeClass.getDeclaredMethod("getLong", Object.class, long.class).invoke(unsafe, array, offset);
return (long) getLongMethod.invoke(unsafe, array, offset);
} catch (Exception e) {
Log.w(TAG, e);
return 0;
}
}
@SuppressWarnings("unchecked")
public static void putLong(Object array, long offset, long value) {
try {
unsafeClass.getDeclaredMethod("putLongVolatile", Object.class, long.class, long.class).invoke(unsafe, array, offset, value);
} catch (Exception e) {
try {
unsafeClass.getDeclaredMethod("putLong", Object.class, long.class, long.class).invoke(unsafe, array, offset, value);
} catch (Exception e1) {
Log.w(TAG, e);
}
}
}
@SuppressWarnings("unchecked")
public static void putInt(Object array, long offset, int value) {
try {
unsafeClass.getDeclaredMethod("putIntVolatile", Object.class, long.class, int.class).invoke(unsafe, array, offset, value);
} catch (Exception e) {
try {
unsafeClass.getDeclaredMethod("putIntVolatile", Object.class, long.class, int.class).invoke(unsafe, array, offset, value);
} catch (Exception e1) {
Log.w(TAG, e);
}
}
}
public static long getObjectAddress(Object obj) {
try {
Object[] array = new Object[]{obj};
......
package com.swift.sandhook.xposedcompat.hookstub;
import android.util.Pair;
import com.swift.sandhook.SandHook;
import com.swift.sandhook.utils.ParamWrapper;
......@@ -9,7 +7,6 @@ import java.lang.reflect.Constructor;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
......@@ -49,6 +46,10 @@ public class HookStubManager {
public static HookMethodEntity getHookMethodEntity(Member origin) {
if (!support()) {
return null;
}
Class[] parType;
Class retType;
boolean isStatic = Modifier.isStatic(origin.getModifiers());
......@@ -284,4 +285,8 @@ public class HookStubManager {
return args != null && args.length > 0;
}
public static boolean support() {
return SandHook.canGetObject() && SandHook.canGetObjectAddress();
}
}
......@@ -12,11 +12,11 @@ import com.swift.sandhook.xposedcompat.utils.FileUtils;
import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import de.robv.android.xposed.XposedBridge;
......@@ -28,6 +28,8 @@ public final class DynamicBridge {
private static final AtomicBoolean dexPathInited = new AtomicBoolean(false);
private static File dexDir;
public static Map<Member,HookMethodEntity> entityMap = new HashMap<>();
public static void onForkPost() {
dexPathInited.set(false);
}
......@@ -38,17 +40,13 @@ public final class DynamicBridge {
return;
}
if (hookedInfo.containsKey(hookMethod)) {
if (hookedInfo.containsKey(hookMethod) || entityMap.containsKey(hookMethod)) {
DexLog.w("already hook method:" + hookMethod.toString());
return;
}
DexLog.d("start to generate class for: " + hookMethod);
try {
// using file based DexClassLoader
if (dexPathInited.compareAndSet(false, true)) {
// delete previous compiled dex to prevent potential crashing
// TODO find a way to reuse them in consideration of performance
try {
String fixedAppDataDir = XposedCompat.cacheDir.getAbsolutePath();
dexDir = new File(fixedAppDataDir, "/sandxposed/");
......@@ -63,15 +61,16 @@ public final class DynamicBridge {
HookMethodEntity stub = HookStubManager.getHookMethodEntity(hookMethod);
if (stub != null) {
SandHook.hook(new HookWrapper.HookEntity(hookMethod, stub.hook, stub.backup));
entityMap.put(hookMethod, stub);
} else {
dexMaker.start(hookMethod, additionalHookInfo,
XposedCompat.classLoader, dexDir == null ? null : dexDir.getAbsolutePath());
hookedInfo.put(hookMethod, dexMaker.getCallBackupMethod());
}
DexLog.d("hook method <" + hookMethod.toString() + "> use " + (System.currentTimeMillis() - timeStart) + " ms.");
DexLog.d("hook method <" + hookMethod.toString() + "> cost " + (System.currentTimeMillis() - timeStart) + " ms, by " + (stub != null ? "internal stub." : "dex maker"));
Trace.endSection();
} catch (Exception e) {
DexLog.e("error occur when generating dex. dexDir=" + dexDir, e);
DexLog.e("error occur when hook method <" + hookMethod.toString() + ">", e);
}
}
......@@ -106,10 +105,11 @@ public final class DynamicBridge {
}
public static Object invokeOriginalMethod(Member method, Object thisObject, Object[] args)
throws InvocationTargetException, IllegalAccessException {
throws Throwable {
Method callBackup = hookedInfo.get(method);
if (callBackup == null) {
throw new IllegalStateException("method not hooked, cannot call original method.");
//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!");
......
......@@ -391,7 +391,7 @@ public final class XposedBridge {
Class<?>[] parameterTypes,
Class<?> returnType,
Object thisObject, Object[] args)
throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
throws Throwable {
return DynamicBridge.invokeOriginalMethod(method, thisObject, args);
}
......@@ -421,7 +421,7 @@ public final class XposedBridge {
* if an exception was thrown by the invoked method
*/
public static Object invokeOriginalMethod(Member method, Object thisObject, Object[] args)
throws NullPointerException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
throws Throwable {
if (args == null) {
args = EMPTY_ARRAY;
}
......
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