XposedHookMethods

public class Main implements IXposedHookLoadPackage
{
    /*
    拦截方法一:
    实现hook操作:使用hook类的名称进行内部查找
    hook_method(类型,类加载器,方法名,参数类型和调用 )
    类加载器 作用:将java类加载到java虚拟机
    Object... 作用:这是java的varag功能,允许方法拥有一个可变长度的参数列表,起始实际上这个参数就是一个数组
    */
    private void hook_method(String className,ClassLoader classLoader,String methodName,Object...parameterTypesAndCall){
        try{
            //找到要拦截的方法并且拦截这个方法
            XposedHelpers.findAndHookMethod(className,classLoader,methodName,parameterTypesAndCallback);
        }catch(Exception e){
            XposedBridge.log(e);
        }
    }
    /*
    拦截方法二:
    实现hook操作:使用反射找到要hook的方法

    hook_methods(类名,方法名,回调方法)
    回调方法选择 XC_MethodHook 或 XC_MethodReplacement

    Class<?>clazz = Class.forName(className);
    注意:每次JVM创建一个对象时候,也创建一个java.lang.Class对象来描述该对象的类型。同一个类的所有实例,都共享同一个Class对象。
    使用java.lang.Class的静态方法 forName() 可以用给定的className,即类名来创建一个对象。
    可以使用clazz.newInstance()创建一个className表示的类的实例。
        
    这里的Class<?>clazz 表示 clazz 可以是任意类型的Class对象。

    java.lang.reflect.Modifier.isPublic(int mod)方法判断如果给定mod参数包含public修饰符,则返回true,否则返回false

    java.lang.reflect.Modifier.isAbstract(int mod)方法判定如果整数参数包含abstract修饰符,则返回true,否则返回false

    java.lang.reflect.Method.getModifiers()方法返回由此Method对象表示的方法的Java语言修饰符转为的整数值。 Modifier类应用于解码修饰符。

    java.lang.Class.getDeclaredMethods() 方法返回一个Method对象的数组,包括公共,保护,默认(包)访问和私有方法,
    但不包括继承的方法。该方法返回一个长度为0的数组,如果类或接口不声明

    */
    private void hook_methods(String className, String methodName, XC_MethodHook xc_methodHook) {
        try {
            Class<?> clazz = Class.forName(className); //反射
            for (Method method : clazz.getDeclaredMethods())
                //如果 (通过反射找到的方法名和准备hook的方法名相同 && 方法判定如果整数参数包含abstract修饰符,则返回true,否则返回false &&
                // 方法判断如果给定参数包含public修饰符,则返回true,否则返回false )
                if (method.getName().equals(methodName) && !Modifier.isAbstract(method.getModifiers()) && Modifier.isPublic(method.getModifiers())) {
                    XposedBridge.hookMethod(method, xc_methodHook); 
                }
        } catch (Exception e) {
            XposedBridge.log(e);
        }
    }
    
    /*
    java.lang.Throwable 类是在Java语言中所有错误和异常的超类。只有在这个类(或它的一个子类)的实例对象由Java虚拟机抛出,也可以由Java throw语句抛出

    对于回调过来的参数MethodHookParam param一般有以下2种用处:
    1.param.args[0]:得到被拦截方法的第一个参数,返回值是Object
    2.param.getResult():得到被拦截方法的执行结果,返回值是Object

    */

    @Override
    public void handleLoadPackage(final LoadPackageParam lpp )throws Throwable{
        //函数内部只调用了一个方法,就是前面两个方法中的一个,这里是使用了使用了第一个hook方法,在参数中传入了一个匿名类
        hook_method("android.telephony.TelephonyManager",lpp.classLoader,"getDeviceId",new XC_MethodHook(){
            @Override //MethodHookParam 钩子方法参数
            protected void afterHookedMethod(MethodHookParam param) throws Throwable{
                /*
                具体的逻辑
                例如:
                Object obj = param.getResult();
                param.setResult("chen sheng");
                */
            }
        });

    }
}

***********************************************************************************************************************************
上面是hook了系统的imei信息,下面是Hook系统的地理位置信息:
方法1:在初始化的时候调用getLastKnowLocation()方法获取最后一个系统中的地理位置信息。
方法2:监听地理位置变化的回调借口中的onLocationChanged()回调方法
    LocationListener locationListener = new LocationListener(){
    ....
    ....
    ....
        //回调方法
        @Override
        public void onLocationChanged(Location location){
            showLocation(location);
        }
    }
    

    Hook方法一:
    hook_methods("android.location.LocationManager","getLastKnowLocation",new XC_MethodHook(){
        @Override
        protected void afterHookMethod(MethodHookParam param) throws Throwable{
            Location l = new Location(LocationManager.PASSIVE_PROVIEDR);
            double lo = -10000d;
            double la = -10000d;
            l.setLatitude(lo);
            l.setLongitude(la);
            param.setResult(l);
        }
    });

    Hook方法二:
    思路:
    首先找到添加监听位置的方法requestLocationUpdates()
    然后通过反射得到这个回调对象,然后在进行操作
    因为回调方法是通过参数把Location对象传递过来,这里需要修改参数
    hook_methods("android.location.LocationManager","getLastKnowLocation",new XC_MethodHook(){
        @Override
        protected void afterHookMethod(MethodHookParam param) throws Throwable{
            if(param.args.length == 4 && (param.args[0] instanceof String)){
                LocationListener ll = (LocationListener)param.args[3];
                Class<?> clazz = LocationListener.class;
                Method m = null;
                for(Method method: clazz.getDeclaredMethods()){
                    if(method.getName.equals("onLocationChanged")){
                        m = method;
                        break;
                    }
                }
                try{
                    if(m != null){
                        Object[] args = new Object[1];
                        Location l = new Location(LocationManager.PASSIVE_PROVIDER);
                        double lo = -10000d;
                        double la = -10000d;
                        l.setLatitude(lo);
                        l.setLongitude(la);
                        args[0]=l;
                        m.invoke(ll,args);
                    }
                }catch(Exception e){
                    XposedBridge.log(e);
                }
            }
        }
    });

 

posted @ 2018-03-05 22:14  最美遇见你  阅读(9194)  评论(0编辑  收藏  举报