某夕夕anti_content算法分析

- 代码中大量报错 , 按照顺序处理
403错误 , 未授权
- 调整至fiddler工具中
- 采集真实小程序中产生的token信息 , 并中转拦截处理

- 拦截授权请求后 , 业务接口可以正常访问

- 余下报错为初始化过程中 , wss初始化链接数过多 , 堆栈定位一下

- 寻找
r.MaxWebsocketConnect参数初始化时引用的对象 , 并修改 - 在
app.js中修改调试器的全局参数__devtoolsConfig.setting.MaxWebsocketConnect = 5

- 此时已成功没有错误 , 429状态码为风控引起的返回状态码 , 忽略即可
anti_content算法
- 随便定位一条带有anti_content的请求
https://xcxapp.pinduoduo.com/backend/conf/startup_v2

- 放眼望去 , 只有这么几条参数值得关注
- 两条token大概率由授权请求返回的 , 不是我们关注的重心
- xcx_hash看上去大概率为签名 , 最后一步看即可 , 接下来分析anti_content
- 查看堆栈

- 直接忽略asdebug与waservice的堆栈 , 这是工具自身的引用栈 , 与业务代码无关 , 直接从
41.js分析即可

- 确认引用了anti_content后 , 往上追溯至没有异步的地方或生成的地方

- 业务代码并没有严重的混淆 , 所以很轻松定位到了生成的位置 , 不过参数传入为boolean , 难道不应该为对象吗
- 进入此函数 , 并打印传入参数

- 调试信息都不是想像中的亚子 , 那是不是找错链接了呢 , 尝试寻找其他较长的anti_content
- 尝试调试了其他链接的anti_content后 ,长度不一致 , 问题不在外部函数 , 那么就需要深入anticontent函数了
function g(t) {
for (var e = t || {}, n = e.systemInfoAsync, a = e.fingerprintAsync, r = n || function() {
try {
return wx && wx.getSystemInfoSync ? wx.getSystemInfoSync() : {};
} catch (t) {
return {};
}
}(), i = a || function() {
try {
if (!wx || !wx.getStorageSync) return "";
var t = wx.getStorageSync("e488cb9fe650282");
if (!t || !t.data) return "";
var e = JSON.parse(t.data);
return e && e.a || "";
} catch (t) {
return "";
}
}() || l, h = r.model, u = r.pixelRatio, f = r.version, c = r.system, d = r.platform, _ = r.fontSizeSetting, p = r.SDKVersion, g = [].concat(v.packN(), A.packN(h), b.packN(), y.packN(), O.packN(), w.packN(), k.packN(), S.packN(), m.packN(), x.packN(), C.packN(u), z.packN(f), H.packN(c), E.packN(d), T.packN(_), D.packN(p), N.packN(i)), I = g.length.toString(2).split(""), M = 0; I.length < 16; M += 1) I.unshift("0");
I = I.join("");
var B = [];
0 === g.length ? B.push(0, 0) : g.length > 0 && g.length <= 255 ? B.push(0, g.length) : g.length > 255 && B.push(parseInt(I.substring(0, 8), 2), parseInt(I.substring(8, 16), 2)),
g = [].concat([ 3 ], [ 3, 0, 0 ], B, g);
var R = o.default.deflate(g), j = [].map.call(R, function(t) {
return String.fromCharCode(t);
});
return "3ak" + s.default.encode(j.join(""), s.default.budget);
}
- 稍微深入后 , 即可发现anti_content的生成位置

- 最后一句encode的函数 , 粗略看上去像是类似base64的编码算法 , 直接调用即可
- 看看encode前调用了哪些参数
[
{"data": 0},
{"data": "iPhone 5"},
{"data": ["pages/index/index"]},
{"data": 13},
{"data": [83, 251, 218, 43]},
{"data": "1451015129656341-1661093800919"},
{"data": "1001"},
{"data": ""},
{"data": 1661093800858},
{"data": 325444},
{"data": 2},
{"data": "8.0.5"},
{"data": "iOS 10.0.1"},
{"data": "devtools"},
{"data": 16},
{"data": "2.24.7"},
{"data": "uybW3WN48WL3SblRjUYCZeT4q0lDWdkx"}
]
- 到此为止 , 调用了哪些环境信息就可以知道了
- 关于wss中请求的内容 , 有时间再讲一期 , 难度都不高
侵权说明
此分析仅供学习参考 , 并不提供源码以及代码指导 , 如有侵权 , 联系邮箱admin@tisoz.com删除