【作者主页】:小鱼神1024
【擅长领域】:JS逆向、小程序逆向、AST还原、验证码突防、Python开发、浏览器插件开发、React前端开发、NestJS后端开发等等
本文章中所有内容仅供学习交流使用,不用于其他任何目的,不提供完整代码,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关!若有侵权,请联系作者立即删除!
前言
距离上次分析 x-s 也有一年了,该篇文章阅读量也有 11万 多,感谢小伙伴的一路支持。

最近,它又从 wasm 方式加密更改为 js 加密了,即: mnsv2 从原来的 mns0101 升级为 mns0301。其实目前网络上也有该算法相关的分析,但是整体看下来不够全,不够细。
所以,出于学习目的,我决定手把手分析记录一下,希望对小小伙伴有所帮助。
前置准备
懒人AST解混淆框架:https://blog.csdn.net/studypy1024/article/details/154188036
它不仅能解混淆,还能自动插桩,保存日志文件,方便我们分析。

分析过程
全局搜索 XYS_,打上断点,然后刷新页面,断点触发,如图所示:

发现 x-s 是通过:
javascript
{
"x0": "4.2.6",
"x1": "xhs-pc-web",
"x2": "Windows",
"x3": "mns0301_fZaKqslIYHwR62e9nR/vWclLGdIMR85Vm/jxYj8I2j5l7I4dQ/Hj+Dq9k+DQypUTtJ2+mmhzg0njIDU/4GFsPoY6vSF69C0JdzZvA3R92OUEVAuKAqjA0JHKXS0YLGS70+MCnpsRzRJPUaT3lHnKSndVZlciE0JRIk0OHF==",
"x4": "object"
}
经过 JSON.stringify(f) 转成字符串后,通过 (0,p.lz) 等加密的得到的。如图所示:

这里直接手动扣下代码就行。没啥难度,就不在这里啰嗦了。
大部分小伙伴应该是在 x3 的值上卡住了,其实它就是 window.mnsv2(c, d) 得到的。
所以,我们这次着重分析 window.mnsv2。首先在控制台输入 window.mnsv2,然后双击进入它的代码,如图所示:

复制全部混淆代码,然后粘贴到 懒人AST解混淆框架 的 source.js 中,在 fix.js 引入以下 AST通用插件:
javascript
traverse(ast, LiteralRestore);
traverse(ast, FunctionAliasReplace);
traverse(ast, FunctionCalcFn({
globalProgramBodyIndex: [0, 1, 2]
}));
traverse(ast, ObjectPropertiesRestore);
traverse(ast, forIfBlockRestore);
traverse(ast, CleanUnreferVarsFuns);
traverse(ast, AddXHSLogger);
traverse(ast, AddXysLogSaver);


如图,以上插件,我都有详细的使用场景和说明,直接引入就行。我就不一一截图了。
运行代码后,它会自动解混淆,自动插桩。并保存在在 out.js 中,如图:

替换代码后,在 window.mnsv2(c, d) 上打上断点,然后刷新页面,断点触发。
然后,开启日志打印:
javascript
xysLogSaver.switch = true; // 打开日志开关
然后放开断点,此时会发现,会输出1182条左右日志,如图所示:


可以清楚的看到,fZaKqMlTfvolxQnGnR/vWt8hedNMR85Vm/jxYj8I2j5l7I4dJiJw1eFEUbPQypUTtJ2+mmhzg0njIDU/4GFsPoY6vSF69C0JdzZvA3R92OUEVAuKAqjA0JHKXS0YLGS70+MCnpsRzRJPUaT3l2nKSndVZlciE0JRIk0OHF== 是通过上述函数得到的。
传参有两个:
-
124长度的数组 -
MfgqrsbcyzPQRStuvC7mn501HIJBo2DE 经分析,这个是定值
那现在只需分析 124 长度数组是怎么来的?

这里,124 长度数组通过一个函数,得到相同长度的数组,那这个函数是如何实现呢?

这里我列出了三组,说明它是一个循环,通过异或操作,得到相同长度的数组,我暂且叫它 数组置换函数。
小伙伴可以先动手试试看,不算难,这里就不一一截图了。
那原始的 124 长度数组是怎么来的呢?
总共可以分为 11 部分:
数组置换函数和获取原始 124 长度数组函数,我会贴到星球文章末尾,供大家参考。
1、头部标识固定值

这个可以固定,直接写死 [119, 104, 96, 41]。
2、随机数Math.random字节


这个是通过 Math.floor(Math.random() * 4294967295) 然后取字节数组。具体实现:
javascript
const v1 = Math.floor(0.5507453723052297 * 4294967295);
const v2 = v1 & 255;
const v3 = (v1 >>> 8) & 255;
const v4 = (v1 >>> 16) & 255;
const v5 = (v1 >>> 24) & 255;
其中 v2、v3、v4、v5 就是。
剩余九种情况数组生成,仅限星球内可见!
以上 11 种环境加密就是 124 原始数组组成了。
拥有 懒人AST解混淆框架,真的可以节省很多时间,大家一定要学会使用。
总结
window.mnsv2具体实现等js手稿,我会贴到星球文章末尾,供大家学习参考,严禁用于其他用途!