Commit f130ce34 authored by swift_gan's avatar swift_gan

add new hook api

parent 5ac8c414
package com.swift.sandhook.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface Param {
String value() default "";
}
package com.swift.sandhook.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface ThisObject {
}
package com.swift.sandhook; package com.swift.sandhook;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import android.support.design.widget.FloatingActionButton; import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar; import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity; import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar; import android.support.v7.widget.Toolbar;
import android.view.View; import android.util.Log;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.widget.Toast; import android.view.View;
import android.widget.TextView;
import com.swift.sandhook.test.Inter; import com.swift.sandhook.test.Inter;
import com.swift.sandhook.test.InterImpl; import com.swift.sandhook.test.InterImpl;
import com.swift.sandhook.test.TestClass; import com.swift.sandhook.test.TestClass;
import com.swift.sandhook.wrapper.HookErrorException;
import com.swift.sandhook.wrapper.HookWrapper;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class MainActivity extends AppCompatActivity { public class MainActivity extends AppCompatActivity {
// Used to load the 'native-lib' library on application startup.
Inter inter; Inter inter;
@Override @Override
...@@ -61,6 +55,7 @@ public class MainActivity extends AppCompatActivity { ...@@ -61,6 +55,7 @@ public class MainActivity extends AppCompatActivity {
str.add1(); str.add1();
str.add2(); str.add2();
str.testNewHookApi(this, 1);
str.jni_test(); str.jni_test();
......
...@@ -9,6 +9,7 @@ import com.swift.sandhook.testHookers.CtrHook; ...@@ -9,6 +9,7 @@ import com.swift.sandhook.testHookers.CtrHook;
import com.swift.sandhook.testHookers.CustmizeHooker; import com.swift.sandhook.testHookers.CustmizeHooker;
import com.swift.sandhook.testHookers.JniHooker; import com.swift.sandhook.testHookers.JniHooker;
import com.swift.sandhook.testHookers.LogHooker; import com.swift.sandhook.testHookers.LogHooker;
import com.swift.sandhook.testHookers.NewAnnotationApiHooker;
import com.swift.sandhook.testHookers.ObjectHooker; import com.swift.sandhook.testHookers.ObjectHooker;
import com.swift.sandhook.wrapper.HookErrorException; import com.swift.sandhook.wrapper.HookErrorException;
import com.swift.sandhook.xposedcompat.XposedCompat; import com.swift.sandhook.xposedcompat.XposedCompat;
...@@ -28,7 +29,8 @@ public class MyApp extends Application { ...@@ -28,7 +29,8 @@ public class MyApp extends Application {
LogHooker.class, LogHooker.class,
CustmizeHooker.class, CustmizeHooker.class,
ActivityHooker.class, ActivityHooker.class,
ObjectHooker.class); ObjectHooker.class,
NewAnnotationApiHooker.class);
} catch (HookErrorException e) { } catch (HookErrorException e) {
e.printStackTrace(); e.printStackTrace();
} }
......
package com.swift.sandhook.test; package com.swift.sandhook.test;
import com.swift.sandhook.MainActivity;
public class TestClass { public class TestClass {
public int a = 1; public int a = 1;
...@@ -20,6 +22,12 @@ public class TestClass { ...@@ -20,6 +22,12 @@ public class TestClass {
b++; b++;
} }
public void testNewHookApi (MainActivity activity, int x) {
x++;
a++;
b++;
}
public native void jni_test(); public native void jni_test();
} }
...@@ -8,6 +8,7 @@ import com.swift.sandhook.annotation.HookClass; ...@@ -8,6 +8,7 @@ import com.swift.sandhook.annotation.HookClass;
import com.swift.sandhook.annotation.HookMethod; import com.swift.sandhook.annotation.HookMethod;
import com.swift.sandhook.annotation.HookMethodBackup; import com.swift.sandhook.annotation.HookMethodBackup;
import com.swift.sandhook.annotation.MethodParams; import com.swift.sandhook.annotation.MethodParams;
import com.swift.sandhook.annotation.ThisObject;
import java.lang.reflect.Method; import java.lang.reflect.Method;
...@@ -36,13 +37,13 @@ public class ActivityHooker { ...@@ -36,13 +37,13 @@ public class ActivityHooker {
} }
@HookMethod("onPause") @HookMethod("onPause")
public static void onPause(Activity thiz) { public static void onPause(@ThisObject Activity thiz) {
Log.e("ActivityHooker", "hooked onPause success " + thiz); Log.e("ActivityHooker", "hooked onPause success " + thiz);
onPauseBackup(thiz); onPauseBackup(thiz);
} }
@HookMethodBackup("onPause") @HookMethodBackup("onPause")
public static void onPauseBackup(Activity thiz) { public static void onPauseBackup(@ThisObject Activity thiz) {
//invoke self to kill inline //invoke self to kill inline
onPauseBackup(thiz); onPauseBackup(thiz);
} }
......
...@@ -2,26 +2,24 @@ package com.swift.sandhook.testHookers; ...@@ -2,26 +2,24 @@ package com.swift.sandhook.testHookers;
import android.util.Log; import android.util.Log;
import com.swift.sandhook.annotation.HookMode;
import com.swift.sandhook.test.TestClass;
import com.swift.sandhook.annotation.HookClass; import com.swift.sandhook.annotation.HookClass;
import com.swift.sandhook.annotation.HookMethod; import com.swift.sandhook.annotation.HookMethod;
import com.swift.sandhook.annotation.HookMethodBackup; import com.swift.sandhook.annotation.HookMethodBackup;
import com.swift.sandhook.annotation.MethodParams; import com.swift.sandhook.annotation.HookMode;
import com.swift.sandhook.annotation.ThisObject;
import com.swift.sandhook.test.TestClass;
@HookClass(TestClass.class) @HookClass(TestClass.class)
public class CtrHook { public class CtrHook {
@HookMethod @HookMethod
@MethodParams(int.class) public static void onCtr(@ThisObject TestClass thiz, int a) {
public static void onCtr(TestClass thiz, int a) {
Log.e("TestClassHook", "TestClass(int) been hooked"); Log.e("TestClassHook", "TestClass(int) been hooked");
onCtrBackup(thiz, a); onCtrBackup(thiz, a);
} }
@HookMethodBackup @HookMethodBackup
@MethodParams(int.class) public static void onCtrBackup(@ThisObject TestClass thiz, int a) {
public static void onCtrBackup(TestClass thiz, int a) {
onCtrBackup(thiz, a); onCtrBackup(thiz, a);
} }
...@@ -53,4 +51,5 @@ public class CtrHook { ...@@ -53,4 +51,5 @@ public class CtrHook {
onAdd2Backup(thiz); onAdd2Backup(thiz);
} }
} }
...@@ -6,7 +6,6 @@ import com.swift.sandhook.MainActivity; ...@@ -6,7 +6,6 @@ import com.swift.sandhook.MainActivity;
import com.swift.sandhook.annotation.HookClass; import com.swift.sandhook.annotation.HookClass;
import com.swift.sandhook.annotation.HookMethod; import com.swift.sandhook.annotation.HookMethod;
import com.swift.sandhook.annotation.HookMethodBackup; import com.swift.sandhook.annotation.HookMethodBackup;
import com.swift.sandhook.annotation.HookMode;
import com.swift.sandhook.annotation.MethodParams; import com.swift.sandhook.annotation.MethodParams;
import java.lang.reflect.Method; import java.lang.reflect.Method;
...@@ -20,7 +19,6 @@ public class CustmizeHooker { ...@@ -20,7 +19,6 @@ public class CustmizeHooker {
@HookMethod("methodBeHooked") @HookMethod("methodBeHooked")
@MethodParams({int.class, int.class}) @MethodParams({int.class, int.class})
@HookMode(HookMode.REPLACE)
public static int staticMethodHooked(int a, int b) { public static int staticMethodHooked(int a, int b) {
Log.e("CustmizeHooker", "methodBeHooked be hooked"); Log.e("CustmizeHooker", "methodBeHooked be hooked");
try { try {
......
...@@ -6,22 +6,20 @@ import com.swift.sandhook.annotation.HookClass; ...@@ -6,22 +6,20 @@ import com.swift.sandhook.annotation.HookClass;
import com.swift.sandhook.annotation.HookMethod; import com.swift.sandhook.annotation.HookMethod;
import com.swift.sandhook.annotation.HookMethodBackup; import com.swift.sandhook.annotation.HookMethodBackup;
import com.swift.sandhook.annotation.HookMode; import com.swift.sandhook.annotation.HookMode;
import com.swift.sandhook.annotation.MethodParams; import com.swift.sandhook.annotation.Param;
@HookClass(Log.class) @HookClass(Log.class)
public class LogHooker { public class LogHooker {
@HookMethod("w") @HookMethod("w")
@MethodParams({String.class, String.class})
@HookMode(HookMode.INLINE) @HookMode(HookMode.INLINE)
public static int onCreate(String tag, String msg) { public static int onCreate(String tag, @Param("java.lang.String") Object msg) {
Log.e("LogHooker", "hooked success " + tag); Log.e("LogHooker", "hooked success " + tag);
return onCreateBackup(tag, msg); return onCreateBackup(tag, msg);
} }
@HookMethodBackup("w") @HookMethodBackup("w")
@MethodParams({String.class, String.class}) public static int onCreateBackup(String tag, @Param("java.lang.String") Object msg) {
public static int onCreateBackup(String tag, String msg) {
return onCreateBackup(tag, msg); return onCreateBackup(tag, msg);
} }
......
package com.swift.sandhook.testHookers;
import android.app.Activity;
import android.util.Log;
import com.swift.sandhook.annotation.HookClass;
import com.swift.sandhook.annotation.HookMethod;
import com.swift.sandhook.annotation.HookMethodBackup;
import com.swift.sandhook.annotation.Param;
import com.swift.sandhook.annotation.ThisObject;
import com.swift.sandhook.test.TestClass;
@HookClass(TestClass.class)
public class NewAnnotationApiHooker {
@HookMethod("testNewHookApi")
public static void onTestNewHookApi(@ThisObject TestClass thiz, @Param("com.swift.sandhook.MainActivity") Activity activity, int a) {
Log.e("TestClassHook", "testNewHookApi been hooked");
onTestNewHookApiBackup(thiz, activity, a);
}
@HookMethodBackup("testNewHookApi")
public static void onTestNewHookApiBackup(@ThisObject TestClass thiz, @Param("com.swift.sandhook.MainActivity") Activity activity, int a) {
onTestNewHookApiBackup(thiz, activity, a);
}
}
...@@ -9,7 +9,10 @@ import com.swift.sandhook.annotation.HookMethodBackup; ...@@ -9,7 +9,10 @@ import com.swift.sandhook.annotation.HookMethodBackup;
import com.swift.sandhook.annotation.HookReflectClass; import com.swift.sandhook.annotation.HookReflectClass;
import com.swift.sandhook.annotation.MethodParams; import com.swift.sandhook.annotation.MethodParams;
import com.swift.sandhook.annotation.MethodReflectParams; import com.swift.sandhook.annotation.MethodReflectParams;
import com.swift.sandhook.annotation.Param;
import com.swift.sandhook.annotation.ThisObject;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Member; import java.lang.reflect.Member;
...@@ -148,6 +151,16 @@ public class HookWrapper { ...@@ -148,6 +151,16 @@ public class HookWrapper {
} }
} }
return pars; return pars;
} else if (getParsCount(method) > 0) {
if (getParsCount(method) == 1) {
if (hasThisObject(method)) {
return parseMethodParsNew(classLoader, method);
} else {
return null;
}
} else {
return parseMethodParsNew(classLoader, method);
}
} else { } else {
return null; return null;
} }
...@@ -175,6 +188,78 @@ public class HookWrapper { ...@@ -175,6 +188,78 @@ public class HookWrapper {
} }
} }
private static Class[] parseMethodParsNew(ClassLoader classLoader, Method method) throws HookErrorException {
Class[] hookMethodPars = method.getParameterTypes();
if (hookMethodPars == null || hookMethodPars.length == 0)
return null;
Annotation[][] annotations = method.getParameterAnnotations();
Class[] realPars = null;
int parIndex = 0;
for (int i = 0;i < annotations.length;i ++) {
Class hookPar = hookMethodPars[i];
Annotation[] methodAnnos = annotations[i];
if (i == 0) {
//check thisObject
if (isThisObject(methodAnnos)) {
realPars = new Class[annotations.length - 1];
continue;
} else {
//static method
realPars = new Class[annotations.length];
}
}
try {
realPars[parIndex] = getRealParType(classLoader, hookPar, methodAnnos);
} catch (Exception e) {
throw new HookErrorException("hook method <" + method.getName() + "> parser pars error", e);
}
parIndex++;
}
return realPars;
}
private static Class getRealParType(ClassLoader classLoader, Class hookPar, Annotation[] annotations) throws Exception {
if (annotations == null || annotations.length == 0)
return hookPar;
for (Annotation annotation:annotations) {
if (annotation instanceof Param) {
Param param = (Param) annotation;
if (TextUtils.isEmpty(param.value()))
return hookPar;
Class realPar = classNameToClass(param.value(), classLoader);
if (realPar.equals(hookPar) || hookPar.isAssignableFrom(realPar)) {
return realPar;
} else {
throw new ClassCastException("hook method par cast error!");
}
}
}
return hookPar;
}
private static boolean hasThisObject(Method method) {
Annotation[][] annotations = method.getParameterAnnotations();
if (annotations == null || annotations.length == 0)
return false;
Annotation[] thisParAnno = annotations[0];
return isThisObject(thisParAnno);
}
private static boolean isThisObject(Annotation[] annotations) {
if (annotations == null || annotations.length == 0)
return false;
for (Annotation annotation:annotations) {
if (annotation instanceof ThisObject)
return true;
}
return false;
}
private static int getParsCount(Method method) {
Class[] hookMethodPars = method.getParameterTypes();
return hookMethodPars == null ? 0 : hookMethodPars.length;
}
private static Class classNameToClass(String name, ClassLoader classLoader) throws ClassNotFoundException { private static Class classNameToClass(String name, ClassLoader classLoader) throws ClassNotFoundException {
Class clazz; Class clazz;
switch (name) { switch (name) {
......
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