zoukankan      html  css  js  c++  java
  • Xposed框架Hook Android应用的所有类方法打印Log日志

    本文博客地址:https://blog.csdn.net/QQ1084283172/article/details/80954759

    在进行Android程序的逆向分析的时候,经常需要Android程序的静态分析和动态调试的结合,尤其是对一些加固后的Android类方法被调用的确认,需要Hook java类方法打印java类方法的调用堆栈。有幸在网上看到了这篇文章《XPosed暴力列举Package下所有的方法调用》,按照作者的思路和代码进行了验证和尝试,发现效果并不明显而且不好用,对多dex的Android应用支持不好,因此在此基础上调整了一下思路,简单的写了份xposed Hook代码,如下:
    package com.xposed.enumeratorClassHook;
    
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    import java.lang.reflect.Modifier;
    
    import de.robv.android.xposed.IXposedHookLoadPackage;
    import de.robv.android.xposed.XC_MethodHook;
    import de.robv.android.xposed.XC_MethodHook.MethodHookParam;
    import de.robv.android.xposed.XposedBridge;
    import de.robv.android.xposed.XposedHelpers;
    import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam;
    import static de.robv.android.xposed.XposedHelpers.findAndHookMethod;
    
    // 自定义的回调函数接口
    public class Module implements IXposedHookLoadPackage {
    
        static String strClassName = "";
    
        @Override
        public void handleLoadPackage(LoadPackageParam lpparam) throws Throwable {
    
            // 被Hook操作的目标Android应用的包名,进行Hook操作的过滤
            String strPackageName = "com.guji.loveparty";
            if (lpparam.packageName.equals(strPackageName)) {
    
                XposedBridge.log("Loaded App:" + lpparam.packageName);
    
    //          // 枚举指定Android应用的所有类方法并对指定的类方法进行java Hook操作
    //          PackageHooker packageHooker = new PackageHooker(lpparam);
    //          // 获取指定类的方法、属性变量、内部类等的信息
    //          ClassLoader classLoader = lpparam.classLoader;
    //          Class<?> dumpClass = XposedHelpers.findClass("com.tencent.bugly.lejiagu.crashreport.BuglyLog", classLoader);
    //          packageHooker.dumpClass(dumpClass);
    
    //           // 被Hook操作的目标类的名称
    //          String strNomalCln = "";
    //           // 被Hook操作的目标类的方法的名称
    //          String strNomalMdn = "";
    //          // 在Android应用默认的classes.dex文件中的类方法的Hook操作
    //          XposedHelpers.findAndHookMethod(
    //                   // 被Hook操作的目标类
    //                  strNomalCln,
    //                  lpparam.classLoader, 
    //                  // 被Hook操作的目标类方法
    //                  strNomalMdn,     
    //                  // 被Hook操作的目标类方法的第1个参数的类型
    //                  String.class, 
    //                  // 被Hook操作的目标类方法的第2个参数的类型
    //                  String.class, 
    //                  new XC_MethodHook() {
    //                      // 在被Hook操作的类方法执行之前执行代码
    //                      @Override
    //                      protected void beforeHookedMethod(MethodHookParam param)
    //                              throws Throwable {
    //                          
    //                          // 打印被Hook操作的目标类方法的第1个参数值
    //                          XposedBridge.log("beforeHookedMethod 第1个参数:" + param.args[0]); 
    //                          // 打印被Hook操作的目标类方法的第2个参数值
    //                          XposedBridge.log("beforeHookedMethod  第2个参数:" + param.args[1]);
    //                          
    //                          // 打印被Hook操作的目标类方法的函数返回值ֵ
    //                          XposedBridge.log("beforeHookedMethod result:" + param.getResult());
    //                      }
    //                      
    //                      // 在被Hook操作的类方法执行之后执行代码
    //                      @Override
    //                      protected void afterHookedMethod(MethodHookParam param)
    //                              throws Throwable {
    //                          
    //                          // 打印被Hook操作的目标类方法的第1个参数值
    //                          XposedBridge.log("afterHookedMethod userName:" + param.args[0]); 
    //                          // 打印被Hook操作的目标类方法的第2个参数值 
    //                          XposedBridge.log("afterHookedMethod sn:" + param.args[1]);
    //                          
    //                          // 修改被Hook操作的目标类方法的函数返回值
    //                          param.setResult(true);
    //                          
    //                          // 打印被Hook操作的目标类方法的函数返回值ֵ
    //                          XposedBridge.log("afterHookedMethod 函数返回值:" + param.getResult());
    //                      }
    //                  });
    
    
                // 不在Android应用默认的classes.dex文件中的类方法的Hook操作,例如:
                // 1.MultiDex情况下的,多dex文件中的类方法的Hook操作,例如:classes1.dex中的类方法
                // 2.主dex加载的jar(包含dex)情况下的,类方法的的Hook操作
    
                // Hook类方法ClassLoader#loadClass(String)
                findAndHookMethod(ClassLoader.class, "loadClass", String.class, new XC_MethodHook() {
    
                    // 在类方法loadClass执行之后执行的代码
                    @Override
                    protected void afterHookedMethod(MethodHookParam param) throws Throwable {
    
                        // 参数的检查
                        if (param.hasThrowable()) {
                            return;
                        }
    
                        // 获取指定名称的类加载之后的Class<?>
                        Class<?> clazz = (Class<?>) param.getResult();
                        // 获取加载的指定类的名称
                        String strClazz = clazz.getName();
                        XposedBridge.log("LoadClass : "+strClazz);
    
    //                  // 被Hook操作的目标类名称
    //                  String strClazzName = "";
    //                  // 被Hook操作的类方法的名称
    //                  String strMethodName = "";
    
                        // 所有的类都是通过loadClass方法加载的
                        // 过滤掉Android系统的类以及一些常见的java类库
                        if (!strClazz.startsWith("android.") 
                            && !strClazz.startsWith(".system")
                            && !strClazz.startsWith("java.") 
                            && !strClazz.startsWith("org.") 
                            && !strClazz.contains("umeng.")
                            && !strClazz.contains("com.google")
                            && !strClazz.contains(".alipay")
                            && !strClazz.contains(".netease")
                            && !strClazz.contains(".alibaba")
                            && !strClazz.contains(".pgyersdk")
                            && !strClazz.contains(".daohen")
                            && !strClazz.contains(".bugly")
                            && !strClazz.contains("mini")
                            && !strClazz.contains("xposed")) {
                            // 或者只Hook加密算法类、网络数据传输类、按钮事件类等协议分析的重要类
    
                            // 同步处理一下
                            synchronized (this.getClass()) {
    
                                // 获取被Hook的目标类的名称
                                strClassName = strClazz;
                                //XposedBridge.log("HookedClass : "+strClazz);
                                // 获取到指定名称类声明的所有方法的信息
                                Method[] m = clazz.getDeclaredMethods();
                                // 打印获取到的所有的类方法的信息
                                for (int i = 0; i < m.length; i++) {
    
                                    //XposedBridge.log("HOOKED CLASS-METHOD: "+strClazz+"-"+m[i].toString());
                                    if (!Modifier.isAbstract(m[i].getModifiers())           // 过滤掉指定名称类中声明的抽象方法
                                         && !Modifier.isNative(m[i].getModifiers())     // 过滤掉指定名称类中声明的Native方法
                                         && !Modifier.isInterface(m[i].getModifiers())  // 过滤掉指定名称类中声明的接口方法
                                         ) {
    
                                        // 对指定名称类中声明的非抽象方法进行java Hook处理
                                        XposedBridge.hookMethod(m[i], new XC_MethodHook() {
    
                                            // 被java Hook的类方法执行完毕之后,打印log日志
                                            @Override
                                            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
    
                                                // 打印被java Hook的类方法的名称和参数类型等信息
                                                XposedBridge.log("HOOKED METHOD: "+strClassName+"-"+param.method.toString());
                                            }
                                        });
                                    }
                                }
                            }
    
    
    //                  // 所有的类都是通过loadClass方法加载的
    //                  // 所以这里通过判断全限定类名,查找到被Hook操作的目标类
    //                  if (strClazz.contains(strClazzName)) {
    //
    //                      // Hook目标类方法
    //                      findAndHookMethod(clazz, 
    //                              // 被Hook操作的类方法的名称
    //                              strMethodName, 
    //                              // 被Hook操作的类方法的参数类型
    //                              //paramTypes, // 根据实际情况进行修改
    //                              new XC_MethodHook() {
    //                          @Override
    //                          protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
    //                              
    //                              // ......
    //                              
    //                              // 打印被Hook操作的目标类方法的第1个参数值
    //                              XposedBridge.log("beforeHookedMethod 第1个参数:" + param.args[0]); 
    //                              // 打印被Hook操作的目标类方法的第2个参数值
    //                              XposedBridge.log("beforeHookedMethod  第2个参数:" + param.args[1]);
    //                              
    //                              // ......
    //                          }
    //   
    //                          @Override
    //                          protected void afterHookedMethod(MethodHookParam param) throws Throwable {
    //                              
    //                              // ......
    //                              
    //                              // 打印被Hook操作的目标类方法的函数返回值ֵ
    //                              XposedBridge.log("afterHookedMethod 函数返回值:" + param.getResult());
    //                              
    //                              // ......
    //                          }
    //                      });
    //                  }
                        // ......
    
                        }
                    }
                });
            }
    
        }
    
        // 获取指定名称的类声明的类成员变量、类方法、内部类的信息
        public void dumpClass(Class<?> actions) {
    
            XposedBridge.log("Dump class " + actions.getName());
            XposedBridge.log("Methods");
    
            // 获取到指定名称类声明的所有方法的信息
            Method[] m = actions.getDeclaredMethods();
            // 打印获取到的所有的类方法的信息
            for (int i = 0; i < m.length; i++) {
    
                XposedBridge.log(m[i].toString());
            }
    
            XposedBridge.log("Fields");
            // 获取到指定名称类声明的所有变量的信息
            Field[] f = actions.getDeclaredFields();
            // 打印获取到的所有变量的信息
            for (int j = 0; j < f.length; j++) {
    
                XposedBridge.log(f[j].toString());
            }
    
            XposedBridge.log("Classes");
            // 获取到指定名称类中声明的所有内部类的信息
            Class<?>[] c = actions.getDeclaredClasses();
            // 打印获取到的所有内部类的信息
            for (int k = 0; k < c.length; k++) {
    
                XposedBridge.log(c[k].toString());
            }
        }
    }
    
    /**
     * Look up a method and place a hook on it. The last argument must be the callback for the hook.
     * @see #findMethodExact(Class, String, Object...)
     */
    /* 目标java方法的Hook
    public static XC_MethodHook.Unhook findAndHookMethod(Class<?> clazz, String methodName, Object... parameterTypesAndCallback) {
        if (parameterTypesAndCallback.length == 0 || !(parameterTypesAndCallback[parameterTypesAndCallback.length-1] instanceof XC_MethodHook))
            throw new IllegalArgumentException("no callback defined");
    
        XC_MethodHook callback = (XC_MethodHook) parameterTypesAndCallback[parameterTypesAndCallback.length-1];
        Method m = findMethodExact(clazz, methodName, getParameterClasses(clazz.getClassLoader(), parameterTypesAndCallback));
    
        return XposedBridge.hookMethod(m, callback);
    }*/
    
    /** @see #findAndHookMethod(Class, String, Object...) */
    /* 目标java方法的Hook
     public static XC_MethodHook.Unhook findAndHookMethod(String className, ClassLoader classLoader, String methodName, Object... parameterTypesAndCallback) {
        return findAndHookMethod(findClass(className, classLoader), methodName, parameterTypesAndCallback);
    }*/
    
    
    /**
    * Loads the class with the specified name. Invoking this method is
    * equivalent to calling {@code loadClass(className, false)}.
    * <p>
    * <strong>Note:</strong> In the Android reference implementation, the
    * second parameter of {@link #loadClass(String, boolean)} is ignored
    * anyway.
    * </p>
    *
    * @return the {@code Class} object.
    * @param className
    *            the name of the class to look for.
    * @throws ClassNotFoundException
    *             if the class can not be found.
    */
    //public Class<?> loadClass(String className) throws ClassNotFoundException {
    //        return loadClass(className, false);
    //    }
    
    Xposed Hook处理Android应用打印Log日志的结果截图:

    这里写图片描述

  • 相关阅读:
    C# FileStream 文件复制
    DataSnap Server 客户端调用 异常
    抛出异常 exception
    RAD Tokyo 10.2.2
    delphi ios info.plist
    sql 日期格式
    sql server 2014登录账号
    sql server导入excel数据
    dev16 cxgrid 在DLL里报0地址错
    sql server 查看所有表记录数
  • 原文地址:https://www.cnblogs.com/csnd/p/11800592.html
Copyright © 2011-2022 走看看