欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

xposed项目基本流程解析

程序员文章站 2024-03-16 15:39:10
...

因为接触了XPosed以后,感觉在这条路上越走越远了。作为一个资深的标准C++程序员,其实我个人是不建议做这种事情,但奈何有很多的朋友也想了解这块的技术,就简单的用最近很火的一个应用的hook做个项目的分析吧,仅做技术分享,可能没有太营养的内容,只是提供思路。

一. 项目的需求

  • 二维码数据
  • 获得账单详情
  • 自动账号登录
  • 掉单数据核对

二.项目剖析

  • 针对二维码数据获取,这个是最简单的,基本只要找到口,就能获得数据。
  • 账单详情有两种方式获得。第一种,在支付成功后,抓取应用服务器主动推送的数据并解析即可。第二种相对繁琐。主动打开账单列表,获得账单列表数据,并指定打开某条订单,获取订单详情。
  • 登录方式有多种,人脸,指纹,账号密码。既然是自动登录,只能做账号密码了。登录界面的事情,肯定是hook登录界面来解决。
  • 由于网络的原因以及不可控的因素影响,人工核对太麻烦,肯定要做掉单的自动核对并补单。这块就需要用到之前说的账单列表获取订单详情的方式来处理。先获得账单列表中的所有订单号,再和后端进行核对,然后将漏掉的订单详情主动补全,这块也是最繁琐的一个步骤。

三.门槛

  • 反编译,比较好用的有AndroidKiller以及jadx。
  • 插件客户端和服务端的数据交互,个人建议使用websocket,毕竟数据太重要了,http不稳定。
  • 插件和hook应用的数据交互,直接通过Intent就够了。
  • 数据的获取,这个就是个细致的活了,不厌其烦的尝试,当然有一些技巧可以减少不必要的工作,这个大家可以多摸索一下。
  • Hook接口的获取,基本一个应用的剖析,90%的时间都是在做这个工作。并不是简单找到口就够,还需要配合整体的流程找到最佳的位置。使用完了以后,释放窗口也是应该的,否则,开了一堆的窗口,占用太多的系统资源,那就自己把自己搞死了。
  • 代码混淆以及混编。代码混淆的问题,只能通过尝试,当然,如果能反编译出源码,事半功倍。至于混编,最头疼,因为xposed无法hook到native接口,不过可以尝试其他接口,或多或少有可以用的。

四.延伸

  • 在做不同应用的hook过程中,会发现更多的问题。比如应用被加固后,常见的就有360加固、爱加密加固、腾讯加固、网易加固等等,直接用反编译工具无法获得我们想要的内容,这个时候,就需要用其他的工具来辅助**。就算**了APK包,在使用xposed进行应用hook的时候,你还会发现没有任何的类供你hook,懵逼了。庆幸的是,总有牛逼的大神给了我们解决的办法,站在巨人的肩膀上就是舒坦。
  • 想要真正将这个技术运用到实际项目中,还需要正儿八经的搭建自己的C/S框架,网络通讯、并发承载、体验优化。
  • 有空可以多尝试一下不同的应用,可以增加熟练度。多封装一些自己常用的获取程序信息的接口,有效的增加效率也是必要的。因为朋友关系,做了挺多类似的活,加固的、不加固的,多多少少能熟练很多。

文章结尾
提供一个我经常使用的,自己封装好的一个接口,算是给各位一些福利吧(大神就不要喷我了)

public void printClassStruction(String strClassName,final ClassLoader classLoader){
        final Class<?> clazz = XposedHelpers.findClass(strClassName, classLoader);
        String strClazz = clazz.getName();
        XposedBridge.log("#####LoadClass : " + strClazz);
        {
            Method[] m = clazz.getDeclaredMethods();
            XposedBridge.log("Methods:"+m.length);
            for (int i = 0; i < m.length; i++) {
                XposedBridge.log(m[i].toString());
            }

            Field[] f = clazz.getDeclaredFields();
            XposedBridge.log("Fields:"+f.length);
            for (int j = 0; j < f.length; j++) {
                XposedBridge.log(f[j].toString());
            }

            Class[] c = clazz.getDeclaredClasses();
            XposedBridge.log("Classes:"+c.length);
            for (int k = 0; k < c.length; k++) {
                XposedBridge.log(c[k].toString());
            }


        }

这个接口用于那些无法反编译出的类,如果想获得这个类的大致结构,包括他的函数接口、成员、关联类,可以使用这个方法。