js逆向-模拟加密
实战七麦数据:
1.寻找加密入口
尝试搜索的方法:
那只能使用跟栈的方法,进入send发包位置:
打上断点,寻找加密入口,前面是发包分包,promise注意到是一个异步操作,看是否在此加密,不是跳出异步跟栈:
2.模拟调试
打印一下t:
打断点,发现被加密了,那么此处就是加密位置
3.模拟执行
原加密代码:
var n;
f || $ != s || (n = (0,
i[Zt])(m),
s = c[x][k][Rt] = -(0,
i[Zt])(l) || +new R[K] - r2 * n);
var e, r = +new R[K] - (s || H) - 1661224081041, a = [];
return void 0 === t[Ot] && (t[Ot] = {}),
R[W][o7](t[Ot])[M](function(n) {
if (n == v)
return !B;
t[Ot][_2](n) && a[b](t[Ot][n])
}),
a = a[jt]()[I5](N),
a = (0,
i[Jt])(a),
a = (a += p + t[qt][T](t[Tt], N)) + (p + r) + (p + 3),
e = (0,
i[Jt])((0,
i[Qt])(a, d)),
-B == t[qt][O](v) && (t[qt] += (-B != t[qt][O](Bn) ? Nn : Bn) + v + B5 + R[V5](e)),
t
发现是一个混淆代码,需要进行处理,删除不必要的代码,不执行的代码(参数| &运算false)添加未知参数、未知函数,修改合适格式。
删除不必要的代码,此处之前已经加密:
t的寻找,刚刚的t已经有了analysis参数,重新跳过进入,复制t的object:
不执行的代码:
混淆代码,反应一个结果用浏览器智能提示进行替换 R[K]=Date:
存在内部又一个调用函数:
存在内部又一个调用函数:
存在内部又一个调用函数:
最后js代码:
t = {
"url": "/rank/indexPlus/brand_id/0",
"method": "get",
"headers": {
"common": {
"Accept": "application/json, text/plain, */*"
},
"delete": {},
"get": {},
"head": {},
"post": {
"Content-Type": "application/x-www-form-urlencoded"
},
"put": {
"Content-Type": "application/x-www-form-urlencoded"
},
"patch": {
"Content-Type": "application/x-www-form-urlencoded"
}
},
"params": {
"brand": "all",
"device": "iphone",
"country": "cn",
"genre": "36"
},
"baseURL": "https://api.qimai.cn",
"transformRequest": [
null
],
"transformResponse": [
null
],
"timeout": 15000,
"withCredentials": true,
"xsrfCookieName": "XSRF-TOKEN",
"xsrfHeaderName": "X-XSRF-TOKEN",
"maxContentLength": -1,
"maxBodyLength": -1
}
s = 968;
H = 0;
p = "@#";
function i_qt(n, t) {
for (var e = (n = n.split("")).length, r = t.length, a = "charCodeAt", i = H; i < e; i++)
n[i] = o(n[i][a](H) ^ t[(i + 10) % r][a](H));
return n.join("")
}
function o(n) {
t = "",
['66', '72', '6f', '6d', '43', '68', '61', '72', '43', '6f', '64', '65'].forEach(function (n) {
t += unescape("%u00" + n)
});
var t, e = t;
return String[e](n)
}
function i_jt(t) {
t = encodeURIComponent(t).replace(/%([0-9A-F]{2})/g, function (n, t) {
return o("0x" + t)
});
return btoa(t)
}
function get_analysis(t) {
var n;
var e, r = +new Date() - (s || H) - 1661224081041, a = [];
Object.keys(t.params).forEach(function (n) {
if (n == "analysis")
return false;
t.params.hasOwnProperty(n) && a.push(t.params[n])
})
a = a.sort().join("")
a = i_jt(a)
a = (a += p + t.url.replace(t.baseURL, "")) + (p + r) + (p + 3)
e = i_jt(i_qt(a, "xyz517cda96efgh"))
return e
}
console.log(get_analysis(t))
还可以在精简一下,去除不必要的代码:
js代码+python代码调用实现:
s = 968;
H = 0;
p = "@#";
function i_qt(n, t) {
for (var e = (n = n.split("")).length, r = t.length, a = "charCodeAt", i = H; i < e; i++)
n[i] = o(n[i][a](H) ^ t[(i + 10) % r][a](H));
return n.join("")
}
function o(n) {
t = "",
['66', '72', '6f', '6d', '43', '68', '61', '72', '43', '6f', '64', '65'].forEach(function (n) {
t += unescape("%u00" + n)
});
var t, e = t;
return String[e](n)
}
function i_jt(t) {
t = encodeURIComponent(t).replace(/%([0-9A-F]{2})/g, function (n, t) {
return o("0x" + t)
});
return btoa(t)
}
function get_analysis(t) {
var n;
var e, r = +new Date() - (s || H) - 1661224081041, a = [];
Object.keys(t.params).forEach(function (n) {
if (n == "analysis")
return false;
t.params.hasOwnProperty(n) && a.push(t.params[n])
})
a = a.sort().join("")
a = i_jt(a)
a = (a += p + t.url.replace(t.baseURL, "")) + (p + r) + (p + 3)
e = i_jt(i_qt(a, "xyz517cda96efgh"))
return e
}
// console.log(get_analysis(t))
import requests
import execjs
with open('七麦爬虫.js','r',encoding='utf-8') as f:
js_code = f.read()
headers = {
"accept": "application/json, text/plain, */*",
"accept-language": "zh-CN,zh;q=0.9,en;q=0.8",
"cache-control": "no-cache",
"origin": "https://www.qimai.cn",
"pragma": "no-cache",
"priority": "u=1, i",
"sec-ch-ua": "\"Google Chrome\";v=\"129\", \"Not=A?Brand\";v=\"8\", \"Chromium\";v=\"129\"",
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": "\"Windows\"",
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-fetch-site": "same-site",
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36"
}
cookies = {
"qm_check": "A1sdRUIQChtxen8pI0dAOTQ+GRdzfX0QZlkBAwgGWFEueB4Sd0tRRFAMBRRIUEkCBQcCAAgFcQ9MRiMBChwZQQR2AQgQQks6UzhYWAkJagJtABUQcAshV1ZBWlVYVl9XU1ISDhpVSldESFVKGQcQTQ%3D%3D",
"PHPSESSID": "bsmo60rhgvm8agj62f6i6hpkio",
"gr_user_id": "a9dbc2ff-61c1-4e4e-a91e-6556ac15a1ae",
"ada35577182650f1_gr_session_id": "769644b9-a263-4c0e-8c01-6568f5f9c0ce",
"ada35577182650f1_gr_session_id_sent_vst": "769644b9-a263-4c0e-8c01-6568f5f9c0ce",
"USERINFO": "8ce4AvyvF4frUWw%2Bfg%2FLVh5N6smv4JB5cBUIqIFkBf6Lrspr3BoLCwCUkSnsDf9aBNTzRUdQehFa%2FfVqeOoJ6b%2BRTIiCjx34FVeN4k4FBTvwnspAyGH3XJDhscOWaRRmCnxW4mn3kWVhbVE8BluihQ%3D%3D",
"AUTHKEY": "POJK%2Fi4kQMJvUXS9sjPzP5hK%2B9PxhVbbmdgkypn%2F7NNY1%2B87injqLgLPKkabSm71Z2UGM65rvp%2FkGRxptXlB9nuQZjAojf%2Beusf1jaSdpQH2oogk%2FNUVJQ%3D%3D",
"ada35577182650f1_gr_last_sent_sid_with_cs1": "769644b9-a263-4c0e-8c01-6568f5f9c0ce",
"ada35577182650f1_gr_last_sent_cs1": "qm22941302962",
"synct": "1730621742.633",
"syncd": "-995",
"ada35577182650f1_gr_cs1": "qm22941302962",
"tgw_l7_route": "1ed618a657fde25bb053596f222bc44a"
}
t = {
"url": "/rank/indexPlus/brand_id/0",
"params": {
"brand": "all",
"device": "iphone",
"country": "cn",
"genre": "36"
},
"baseURL": "https://api.qimai.cn",
}
analysis =execjs.compile(js_code).call('get_analysis',t)
params = t['params']
params['analysis'] = analysis
# print(params)
# exit()
url = t['baseURL']+t['url']
response = requests.get(url, headers=headers, cookies=cookies, params=params)
print(response.json())