网址链接:财联社A股24小时电报-上市公司动态-今日股市行情报道
数据包sign参数为加密,可以直接搜索找参数的位置,搜索不到的情况下,在断点跟栈:
确定js文件所在位置,并打上断点。 点击加载刷新页面。可以发现这个文件是一个多文件的webpack,最上面的代码展现。
在控制台输出:
鼠标放在S上,进入S
这种形式,是一个加载器,在同js文件上面找S生成的位置
其中n为加载器,里面的字符串为webpack后面列表中的字典的键,对应的配置函数。
鼠标放在m上,进入m,发现是一个最后列表函数为空的webpack
复制代码,并在js中稍微改写
var yangxin;
var window=global;
!function(e) {
function r(r) {
for (var n, u, i = r[0], c = r[1], f = r[2], p = 0, s = []; p < i.length; p++)
u = i[p],
Object.prototype.hasOwnProperty.call(o, u) && o[u] && s.push(o[u][0]),
o[u] = 0;
for (n in c)
Object.prototype.hasOwnProperty.call(c, n) && (e[n] = c[n]);
for (l && l(r); s.length; )
s.shift()();
return a.push.apply(a, f || []),
t()
}
function t() {
for (var e, r = 0; r < a.length; r++) {
for (var t = a[r], n = !0, i = 1; i < t.length; i++) {
var c = t[i];
0 !== o[c] && (n = !1)
}
n && (a.splice(r--, 1),
e = u(u.s = t[0]))
}
return e
}
var n = {}
, o = {
1: 0
}
, a = [];
function u(r) {
if (n[r])
return n[r].exports;
var t = n[r] = {
i: r,
l: !1,
exports: {}
}
, o = !0;
console.log(r)
try {
e[r].call(t.exports, t, t.exports, u),
o = !1
} finally {
o && delete n[r]
}
return t.l = !0,
t.exports
}
u.e = function(e) {
var r = []
, t = o[e];
if (0 !== t)
if (t)
r.push(t[2]);
else {
var n = new Promise((function(r, n) {
t = o[e] = [r, n]
}
));
r.push(t[2] = n);
var a, i = document.createElement("script");
i.charset = "utf-8",
i.timeout = 120,
u.nc && i.setAttribute("nonce", u.nc),
i.src = function(e) {
return u.p + "static/chunks/" + ({}[e] || e) + "." + {
64: "f98369126adebd425fa6",
65: "c822939a64030dc2b41a",
66: "a6f1cad4a3fd3d93d6ad",
67: "19ba0ff6a097f7a56d45"
}[e] + ".js"
}(e);
var c = new Error;
a = function(r) {
i.onerror = i.onload = null,
clearTimeout(f);
var t = o[e];
if (0 !== t) {
if (t) {
var n = r && ("load" === r.type ? "missing" : r.type)
, a = r && r.target && r.target.src;
c.message = "Loading chunk " + e + " failed.\n(" + n + ": " + a + ")",
c.name = "ChunkLoadError",
c.type = n,
c.request = a,
t[1](c)
}
o[e] = void 0
}
}
;
var f = setTimeout((function() {
a({
type: "timeout",
target: i
})
}
), 12e4);
i.onerror = i.onload = a,
document.head.appendChild(i)
}
return Promise.all(r)
}
,
u.m = e,
u.c = n,
u.d = function(e, r, t) {
u.o(e, r) || Object.defineProperty(e, r, {
enumerable: !0,
get: t
})
}
,
u.r = function(e) {
"undefined" !== typeof Symbol && Symbol.toStringTag && Object.defineProperty(e, Symbol.toStringTag, {
value: "Module"
}),
Object.defineProperty(e, "__esModule", {
value: !0
})
}
,
u.t = function(e, r) {
if (1 & r && (e = u(e)),
8 & r)
return e;
if (4 & r && "object" === typeof e && e && e.__esModule)
return e;
var t = Object.create(null);
if (u.r(t),
Object.defineProperty(t, "default", {
enumerable: !0,
value: e
}),
2 & r && "string" != typeof e)
for (var n in e)
u.d(t, n, function(r) {
return e[r]
}
.bind(null, n));
return t
}
,
u.n = function(e) {
var r = e && e.__esModule ? function() {
return e.default
}
: function() {
return e
}
;
return u.d(r, "a", r),
r
}
,
u.o = function(e, r) {
return Object.prototype.hasOwnProperty.call(e, r)
}
,
u.p = "",
u.oe = function(e) {
throw console.error(e),
e
}
;
var i = window.webpackJsonp = window.webpackJsonp || []
, c = i.push.bind(i);
i.push = r,
i = i.slice();
for (var f = 0; f < i.length; f++)
r(i[f]);
var l = c;
t()
yangxin = u;
}([]);
console.log(yangxin))
结果为:
现在的目标就是复制 W2Yj函数,直接在sign所在的js文件搜索并复制粘贴。j将后面的列表改为字典格式
代码展现:
var yangxin;
var window=global;
!function(e) {
function r(r) {
for (var n, u, i = r[0], c = r[1], f = r[2], p = 0, s = []; p < i.length; p++)
u = i[p],
Object.prototype.hasOwnProperty.call(o, u) && o[u] && s.push(o[u][0]),
o[u] = 0;
for (n in c)
Object.prototype.hasOwnProperty.call(c, n) && (e[n] = c[n]);
for (l && l(r); s.length; )
s.shift()();
return a.push.apply(a, f || []),
t()
}
function t() {
for (var e, r = 0; r < a.length; r++) {
for (var t = a[r], n = !0, i = 1; i < t.length; i++) {
var c = t[i];
0 !== o[c] && (n = !1)
}
n && (a.splice(r--, 1),
e = u(u.s = t[0]))
}
return e
}
var n = {}
, o = {
1: 0
}
, a = [];
function u(r) {
if (n[r])
return n[r].exports;
var t = n[r] = {
i: r,
l: !1,
exports: {}
}
, o = !0;
console.log(r)
try {
e[r].call(t.exports, t, t.exports, u),
o = !1
} finally {
o && delete n[r]
}
return t.l = !0,
t.exports
}
u.e = function(e) {
var r = []
, t = o[e];
if (0 !== t)
if (t)
r.push(t[2]);
else {
var n = new Promise((function(r, n) {
t = o[e] = [r, n]
}
));
r.push(t[2] = n);
var a, i = document.createElement("script");
i.charset = "utf-8",
i.timeout = 120,
u.nc && i.setAttribute("nonce", u.nc),
i.src = function(e) {
return u.p + "static/chunks/" + ({}[e] || e) + "." + {
64: "f98369126adebd425fa6",
65: "c822939a64030dc2b41a",
66: "a6f1cad4a3fd3d93d6ad",
67: "19ba0ff6a097f7a56d45"
}[e] + ".js"
}(e);
var c = new Error;
a = function(r) {
i.onerror = i.onload = null,
clearTimeout(f);
var t = o[e];
if (0 !== t) {
if (t) {
var n = r && ("load" === r.type ? "missing" : r.type)
, a = r && r.target && r.target.src;
c.message = "Loading chunk " + e + " failed.\n(" + n + ": " + a + ")",
c.name = "ChunkLoadError",
c.type = n,
c.request = a,
t[1](c)
}
o[e] = void 0
}
}
;
var f = setTimeout((function() {
a({
type: "timeout",
target: i
})
}
), 12e4);
i.onerror = i.onload = a,
document.head.appendChild(i)
}
return Promise.all(r)
}
,
u.m = e,
u.c = n,
u.d = function(e, r, t) {
u.o(e, r) || Object.defineProperty(e, r, {
enumerable: !0,
get: t
})
}
,
u.r = function(e) {
"undefined" !== typeof Symbol && Symbol.toStringTag && Object.defineProperty(e, Symbol.toStringTag, {
value: "Module"
}),
Object.defineProperty(e, "__esModule", {
value: !0
})
}
,
u.t = function(e, r) {
if (1 & r && (e = u(e)),
8 & r)
return e;
if (4 & r && "object" === typeof e && e && e.__esModule)
return e;
var t = Object.create(null);
if (u.r(t),
Object.defineProperty(t, "default", {
enumerable: !0,
value: e
}),
2 & r && "string" != typeof e)
for (var n in e)
u.d(t, n, function(r) {
return e[r]
}
.bind(null, n));
return t
}
,
u.n = function(e) {
var r = e && e.__esModule ? function() {
return e.default
}
: function() {
return e
}
;
return u.d(r, "a", r),
r
}
,
u.o = function(e, r) {
return Object.prototype.hasOwnProperty.call(e, r)
}
,
u.p = "",
u.oe = function(e) {
throw console.error(e),
e
}
;
var i = window.webpackJsonp = window.webpackJsonp || []
, c = i.push.bind(i);
i.push = r,
i = i.slice();
for (var f = 0; f < i.length; f++)
r(i[f]);
var l = c;
t()
yangxin = u;
}({
W2Yj: function(e, t, n) {
var r = n("p0XB")
, o = n("pLtp")
, i = n("KjvB")
, u = n("aCH8")
, a = !0;
function s(e) {
return String(e)
}
function c(e) {
return o(e).sort()
}
function f(e) {
return e.filter((function(e) {
return e
}
)).join("&")
}
function p(e, t) {
var n = typeof t
, o = null;
return t === o ? o = a ? o : "".concat(s(e), "=").concat(o) : /string|number|boolean/.test(n) ? o = "".concat(s(e), "=").concat(s(t)) : r(t) ? o = function(e, t) {
return t.length ? f(t.map((function(t, n) {
return p("".concat(e, "[").concat(n, "]"), t)
}
))) : s("".concat(e, "[]"))
}(e, t) : "object" === n && (o = function(e, t) {
return f(c(t).map((function(n) {
return p("".concat(e, "[").concat(n, "]"), t[n])
}
)))
}(e, t)),
o
}
e.exports = function(e) {
var t = e && f(c(e).map((function(t) {
return p(t, e[t])
}
)));
return t = i.sync(t),
t = u(t)
}
}
});
console.log(yangxin('W2Yj'))
结果展现:
为了找到缺少的具体部分,可以在加载器一开始打入console.log(r)
然后会返回:
返回一开复制的地方
发现W2Yj还调用了其他模块,为了找到它们,直接在控制台打印。它们是内置函数,跟上一个案例还有一点不同。
最后解决方法见链接:【搞Python爬虫JS逆向,再不会WebPack解密,就OUT啦!-哔哩哔哩】 https://b23.tv/OFVDLi5
比较与上一个案例的相同点:
两者的生成js文件最上面都是
(window.webpackJsonp = window.webpackJsonp || []).push([[4], [function(t, e, n) {
(1)repid由n赋值
n由c()()赋值
进入c(),发现是在下面 是
上面追溯,发现c是由n组成,进入n发现是一个webpack,且列表中为空,n就是代表加载器,n(100)为函数,可以在控制台打印。
(2)
进入S,这种形式的一看就是webpack
所以一定可以在上面找到S的生成。
进入n发现是一个webpack,n代表加载器。n('W2Yj')代表函数,可以在下面打印。