• Xposed快速hook关键点


    0x01 导读

      工作中,常常需要针对各种app进行快速代码定位,找到代码修改和调试各种功能,就不得不面对xposed来进行一系列快速定位关键代码的问题了。那么问题来了,如何快速找到代码呢?

    这里值这针对代码在java层的进行分析,在so中的,目前作者是无能为力的。

    0x02 众所周知

      我们的一般做法就是通过界面定位到具体的Activity ,执行adb 命令 “adb shell dumpsys activity | findstr "mFocusedActivity"”

    就可以快速找到我们当前需要hook页面的Activity功能块,然后通过,XposedHelpers的

      findAndHookMethod方法来,监控方法。少量的工作没什么,但是如果代码量很多,很难看,就比较麻烦了。 所以这里介绍一种作者目前使用的,自仍未快速的方式。

    0x03 推荐使用

      1、安装apk后,可以得到app使用的dex文件。

      2、然后解包dex文件得到jar文件。

      3、通过xposed读取jar中的所有类,

      4、然后hook,然后读取所有方法hook.

      5、然后通过关键字,匹配参数,匹配返回值,快速得到操作日志。

      注意:如果是多个dex,一样是可以的,多个jar。解压然后覆盖保存到一个里面,然后打包成jar就可以,jar就使用zip打包工具就可以,修改后缀就ok.,

    dex文件一般都可以通过apk解压得到,然后用apktool工具得到jar文件,针对某些apk无法apktool解包的可以添加-r等操作,不处理资源文件就OK.

      懒加载plugin如何操作呢? 找到不类呢?有一种情况,某些dex是专门存放插件,插件是进入到某些页面才会进行加载的,通过懒hook,进入某某页面,然后再进行hook操作,或者hook文件操作即可。

    部分参考代码:

    public static void hook_byJar(final XC_LoadPackage.LoadPackageParam loadPackageParam, String jarFile) throws Exception {
            try {
                //通过将给定路径名字符串转换为抽象路径名来创建一个新File实例
                File f = new File(jarFile);
                URL url1 = f.toURI().toURL();
                URLClassLoader myClassLoader = new URLClassLoader(new URL[]{url1}, Thread.currentThread().getContextClassLoader());
    
                //通过jarFile和JarEntry得到所有的类
                JarFile jar = new JarFile(jarFile);
                //返回zip文件条目的枚举
                Enumeration<JarEntry> enumFiles = jar.entries();
                JarEntry entry;
    
                //测试此枚举是否包含更多的元素
                while (enumFiles.hasMoreElements()) {
                    entry = (JarEntry) enumFiles.nextElement();
                    if (entry.getName().indexOf("META-INF") < 0) {
                        String classFullName = entry.getName();
                        if (classFullName.indexOf(".class") < 0) {
                                    classFullName = classFullName.substring(0, classFullName.length() - 1);
                                } else {
                                    Map<String, Object> hashMap = new HashMap<String, Object>();
                                    
                                    // 这里通过包名对部分类进行过滤,方式由于类不存在引起的错误。
                                    hashMap.put("com/test/test/test/", new ArrayList<String>());
                                    boolean isOkClass = false;
                                    for (Map.Entry<String, Object> m : hashMap.entrySet()) {
                                        String name = m.getKey();
                                        ArrayList<String> list = (ArrayList<String>) m.getValue();
                                        if (classFullName.startsWith(name)) {
                                            isOkClass = true;
                                            for (String str : list) {
                                                if (classFullName.startsWith(str)) {
                                                    isOkClass = false;
                                                }
                                            }
    
                                            break;
                                        }
                                    }
    
                                    if (isOkClass) {
                                        //去掉后缀.class
                                        String className = classFullName.substring(0, classFullName.length() - 6).replace("/", ".");
                                        // log(classFullName);
                                        try {
                                            final Class<?> myclass = myClassLoader.loadClass(className);
                                            for (final Method method : myclass.getDeclaredMethods()) {
                                                if (!Modifier.isAbstract(method.getModifiers())) {
                                                    XposedBridge.hookMethod(method, new XC_MethodHook() {
                                                        @Override
                                                        protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                                                            String before_className = myclass.getName();
                                                            String methodName = param.method.getName();
    
                                                            super.beforeHookedMethod(param);
                                                        }
    
                                                        @Override
                                                        protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                                                            String before_className = myclass.getName();
                                                            String methodName = param.method.getName();
                                                            
                                                            super.afterHookedMethod(param);
                                                        }
                                                    });
                                                }
                                            }
                                        } catch (Exception e) {
                                            e.printStackTrace();
                                        }
                                    }
                        }
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    View Code 读取jarhook方法和类

    0x04 其他方式

      1、针对app使用的开源库进行了解然后方便hook注关键代码,因为开源代码都是开源的,不需要看app解包的混淆,羞涩的代码。

      2、针对app作者,写入Log的内容进行hook,因为发布的app一般都是把其中的一个true或者false进行注释掉了,方法调用日志本身没有注释掉,所以可以针对写入的日志的地方进行处理。

  • 相关阅读:
    69期-Java SE-029_XML解析
    69期-Java SE-028_网络编程-3
    Django(46)drf序列化类的使用(ModelSerializer)
    Django(45)drf序列化类的使用(Serializer)
    Django(44)drf序列化源码分析
    Django(43)restful接口规范
    Django(42)DRF安装与使用
    Django(41)详解异步任务框架Celery
    Django(40)解决celery报错 No module named 'click._bashcomplete'
    Django(39)使用redis配置缓存
  • 原文地址:https://www.cnblogs.com/Supperlitt/p/7825960.html
Copyright © 2020-2023  润新知