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;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.util.Log;
import android.view.Menu;
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.InterImpl;
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.InvocationTargetException;
import java.lang.reflect.Method;
public class MainActivity extends AppCompatActivity {
// Used to load the 'native-lib' library on application startup.
Inter inter;
@Override
......@@ -61,6 +55,7 @@ public class MainActivity extends AppCompatActivity {
str.add1();
str.add2();
str.testNewHookApi(this, 1);
str.jni_test();
......
......@@ -9,6 +9,7 @@ import com.swift.sandhook.testHookers.CtrHook;
import com.swift.sandhook.testHookers.CustmizeHooker;
import com.swift.sandhook.testHookers.JniHooker;
import com.swift.sandhook.testHookers.LogHooker;
import com.swift.sandhook.testHookers.NewAnnotationApiHooker;
import com.swift.sandhook.testHookers.ObjectHooker;
import com.swift.sandhook.wrapper.HookErrorException;
import com.swift.sandhook.xposedcompat.XposedCompat;
......@@ -28,7 +29,8 @@ public class MyApp extends Application {
LogHooker.class,
CustmizeHooker.class,
ActivityHooker.class,
ObjectHooker.class);
ObjectHooker.class,
NewAnnotationApiHooker.class);
} catch (HookErrorException e) {
e.printStackTrace();
}
......
package com.swift.sandhook.test;
import com.swift.sandhook.MainActivity;
public class TestClass {
public int a = 1;
......@@ -20,6 +22,12 @@ public class TestClass {
b++;
}
public void testNewHookApi (MainActivity activity, int x) {
x++;
a++;
b++;
}
public native void jni_test();
}
......@@ -8,6 +8,7 @@ import com.swift.sandhook.annotation.HookClass;
import com.swift.sandhook.annotation.HookMethod;
import com.swift.sandhook.annotation.HookMethodBackup;
import com.swift.sandhook.annotation.MethodParams;
import com.swift.sandhook.annotation.ThisObject;
import java.lang.reflect.Method;
......@@ -36,13 +37,13 @@ public class ActivityHooker {
}
@HookMethod("onPause")
public static void onPause(Activity thiz) {
public static void onPause(@ThisObject Activity thiz) {
Log.e("ActivityHooker", "hooked onPause success " + thiz);
onPauseBackup(thiz);
}
@HookMethodBackup("onPause")
public static void onPauseBackup(Activity thiz) {
public static void onPauseBackup(@ThisObject Activity thiz) {
//invoke self to kill inline
onPauseBackup(thiz);
}
......
......@@ -2,26 +2,24 @@ package com.swift.sandhook.testHookers;
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.HookMethod;
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)
public class CtrHook {
@HookMethod
@MethodParams(int.class)
public static void onCtr(TestClass thiz, int a) {
public static void onCtr(@ThisObject TestClass thiz, int a) {
Log.e("TestClassHook", "TestClass(int) been hooked");
onCtrBackup(thiz, a);
}
@HookMethodBackup
@MethodParams(int.class)
public static void onCtrBackup(TestClass thiz, int a) {
public static void onCtrBackup(@ThisObject TestClass thiz, int a) {
onCtrBackup(thiz, a);
}
......@@ -53,4 +51,5 @@ public class CtrHook {
onAdd2Backup(thiz);
}
}
......@@ -6,7 +6,6 @@ import com.swift.sandhook.MainActivity;
import com.swift.sandhook.annotation.HookClass;
import com.swift.sandhook.annotation.HookMethod;
import com.swift.sandhook.annotation.HookMethodBackup;
import com.swift.sandhook.annotation.HookMode;
import com.swift.sandhook.annotation.MethodParams;
import java.lang.reflect.Method;
......@@ -20,7 +19,6 @@ public class CustmizeHooker {
@HookMethod("methodBeHooked")
@MethodParams({int.class, int.class})
@HookMode(HookMode.REPLACE)
public static int staticMethodHooked(int a, int b) {
Log.e("CustmizeHooker", "methodBeHooked be hooked");
try {
......
......@@ -6,22 +6,20 @@ import com.swift.sandhook.annotation.HookClass;
import com.swift.sandhook.annotation.HookMethod;
import com.swift.sandhook.annotation.HookMethodBackup;
import com.swift.sandhook.annotation.HookMode;
import com.swift.sandhook.annotation.MethodParams;
import com.swift.sandhook.annotation.Param;
@HookClass(Log.class)
public class LogHooker {
@HookMethod("w")
@MethodParams({String.class, String.class})
@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);
return onCreateBackup(tag, msg);
}
@HookMethodBackup("w")
@MethodParams({String.class, String.class})
public static int onCreateBackup(String tag, String msg) {
public static int onCreateBackup(String tag, @Param("java.lang.String") Object 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;
import com.swift.sandhook.annotation.HookReflectClass;
import com.swift.sandhook.annotation.MethodParams;
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.Field;
import java.lang.reflect.Member;
......@@ -148,6 +151,16 @@ public class HookWrapper {
}
}
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 {
return null;
}
......@@ -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 {
Class clazz;
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