Commit 31b1326a authored by swift_gan's avatar swift_gan

fix

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