如果只需要插件,不想看技术实现,可以关注公众号,发送“美团插件”
美团系的APP都可以用,因为虽然类名和方法名不一样,但是做了方法搜寻,所以通用
1. 先定位网络配置
先搜:
nt.defaulttunnel
其中 nt.defaulttunnel 很关键。它决定默认通道,比如 cip、http。
然后找到引用 一个方法读取这个字段,返回 2 或 3,返回3走的就是http,把这个hook掉返回3就可以了,走的就是http
return (!"cip".equals(this.xxx) && "http".equals(this.xxx)) ? 3 : 2;
模块里自动定位的流程就是:
搜 "nt.defaulttunnel"找到被赋值的成员字段找读取这个字段的 int 无参方法方法里包含 "cip"、"http"、返回 2/3hook 这个方法,直接返回3
2. 实现反混淆hook
用 dexlib2 静态扫 dex,不依赖类名、方法名、字段名、Robust。
依赖
implementation "org.smali:dexlib2:2.5.2"implementation "de.robv.android.xposed:api:82"compileOnly "de.robv.android.xposed:api:82"
基于dexlib2库,通过对DEX字节码进行模式匹配
1. 找字段(定位 nt.defaulttunnel 配置)
要找的字节码模式是:optString 读配置 -> move-result-object 拿结果 -> iput-object 存进成员变量。
// 1. 先看有没有 "nt.defaulttunnel" 和 "cip" 两个常量if (!hasKey || !hasCip) continue;// 2. 找到 invoke-virtual 调用 optString 的地方if (isInvokeOptString(insn)) {// 3. 看下一条是不是 move-result-object,拿返回值寄存器Integer moveResultReg = nextMoveResultObjectRegister(insns, i);if (moveResultReg == null) continue;// 4. 在后面几条指令里找 iput-object,且寄存器对上号FieldReference field = findNextIputObjectSameRegister(insns, i + 1, moveResultReg);if (field != null && "Ljava/lang/String;".equals(field.getType())) {return new FieldSig(field.getDefiningClass(), field.getName(), field.getType());}}
2. 找方法(定位返回 int 的选择器)
不硬匹配,方法特征。 在同一个类中,找那个无参且返回int、读取了那个“nt.defaulttunnel”字段(这个是关键,几乎百发百中)、同时引用了"cip"/"http"两个字符串和2/3两个数字常量,并调用了String.equals比较的方法。
3. 转反射(拿到可调用的 Method)
定位到签名后,把 Dex 格式的类型描述符(Lcom/xxx;)转成 Java 类名(com.xxx),然后直接反射拿方法。
// 把 "Lcom/example/MyClass;" 变成 "com.example.MyClass"String className = dexTypeToJava(sig.owner);Class<?> clazz = Class.forName(className, false, cl);// 参数类型同样转一遍Class<?>[] params = new Class<?>[sig.params.size()];for (int i = 0; i < sig.params.size(); i++) {params[i] = dexTypeToClass(sig.params.get(i), cl);}// 反射获取并爆破Method m = clazz.getDeclaredMethod(sig.name, params);m.setAccessible(true);return m;
3. 成果展示
轻松抓到团价格
夜雨聆风