https://www.52pojie.cn/thread-1964578-1-1.html
https://www.52pojie.cn/thread-1845720-1-1.html
主要还是跟第二个帖子结果比较像
我刚接触js两周左右, 有其他语言的基础, 能看懂部分代码, 看不懂的代码都去问ai, 也能看懂整体
使用了 https://github.com/JaveleyQAQ/WeChatOpenDevTools-Python 这个让小程序有F12控制台
跟着 https://www.52pojie.cn/thread-1845720-1-1.html 这个帖子分析
小程序F12动态调试看结果, 看自己拿到的代码和小程序执行的结果是否一样
我使用的微信版本号是 3.9.12.15 64位, 小程序版本 11275
我先把我的一些分析过程说一下, 如果没有答案, 这个也可以参考一下, 我的问题在最后面
a1是固定, a2是时间戳 + (服务器时间戳 - 时间戳), a3是服务器返回的一个dfpid
这段代码是从小程序里扣出来的函数, 获取dfpid和服务器时间戳用的, 不同环境下扣的代码变量名可能不同, 比如我的变量名字和上面第二个帖的名字就不一样
[JavaScript] 纯文本查看 复制代码 g: function(e) {
var a = Date.now();
_r_json = "";// 不太了解js, 自己定义一个变量做返回值
za(
(
function(c) {
var n = Ea;
try {
var t = JSON.parse(JSON.stringify(c));
// 这里是删掉一些不用的成员
if (delete t.fsmode,
delete t.e,
delete t.ext,
delete t.system.gyro,
delete t.dp,
delete t.sessionId,
delete t.system.screenRecord,
delete t.system.wifiList,
void 0 !== t.system.StorageInfo) {
var f = JSON.parse(t.system.StorageInfo);
f.keys = [],
t.system.StorageInfo = JSON.stringify(f)
}
t.reportTick = 0;
var r = JSON.stringify(t);
n += F(Be.codec.utf8String.toBits(r)),
//走到这里的时候 n 就是加密的data数据, 补充其他成员后post请求 https://appsec-mobile.meituan.com/v1/wxdfpid, 得到服务器时间戳和dfpid, 这个dfpid就是a3, 时间戳自己计算一下就得到a2
e && e(n),
Oa && Oa.addApi("dfp_finger", 200, 200, Date.now() - a, .01),
Oa && Oa.addApi("dfp_finger_length", 200, 200, n.length, .01);
_r_json = n;
} catch (c) {
e && e(n);
try {
Oa && Oa.addError("getFinger", c),
Oa && Oa.addApi("dfp_finger", 200, 9401, Date.now() - a, .01)
} catch (e) {}
}
}
)
)
到这里a1,a2,a3都得到了
a6是一段环境加密结果, 我这里是"w1.3", 上面帖子里是"w1.2", 我的直接在js里搜 "1.3" 就能定位到计算a6的函数
下面这一段是计算a6的函数, 有部分代码是我自己加上去的
[JavaScript] 纯文本查看 复制代码i: function() {
var a = "w1.3";
//这里的La.system是我直接从小程序里扣出来的值, 写死在源码里, 小程序那是没有这一段赋值的, 都是其他地方一个一个成员赋值的
La.system = {
"errMsg": "getSystemInfo:ok", // 错误信息
"albumAuthorized": true, // 相册授权
"benchmarkLevel": 1, // 设备性能等级, 仅安卓, -2/ 0:无法运行小游戏, -1:性能未知, >=1: 性能值, 目前最高不到50
"bluetoothEnabled": false, // 蓝牙启用
"brand": "microsoft", // 品牌
"cameraAuthorized": true, // 相机授权
"fontSizeSetting": 15, // 字体大小设置
"language": "zh_CN", // 语言
"locationAuthorized": true, // 地点授权
"locationEnabled": true, // 位置已启用
"microphoneAuthorized": true, // 麦克风授权
"model": "microsoft", // 模型
"notificationAuthorized": true, // 通知授权
"notificationSoundEnabled": true, // 声音启用
"pixelRatio": 1, // 像素比率
"platform": "windows", // 平台
"power": 100, // 电源? 电量?
"safeArea": { // 在竖屏正方向下的安全区域
"bottom": 736,
"height": 736,
"left": 0,
"right": 414,
"top": 0,
"width": 414
},
"screenHeight": 736, // 屏幕高度
"screenWidth": 414, // 屏幕宽度
"statusBarHeight": 0, // 状态栏高度
"system": "Windows 10 x64", // 系统
"theme": "light", // 主题, 亮色
"version": "3.9.12", // 版本
"wifiEnabled": true, // wifi启用
"windowHeight": 736, // 窗口高度
"windowWidth": 414, // 窗口宽度
"SDKVersion": "3.3.5", // SDK版本
"enableDebug": false, // 启用调试
"devicePixelRatio": 1, // 分辨比
"host": {
"appId": "",
"env": "WeChat"
},
"networkType": "wifi", // 网络类型
"brightness": 0.5, // 亮度
// LaunchOptionsSync: 启动选项同步
"LaunchOptionsSync": "{\"path\":\"pages/home/home\",\"query\":{},\"scene\":1256,\"referrerInfo\":{},\"apiCategory\":\"default\"}"
};
if (Y(),
Ia || G(_a),
!Da)
try {
//我把这一段代码都屏蔽了, 这里其实就是计算得到ja这个数组, 我不执行, 直接在后面固定这个ja数组
// Date.now(),
// function() {
// try {
// ja[0] = "undefined" == typeof NativeClient ? 0 : 1,
// ja[1] = "undefined" == typeof addEventListener ? 0 : 1;
// try {
// var e = {
// "appDebug": false,
// "appMD5": "",
// "appVersion": "",
// "libDebug": false,
// "libVersion": "3.3.5",
// "system": "windows",
// "systemVersion": "Win 10"
// }
// , a = 0
到这里, a1,a2,a3,a6 都得到了
然后计算a5
我这里拿到的js代码是 function oe(c, t) {} 这个函数计算mtgsig, 除了a1,a2,a3,a6, 其他的成员都是这里计算出来的
下面这段代码是获取剩下其他成员的函数
[JavaScript] 纯文本查看 复制代码function oe(c, t) {
void 0 === t && (t = !0);
try {
var f = Date['now']()
, r = 0;
switch ('undefined' != ("undefined" == typeof mmp_env ? "undefined" : _typeof(mmp_env)) ? 'web' === mmp_env && (r = 1)
: 'undefined' != ("undefined" == typeof mmp ? "undefined"
: _typeof(mmp)) && (r = 2),
r) {
case 2:
c['mtSecuritySign'] = !0,
c['mtSecuritySiua'] = !0;
break;
default:
c = function(c, t) {
if (void 0 === t && (t = !1), rc += 1, Qa['b8'] = rc, c) {
// 拿到header, 请求方法, 时间戳(当前时间戳 + _a['id']['serverTimeDiff'])
// _a['id']['serverTimeDiff'] 需要得到这个值, 小程序里这个是调用 wx.getStorageSync("guardSample") 获取
var r = c['header'] || {}
, d = (c['method'] || 'GET')['toUpperCase']()
, o = 'GET' !== d && de(r, oc)
, i = ('GET' !== d && de(r, ic), (new Date)['valueOf']() + Fa());
r = c['url'] || "";
var b = c['data']; // post请求的请求参数, 搜索的参数也当成post参数传递
// 判断c['header'] 是不是对象, 不是就赋值空对象
c['header'] && 'object' == _typeof(c['header']) || (c['header'] = {});
// 解析url, 域名, 资源路径, url上的参数等
var u = "/", s = [];
(r = /^(?:([A-Za-z]+):)?(\/{0,3})([0-9.\-A-Za-z]+)(?::(\d+))?(?:\/([^?#]*))?(?:\?([^#]*))?(?:#(.*))?$/['exec'](r))
&& ( r[5] && (u += r[5]), r[6] && (s = $(r[6])) );
var h = [], l = "", p = [];
if ('GET' === d)
{
if ('object' == _typeof(b) && 0 >> 0;
///////////////////////////////////////////////////////////
// 走到这里就已经把 a1,a2,a3,a4,a5,a6,a7,x0,都获取完了, 现在就差一个d1
///////////////////////////////////////////////////////////
// 把a1, a2, a3, a4 a7, 和o, v进行运算, 得到d1
// ee = 把输入字符串进行 URL 编码,返回编码后的字节数组
var D = f['a1'] + f['a2'] + f['a3'] + f['a4'] + o + v + f['a7']
, N = me['md5Array'](new Uint8Array(ee(D)))
, j = d
我的问题:
我使用了 https://github.com/JaveleyQAQ/WeChatOpenDevTools-Python 注入到小程序里让小程序能打开F12后小程序访问部分接口就403了
怀疑是小程序检测到调试状态, 然后加密流程有可能变动
或者a6这个环境的结果不对
有没有什么方式能让小程序能加密成功呢? 就是让小程序能访问到数据
打开某点评小程序, 点击搜索框, 输入搜索内容, 点击搜索 这个搜索的请求就会返回403
如果没有注入F12控制台, 那这个搜索就可以返回正确的数据
求助, 到底是我上面的流程哪里有问题, 或者哪个环境没弄对
或者真的是我想的那样, 小程序检测到调试就走不同的分支, 导致结果不对....
最终的问题就是能打开F12控制台, 并且能搜索