某麦购票Xposed脚本(一)
本文仅研究了某麦app的购票接口,不涉及破盾方法。
本文仅供研究学习使用,请勿用于任何商业和非法用途。否则后果自负。
在之前的文章中我们详细分析了大麦的购票协议接口,并使用了 Python + Frida RPC 的方式成功实现了购票。本文我们尝试将其改为用 Xposed 来实现。
环境
设备:pixel 5(Android11已root)
app平台:Android
app版本:8.10.9
工具:
抓包:Postern + Charles
动态静态分析:jadx、frida
LSPosed版本:1.9.2
Magisk版本:26.1
流程拆解
先来分解一下我们之前获取订单详情的 frida hook 流程:
构建
MtopContext对象作为参数主动调用buildParams获取加密参数
构建
MtopContext对象 构造 MtopRequest 对象
构造 MtopBusiness 对象
构造 MtopContext 对象
主动调用
buildParams主动调用
CookieManager.d获取Cookie向服务器发送请求并获取返回值,从中提取
signKey用于订单构建
androidStudio 环境配置
创建一个空项目
改一下项目名称,这里我们使用java写
拷贝 XposedBridgeApi.jar 到新建工程的libs目录
- 没有 libs 目录的话就在这里新建一个
修改app目录下的 build.gradle 文件,在AndroidManifest.xml 中增加Xposed相关内容
新建 assets 文件夹,然后在 assets 目录下新建文件 xposed_init,在里面写上 hook 类的完整路径

开始分析
获取 realClassLoader 原理
Xposed hook的时机非常早,因为首先拿到的是壳的 classLoader ,而非脱壳后真正的 realClassLoader。所以在有壳的情况下直接hook目标函数是无法找到目标函数的。
那么我们得先拿到脱壳后的 realClassLoader。
加壳app的启动流程
启动时只加载壳自己的
StubApplication(不是业务代码)壳在
attachBaseContext()或onCreate()里:加载加密的 dex
解密原始 dex
使用
DexClassLoader/PathClassLoader加载业务代码有时还会用反射把真实的
Application替换进去
最后才进入真实代码逻辑
所以,我们要hook attachBaseContext() 或者 onCreate()
| 方法名 | 原因 |
|---|---|
attachBaseContext(Context) |
加壳 App 最早可执行逻辑,通常在此加载原始 dex |
onCreate() |
有些壳把 dex 加载延后到这一步 |
| 两者之后 | ClassLoader 已经被替换或补充,可以安全用来加载真实类 ✅ |
确定 hook 入口
查看壳的入口,找到attachBaseContext(Context)或者onCreate()方法的地址
- 查看 AndroidManifest.xml 从
application中可以找到壳的入口com.ali.mobisecenhance.ld.StubApplication
- 进来之后可以看到这个类本身没有
attachBaseContext(Context)或者onCreate(),那么跟进它继承的父类看看
- 进来之后可以看到这两个方法
- 一般来说我们优先选择
attachBaseContext(),onCreate()可作为补充
获取 realClassLoader
- 这里我们通过 hook
attachBaseContext()成功的拿到了脱壳后的realClassLoader - 拿到了
realClassLoader之后就可以编写代码继续之后的流程了
代码编写
按照之前的拆解流程,构建出 MtopContext 对象之后就可以调用 buildParams()方法获取到加密参数了
构建MtopContext对象
构造 MtopRequest 对象
构造成功说明我们成功的加载了类对象,访问类对象的方法也没有问题。
访问的时候需要注意一下是静态的还是非静态的,分别使用
callStaticMethod()、callMethod()
…
构造 MtopBusiness 对象
这里调用静态工厂方法
build()拿到实例
构造 MtopContext 对象并调用 buildParams()
- 执行没有报错,但是调用
buildParams()的返回值为空 - 经过尝试可能是因为
attachBaseContext()执行完成后业务代码还没有加载完毕,换为hookonCreate()可以正常执行返回加密数据
更换 hook 时机为 onCreate()
- 现在可以正常打印出加密参数
主动调用CookieManager.d获取Cookie
向服务器发送请求并获取返回值
接下来手动用 HttpURLConnection 发起 GET 请求,格式跟之前 python 中保持相同即可
- 需要注意,因为 Android 默认是不允许在主线程进行网络 I/O 的。解决办法是把网络请求放到子线程中执行。
提取返回值中的 signKey
- 提取到之后保存下来,用于构建订单使用
