前言
在shield参数逆向日记里我们已经解决了请求的核心参数shield的逆向,此时携带shield已经可以拿到数据,但是那几个风控参数没有逆的情况下,是不能大量请求的,所以称有空,继续逆向核心风控参数x-mini-mua。
我承认在定位这个参数的时候花了我一点时间,一时没转过弯,现在我将这个曲折史写下来,
x-mnini-mua参数定位
在找shield参数时,是在hook请求拦截器的,如下图:

在com.xingin.shield.http.XhsHttpInterceptor拦截器里,x-mini-mua参数已经生成了,继续hook mt5.u 拦截器:
let TinyInterceptor = Java.use("mt5.u");
TinyInterceptor["intercept"].implementation = function (chain) {
console.log(`TinyInterceptor.intercept is called: chain=${chain}`);
console.log(chain.request().headers().toString())
let result = this["intercept"](chain);
console.log(`TinyInterceptor.intercept result=${result}`);
return result;
};
此时打印的入参这里是没有生成x-mini-mua参数的,此时打印的请求头参数还较少:

那就在这个这里打印一下堆栈继续跟踪x-mini-mua生成的位置:

打印的堆栈信息如下:

那我们继续hook下一个栈okhttp3.internal.http.RealInterceptorChain.proceed,看这里的入参及返回值:

hook完后我们看到其实在入参里x-mini-mua就已经生成了,我们有理由肯定x-mini-mua参数就是在上一个栈mt5.u.intercept(Native Method)生成的,同时这里还有个标记Native Method,经验丰富的能看出来这里大概率是调用了so层的代码,我们重点看mt5.u.intercept方法,在jadx里搜:

这里我们前面已经hook了,入参那里是没有x-mini-mua参数的,那这个参数一定是在这个里面的逻辑里生成的,那我们重点看这个方法的里面就行,我一开始这里没想明白,后面是猜想这个x-mini-mua参数是在so层加密的,但是一定会在java层加入,加入时基本是只需要hook Request.Builder.header 方法,当发现key是x-mini-mua时打印堆栈:
var RequestBuilder = Java.use('okhttp3.Request$Builder');
RequestBuilder.header.overload('java.lang.String', 'java.lang.String').implementation = function(key, value) {
if (key === 'x-mini-mua') {
console.log('[+] x-mini-mua 值:' + value);
console.log('[+] 调用栈:\n' + Java.use('android.util.Log').getStackTraceString(Java.use('java.lang.Exception').$new()));
}
return this.header(key, value);
};

我发现还是在这里,这才反应过来第一行at okhttp3.Request$Builder.header(Native Method)提示是Native Method以及okhttp3.Request$Builder.header的提醒,这个时候疯狂在mt5.u.intercept(TinyInterceptor.kt:16)里找request.newBuilder().header("x-mini-mua", ...) 类似代码。

发现还真有,这里在添加key和value了,hook打印一下:
let e = Java.use("wn5.e");
e["l"].implementation = function (str, str2, bArr) {
console.log(`e.l is called: str=${str}, str2=${str2}, bArr=${bArr}`);
let resultMap = this["l"](str, str2, bArr);
console.log(`e.l result=${resultMap}`);
// 获取 Map 的键集合
var keySet = resultMap.keySet();
var iterator = keySet.iterator();
while (iterator.hasNext()) {
var key = iterator.next();
var value = resultMap.get(key);
console.log("key-->" + key + ":" + "value-->" + value);
}
return resultMap;
};

这个几个风控参数都在此,终于找到位置了!!!现在我们确定的是在经过wn5.e.l时关键参数x-mini-mua才生成好,继续跟踪点进去:

在return的地方继续跟踪(此处2个分支都需要跟,我只跟下面对的分支):

继续跟:

发现这里的native方法了,到这里心里基本确定了就是这个native方法!终于跟到了,最后hook一下这个native方法:
let t = Java.use("com.xingin.tiny.internal.t");
t["a"].overload('int', '[Ljava.lang.Object;').implementation = function (i17, objArr) {
console.log(`t.a is called: i17=${i17}, objArr=${objArr}`);
let result = this["a"](i17, objArr);
console.log(`t.a result=${result}`);
return result;
};

此时才彻底放松一口气,不容易,前面走了弯路啊!接下来就是找加载这个方法的动态so文件了(在这个java类里没找到直接的so文件),hook一下:

确定是libtiny.so文件,此时就直接上unidbg了,纯算还不是我这个阶段去分析的了,哈哈哈,纯算起码是后期技术很成熟了再去考虑的东西了,找到入口方法及so文件了,那么接下来就是开始unidbg环节了,这个环节我后续空了再一点一点开始了!
今天先到此了,感谢大家的陪伴~~~

1016

被折叠的 条评论
为什么被折叠?



