Commit 31b1326a authored by swift_gan's avatar swift_gan

fix

parent da81d7bd
...@@ -32,6 +32,13 @@ void disableInterpreterForO(art::mirror::ArtMethod* method) { ...@@ -32,6 +32,13 @@ void disableInterpreterForO(art::mirror::ArtMethod* method) {
SandHook::CastArtMethod::accessFlag->set(method, accessFlag); SandHook::CastArtMethod::accessFlag->set(method, accessFlag);
} }
void setPrivate(art::mirror::ArtMethod* method) {
uint32_t accessFlag = SandHook::CastArtMethod::accessFlag->get(method);
accessFlag &= ~ 0x1;
accessFlag |= 0x2;
SandHook::CastArtMethod::accessFlag->set(method, accessFlag);
}
void ensureMethodCached(art::mirror::ArtMethod *hookMethod, art::mirror::ArtMethod *backupMethod) { void ensureMethodCached(art::mirror::ArtMethod *hookMethod, art::mirror::ArtMethod *backupMethod) {
if (SDK_INT >= ANDROID_P) if (SDK_INT >= ANDROID_P)
return; return;
...@@ -120,7 +127,7 @@ bool doHookWithInline(JNIEnv* env, ...@@ -120,7 +127,7 @@ bool doHookWithInline(JNIEnv* env,
if (SDK_INT >= ANDROID_O) { if (SDK_INT >= ANDROID_O) {
disableInterpreterForO(backupMethod); disableInterpreterForO(backupMethod);
} }
//setPrivate(backupMethod);
hookTrampoline->callOrigin->flushCache(reinterpret_cast<Size>(backupMethod), SandHook::CastArtMethod::size); hookTrampoline->callOrigin->flushCache(reinterpret_cast<Size>(backupMethod), SandHook::CastArtMethod::size);
} }
return true; return true;
......
...@@ -10,6 +10,7 @@ import android.support.v7.widget.Toolbar; ...@@ -10,6 +10,7 @@ import android.support.v7.widget.Toolbar;
import android.view.View; import android.view.View;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.widget.Toast;
import com.swift.sandhook.wrapper.HookErrorException; import com.swift.sandhook.wrapper.HookErrorException;
import com.swift.sandhook.wrapper.HookWrapper; import com.swift.sandhook.wrapper.HookWrapper;
...@@ -76,7 +77,7 @@ public class MainActivity extends AppCompatActivity { ...@@ -76,7 +77,7 @@ public class MainActivity extends AppCompatActivity {
public static int methodBeHooked(int a, int b) { public static int methodBeHooked(int a, int b) {
a = a + 1 + 2; a = a + 1 + 2;
b = b + a + 3; b = b + a + 3;
Log.e("MainActivity", "methodBeHooked called"); //Toast.makeText(MyApp.context, "call origin!", Toast.LENGTH_SHORT).show();
return a + b; return a + b;
} }
......
...@@ -59,15 +59,21 @@ public class SandHook { ...@@ -59,15 +59,21 @@ public class SandHook {
if (target instanceof Method) { if (target instanceof Method) {
((Method)target).setAccessible(true); ((Method)target).setAccessible(true);
} }
return hookMethod(target, hook, backup); boolean res = hookMethod(target, hook, backup);
if (res && backup != null) {
backup.setAccessible(true);
}
return res;
} }
private static void resolveStaticMethod(Member method) { private static void resolveStaticMethod(Member method) {
//ignore result, just call to trigger resolve //ignore result, just call to trigger resolve
try { try {
if (method instanceof Method) { if (method instanceof Method) {
((Method)method).setAccessible(true);
((Method)method).invoke(null); ((Method)method).invoke(null);
} else if (method instanceof Constructor){ } else if (method instanceof Constructor){
((Constructor)method).setAccessible(true);
((Constructor)method).newInstance(null); ((Constructor)method).newInstance(null);
} }
} catch (Exception e) { } catch (Exception e) {
......
...@@ -8,9 +8,15 @@ import com.swift.sandhook.wrapper.HookMethod; ...@@ -8,9 +8,15 @@ import com.swift.sandhook.wrapper.HookMethod;
import com.swift.sandhook.wrapper.HookMethodBackup; import com.swift.sandhook.wrapper.HookMethodBackup;
import com.swift.sandhook.wrapper.MethodParams; import com.swift.sandhook.wrapper.MethodParams;
import java.lang.reflect.Method;
@HookClass(MainActivity.class) @HookClass(MainActivity.class)
public class CustmizeHooker { public class CustmizeHooker {
@HookMethodBackup("methodBeHooked")
@MethodParams({int.class, int.class})
static Method backup;
@HookMethod("methodBeHooked") @HookMethod("methodBeHooked")
@MethodParams({int.class, int.class}) @MethodParams({int.class, int.class})
public static int staticMethodHooked(int a, int b) { public static int staticMethodHooked(int a, int b) {
......
...@@ -5,7 +5,7 @@ import java.lang.annotation.Retention; ...@@ -5,7 +5,7 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; import java.lang.annotation.Target;
@Target({ElementType.METHOD}) @Target({ElementType.METHOD,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
public @interface HookMethodBackup { public @interface HookMethodBackup {
String value() default "<init>"; String value() default "<init>";
......
package com.swift.sandhook.wrapper; package com.swift.sandhook.wrapper;
import android.text.TextUtils;
import com.swift.sandhook.SandHook; import com.swift.sandhook.SandHook;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
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;
...@@ -25,6 +28,7 @@ public class HookWrapper { ...@@ -25,6 +28,7 @@ public class HookWrapper {
if (targetHookClass == null) if (targetHookClass == null)
throw new HookErrorException("error hook wrapper class :" + clazz.getName()); throw new HookErrorException("error hook wrapper class :" + clazz.getName());
Map<Member,HookEntity> hookEntityMap = getHookMethods(targetHookClass, clazz); Map<Member,HookEntity> hookEntityMap = getHookMethods(targetHookClass, clazz);
fillBackupMethod(clazz, hookEntityMap);
for (HookEntity entity:hookEntityMap.values()) { for (HookEntity entity:hookEntityMap.values()) {
if (entity.target != null && entity.hook != null) { if (entity.target != null && entity.hook != null) {
SandHook.hook(entity.target, entity.hook, entity.backup); SandHook.hook(entity.target, entity.hook, entity.backup);
...@@ -33,6 +37,33 @@ public class HookWrapper { ...@@ -33,6 +37,33 @@ public class HookWrapper {
} }
} }
private static void fillBackupMethod(Class<?> clazz, Map<Member, HookEntity> hookEntityMap) {
Field[] fields = clazz.getDeclaredFields();
if (fields == null || fields.length == 0)
return;
if (hookEntityMap.isEmpty())
return;
for (Field field:fields) {
if (!field.getType().equals(Method.class))
continue;
if (!Modifier.isStatic(field.getModifiers()))
continue;
HookMethodBackup hookMethodBackup = field.getAnnotation(HookMethodBackup.class);
if (hookMethodBackup == null)
continue;
for (HookEntity hookEntity:hookEntityMap.values()) {
if (TextUtils.equals(hookEntity.target.getName(), hookMethodBackup.value()) && hookEntity.backup != null && samePars(field, hookEntity.pars)) {
field.setAccessible(true);
try {
field.set(null, hookEntity.backup);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
}
private static Map<Member, HookEntity> getHookMethods(Class targetHookClass, Class<?> hookWrapperClass) throws HookErrorException { private static Map<Member, HookEntity> getHookMethods(Class targetHookClass, Class<?> hookWrapperClass) throws HookErrorException {
Map<Member,HookEntity> hookEntityMap = new HashMap<>(); Map<Member,HookEntity> hookEntityMap = new HashMap<>();
Method[] methods = hookWrapperClass.getDeclaredMethods(); Method[] methods = hookWrapperClass.getDeclaredMethods();
...@@ -81,6 +112,7 @@ public class HookWrapper { ...@@ -81,6 +112,7 @@ public class HookWrapper {
entity = new HookEntity(foundMethod); entity = new HookEntity(foundMethod);
hookEntityMap.put(foundMethod, entity); hookEntityMap.put(foundMethod, entity);
} }
entity.pars = pars;
entity.backup = method; entity.backup = method;
} else { } else {
continue; continue;
...@@ -111,6 +143,48 @@ public class HookWrapper { ...@@ -111,6 +143,48 @@ public class HookWrapper {
} }
} }
private static Class[] parseMethodPars(Field field) throws HookErrorException {
MethodParams methodParams = field.getAnnotation(MethodParams.class);
MethodReflectParams methodReflectParams = field.getAnnotation(MethodReflectParams.class);
if (methodParams != null) {
return methodParams.value();
} else if (methodReflectParams != null) {
if (methodReflectParams.value().length == 0)
return null;
Class[] pars = new Class[methodReflectParams.value().length];
for (int i = 0;i < methodReflectParams.value().length; i++) {
try {
pars[i] = Class.forName(methodReflectParams.value()[i]);
} catch (ClassNotFoundException e) {
throw new HookErrorException("hook method pars error: " + field.getName(), e);
}
}
return pars;
} else {
return null;
}
}
private static boolean samePars(Field field, Class[] par) {
try {
Class[] parsOnField = parseMethodPars(field);
if (par == null)
par = new Class[0];
if (parsOnField == null)
parsOnField = new Class[0];
if (par.length != parsOnField.length)
return false;
for (int i = 0;i < par.length;i++) {
if (par[i] != parsOnField[i])
return false;
}
return true;
} catch (HookErrorException e) {
return false;
}
}
...@@ -173,6 +247,8 @@ public class HookWrapper { ...@@ -173,6 +247,8 @@ public class HookWrapper {
public Method hook; public Method hook;
public Method backup; public Method backup;
public Class[] pars;
public HookEntity(Member target) { public HookEntity(Member target) {
this.target = target; this.target = target;
} }
......
...@@ -5,7 +5,7 @@ import java.lang.annotation.Retention; ...@@ -5,7 +5,7 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; import java.lang.annotation.Target;
@Target({ElementType.METHOD}) @Target({ElementType.METHOD,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
public @interface MethodParams { public @interface MethodParams {
Class<?>[] value(); Class<?>[] value();
......
...@@ -5,7 +5,7 @@ import java.lang.annotation.Retention; ...@@ -5,7 +5,7 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; import java.lang.annotation.Target;
@Target({ElementType.METHOD}) @Target({ElementType.METHOD,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
public @interface MethodReflectParams { public @interface MethodReflectParams {
String[] value(); String[] value();
......
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