逆战
关于逆向webpack的模型
常见代码模型
有见解的一些分析
https://blog.csdn.net/sin_0119/article/details/129658679
215
最具有代表性的代码 含引入下面外部 webpackJson 模块 和 内部 传入的模块
require("./webpackJson") // 这里引入同目录下 webpackJson.js 里面都是功能模块函数
var jzq,
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;
try {
e[r].call(t.exports, t, t.exports, u),
o = !1
} finally {
o && delete n[r]
}
return t.l = !0,
t.exports
}
jzq = u;
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) + "." + {
65: "171ca62a04a6be76f495",
66: "f2e18edd4b3b1ee68f7d",
67: "8fb35e19319cb3505775",
68: "aa9bfb31d6a18a5f8e5a"
}[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()
}({
"module_001_inside":function(e,t,n){// 这三个参数分别是 module,module.exports,require 通过n("module_name") 执行 module_name 函数 并且 返回一个 在这个函数里面 通过 e.exports = xx 导出的东西 对象 函数 或者变量 都可以 如下面 a002 就是 函数 e.exports 导出的 可以直接执行 这里的 e.exports === t 是 true 不能 t = xxx (xxx 无论是 函数 变量 还是 对象 都不行) 必须 t.x = x
console.log("module_001_inside")
var a002 = n("module_002_inside") // module_002_inside
a002() // module_001_inside_a002
function a001(){
console.log("module_001_inside_a001")
}
e.exports = a001;
},
"module_002_inside":function(e,t,n){
console.log("module_002_inside")
function a002(){
console.log("module_001_inside_a002")
}
e.exports = a002;
}
});
var tt = "app=CailianpressWeb&os=web&sv=7.7.5"
var obj = jzq("KjvB")
console.log(obj.sync(tt)) //461038b6359a50edfa8ff19d4b917fa12a7b3b56
jzq("module_001_inside") // module_001_inside
需要上面 引入的外部 webpackJson 模块 代码
var window = global
if (!window.webpackJsonp) {
window.webpackJsonp = []
}
(window.webpackJsonp = window.webpackJsonp || []).push([[4], {
"json_001": function (e, t, n) {
console.log("json_001")
},
"json_002": function (e, t, n) {
console.log("json_002")
function a(e) {
console.log("my name is " + e)
}
e.exports.sync = a
},
KjvB: function (e, t, n) {
var r = new (n("c4+4"))
, o = "undefined" !== typeof window ? window : self
, i = o.crypto || o.msCrypto || {}
, u = i.subtle || i.webkitSubtle;
function a(e) {
return r.digest(e)
}
try {
u.digest({
name: "sha-1"
}, new Uint8Array).catch((function () {
u = !1
}
))
} catch (s) {
u = !1
}
e.exports = function (e, t) {
u ? ("string" === typeof e && (e = function (e) {
for (var t = e.length, n = new Uint8Array(t), r = 0; r < t; r++)
n[r] = e.charCodeAt(r);
return n
}(e)),
u.digest({
name: "sha-1"
}, e).then((function (e) {
t(function (e) {
for (var t = e.length, n = [], r = 0; r < t; r++) {
var o = e[r];
n.push((o >>> 4).toString(16)),
n.push((15 & o).toString(16))
}
return n.join("")
}(new Uint8Array(e)))
}
), (function (n) {
t(a(e))
}
))) : setTimeout(t, 0, a(e))
}
,
e.exports.sync = a
},
"c4+4": function(e, t, n) {
var r;
"undefined" !== typeof self && self,
r = function() {
return function(e) {
var t = {};
function n(r) {
if (t[r])
return t[r].exports;
var o = t[r] = {
i: r,
l: !1,
exports: {}
};
return e[r].call(o.exports, o, o.exports, n),
o.l = !0,
o.exports
}
return n.m = e,
n.c = t,
n.d = function(e, t, r) {
n.o(e, t) || Object.defineProperty(e, t, {
configurable: !1,
enumerable: !0,
get: r
})
}
,
n.n = function(e) {
var t = e && e.__esModule ? function() {
return e.default
}
: function() {
return e
}
;
return n.d(t, "a", t),
t
}
,
n.o = function(e, t) {
return Object.prototype.hasOwnProperty.call(e, t)
}
,
n.p = "",
n(n.s = 3)
}([function(e, t, n) {
var r = n(5)
, o = n(1)
, i = o.toHex
, u = o.ceilHeapSize
, a = n(6)
, s = function(e) {
for (e += 9; e % 64 > 0; e += 1)
;
return e
}
, c = function(e, t) {
var n = new Int32Array(e,t + 320,5)
, r = new Int32Array(5)
, o = new DataView(r.buffer);
return o.setInt32(0, n[0], !1),
o.setInt32(4, n[1], !1),
o.setInt32(8, n[2], !1),
o.setInt32(12, n[3], !1),
o.setInt32(16, n[4], !1),
r
}
, f = function() {
function e(t) {
if (function(e, t) {
if (!(e instanceof t))
throw new TypeError("Cannot call a class as a function")
}(this, e),
(t = t || 65536) % 64 > 0)
throw new Error("Chunk size must be a multiple of 128 bit");
this._offset = 0,
this._maxChunkLen = t,
this._padMaxChunkLen = s(t),
this._heap = new ArrayBuffer(u(this._padMaxChunkLen + 320 + 20)),
this._h32 = new Int32Array(this._heap),
this._h8 = new Int8Array(this._heap),
this._core = new r({
Int32Array: Int32Array
},{},this._heap)
}
return e.prototype._initState = function(e, t) {
this._offset = 0;
var n = new Int32Array(e,t + 320,5);
n[0] = 1732584193,
n[1] = -271733879,
n[2] = -1732584194,
n[3] = 271733878,
n[4] = -1009589776
}
,
e.prototype._padChunk = function(e, t) {
var n = s(e)
, r = new Int32Array(this._heap,0,n >> 2);
return function(e, t) {
var n = new Uint8Array(e.buffer)
, r = t % 4
, o = t - r;
switch (r) {
case 0:
n[o + 3] = 0;
case 1:
n[o + 2] = 0;
case 2:
n[o + 1] = 0;
case 3:
n[o + 0] = 0
}
for (var i = 1 + (t >> 2); i < e.length; i++)
e[i] = 0
}(r, e),
function(e, t, n) {
e[t >> 2] |= 128 << 24 - (t % 4 << 3),
e[14 + (2 + (t >> 2) & -16)] = n / (1 << 29) | 0,
e[15 + (2 + (t >> 2) & -16)] = n << 3
}(r, e, t),
n
}
,
e.prototype._write = function(e, t, n, r) {
a(e, this._h8, this._h32, t, n, r || 0)
}
,
e.prototype._coreCall = function(e, t, n, r, o) {
var i = n;
this._write(e, t, n),
o && (i = this._padChunk(n, r)),
this._core.hash(i, this._padMaxChunkLen)
}
,
e.prototype.rawDigest = function(e) {
var t = e.byteLength || e.length || e.size || 0;
this._initState(this._heap, this._padMaxChunkLen);
var n = 0
, r = this._maxChunkLen;
for (n = 0; t > n + r; n += r)
this._coreCall(e, n, r, t, !1);
return this._coreCall(e, n, t - n, t, !0),
c(this._heap, this._padMaxChunkLen)
}
,
e.prototype.digest = function(e) {
return i(this.rawDigest(e).buffer)
}
,
e.prototype.digestFromString = function(e) {
return this.digest(e)
}
,
e.prototype.digestFromBuffer = function(e) {
return this.digest(e)
}
,
e.prototype.digestFromArrayBuffer = function(e) {
return this.digest(e)
}
,
e.prototype.resetState = function() {
return this._initState(this._heap, this._padMaxChunkLen),
this
}
,
e.prototype.append = function(e) {
var t = 0
, n = e.byteLength || e.length || e.size || 0
, r = this._offset % this._maxChunkLen
, o = void 0;
for (this._offset += n; t < n; )
o = Math.min(n - t, this._maxChunkLen - r),
this._write(e, t, o, r),
t += o,
(r += o) === this._maxChunkLen && (this._core.hash(this._maxChunkLen, this._padMaxChunkLen),
r = 0);
return this
}
,
e.prototype.getState = function() {
var e = void 0;
if (this._offset % this._maxChunkLen)
e = this._heap.slice(0);
else {
var t = new Int32Array(this._heap,this._padMaxChunkLen + 320,5);
e = t.buffer.slice(t.byteOffset, t.byteOffset + t.byteLength)
}
return {
offset: this._offset,
heap: e
}
}
,
e.prototype.setState = function(e) {
return this._offset = e.offset,
20 === e.heap.byteLength ? new Int32Array(this._heap,this._padMaxChunkLen + 320,5).set(new Int32Array(e.heap)) : this._h32.set(new Int32Array(e.heap)),
this
}
,
e.prototype.rawEnd = function() {
var e = this._offset
, t = e % this._maxChunkLen
, n = this._padChunk(t, e);
this._core.hash(n, this._padMaxChunkLen);
var r = c(this._heap, this._padMaxChunkLen);
return this._initState(this._heap, this._padMaxChunkLen),
r
}
,
e.prototype.end = function() {
return i(this.rawEnd().buffer)
}
,
e
}();
e.exports = f,
e.exports._core = r
}
, function(e, t) {
for (var n = new Array(256), r = 0; r < 256; r++)
n[r] = (r < 16 ? "0" : "") + r.toString(16);
e.exports.toHex = function(e) {
for (var t = new Uint8Array(e), r = new Array(e.byteLength), o = 0; o < r.length; o++)
r[o] = n[t[o]];
return r.join("")
}
,
e.exports.ceilHeapSize = function(e) {
var t = 0;
if (e <= 65536)
return 65536;
if (e < 16777216)
for (t = 1; t < e; t <<= 1)
;
else
for (t = 16777216; t < e; t += 16777216)
;
return t
}
,
e.exports.isDedicatedWorkerScope = function(e) {
var t = "WorkerGlobalScope"in e && e instanceof e.WorkerGlobalScope
, n = "SharedWorkerGlobalScope"in e && e instanceof e.SharedWorkerGlobalScope
, r = "ServiceWorkerGlobalScope"in e && e instanceof e.ServiceWorkerGlobalScope;
return t && !n && !r
}
}
, function(e, t, n) {这三个参数分别是 module,module.exports,require 通过n("module_name") 执行 module_name 函数 并且 返回一个 在这个函数里面 通过 e.exports = xx 导出的东西 对象 函数 或者变量 都可以 如下面 o 就是 函数 e.exports = o 导出的 可以直接执行
e.exports = function() {
var e = n(0)
, t = function(e, n, r, o, i) {
var u = new self.FileReader;
u.onloadend = function() {
if (u.error)
return i(u.error);
var a = u.result;
n += u.result.byteLength;
try {
e.append(a)
} catch (s) {
return void i(s)
}
n < o.size ? t(e, n, r, o, i) : i(null, e.end())
}
,
u.readAsArrayBuffer(o.slice(n, n + r))
}
, r = !0;
return self.onmessage = function(n) {
if (r) {
var o = n.data.data
, i = n.data.file
, u = n.data.id;
if ("undefined" !== typeof u && (i || o)) {
var a = n.data.blockSize || 4194304
, s = new e(a);
s.resetState();
var c = function(e, t) {
e ? self.postMessage({
id: u,
error: e.name
}) : self.postMessage({
id: u,
hash: t
})
};
o && function(e, t, n) {
try {
n(null, e.digest(t))
} catch (r) {
return n(r)
}
}(s, o, c),
i && t(s, 0, a, i, c)
}
}
}
,
function() {
r = !1
}
}
}
, function(e, t, n) {
var r = n(4)
, o = n(0)
, i = n(7)
, u = n(2)
, a = n(1).isDedicatedWorkerScope
, s = "undefined" !== typeof self && a(self);
o.disableWorkerBehaviour = s ? u() : function() {}
,
o.createWorker = function() {
var e = r(2)
, t = e.terminate;
return e.terminate = function() {
URL.revokeObjectURL(e.objectURL),
t.call(e)
}
,
e
}
,
o.createHash = i,
e.exports = o
}
, function(e, t, n) {
function r(e) {
var t = {};
function n(r) {
if (t[r])
return t[r].exports;
var o = t[r] = {
i: r,
l: !1,
exports: {}
};
return e[r].call(o.exports, o, o.exports, n),
o.l = !0,
o.exports
}
n.m = e,
n.c = t,
n.i = function(e) {
return e
}
,
n.d = function(e, t, r) {
n.o(e, t) || Object.defineProperty(e, t, {
configurable: !1,
enumerable: !0,
get: r
})
}
,
n.r = function(e) {
Object.defineProperty(e, "__esModule", {
value: !0
})
}
,
n.n = function(e) {
var t = e && e.__esModule ? function() {
return e.default
}
: function() {
return e
}
;
return n.d(t, "a", t),
t
}
,
n.o = function(e, t) {
return Object.prototype.hasOwnProperty.call(e, t)
}
,
n.p = "/",
n.oe = function(e) {
throw console.error(e),
e
}
;
var r = n(n.s = ENTRY_MODULE);
return r.default || r
}
var o = "[\\.|\\-|\\+|\\w|/|@]+"
, i = "\\((/\\*.*?\\*/)?s?.*?(" + o + ").*?\\)";
function u(e) {
return (e + "").replace(/[.?*+^$[\]\\(){}|-]/g, "\\$&")
}
function a(e, t, r) {
var a = {};
a[r] = [];
var s = t.toString()
, c = s.match(/^function\s?\(\w+,\s*\w+,\s*(\w+)\)/);
if (!c)
return a;
for (var f, p = c[1], l = new RegExp("(\\\\n|\\W)" + u(p) + i,"g"); f = l.exec(s); )
"dll-reference" !== f[3] && a[r].push(f[3]);
for (l = new RegExp("\\(" + u(p) + '\\("(dll-reference\\s(' + o + '))"\\)\\)' + i,"g"); f = l.exec(s); )
e[f[2]] || (a[r].push(f[1]),
e[f[2]] = n(f[1]).m),
a[f[2]] = a[f[2]] || [],
a[f[2]].push(f[4]);
return a
}
function s(e) {
return Object.keys(e).reduce((function(t, n) {
return t || e[n].length > 0
}
), !1)
}
e.exports = function(e, t) {
t = t || {};
var o = {
main: n.m
}
, i = t.all ? {
main: Object.keys(o)
} : function(e, t) {
for (var n = {
main: [t]
}, r = {
main: []
}, o = {
main: {}
}; s(n); )
for (var i = Object.keys(n), u = 0; u < i.length; u++) {
var c = i[u]
, f = n[c].pop();
if (o[c] = o[c] || {},
!o[c][f] && e[c][f]) {
o[c][f] = !0,
r[c] = r[c] || [],
r[c].push(f);
for (var p = a(e, e[c][f], c), l = Object.keys(p), d = 0; d < l.length; d++)
n[l[d]] = n[l[d]] || [],
n[l[d]] = n[l[d]].concat(p[l[d]])
}
}
return r
}(o, e)
, u = "";
Object.keys(i).filter((function(e) {
return "main" !== e
}
)).forEach((function(e) {
for (var t = 0; i[e][t]; )
t++;
i[e].push(t),
o[e][t] = "(function(module, exports, __webpack_require__) { module.exports = __webpack_require__; })",
u = u + "var " + e + " = (" + r.toString().replace("ENTRY_MODULE", JSON.stringify(t)) + ")({" + i[e].map((function(t) {
return JSON.stringify(t) + ": " + o[e][t].toString()
}
)).join(",") + "});\n"
}
)),
u = u + "(" + r.toString().replace("ENTRY_MODULE", JSON.stringify(e)) + ")({" + i.main.map((function(e) {
return JSON.stringify(e) + ": " + o.main[e].toString()
}
)).join(",") + "})(self);";
var c = new window.Blob([u],{
type: "text/javascript"
});
if (t.bare)
return c;
var f = (window.URL || window.webkitURL || window.mozURL || window.msURL).createObjectURL(c)
, p = new window.Worker(f);
return p.objectURL = f,
p
}
}
, function(e, t) {
e.exports = function(e, t, n) {
"use asm";
var r = new e.Int32Array(n);
function o(e, t) {
e = e | 0;
t = t | 0;
var n = 0
, o = 0
, i = 0
, u = 0
, a = 0
, s = 0
, c = 0
, f = 0
, p = 0
, l = 0
, d = 0
, h = 0
, y = 0
, v = 0;
i = r[t + 320 >> 2] | 0;
a = r[t + 324 >> 2] | 0;
c = r[t + 328 >> 2] | 0;
p = r[t + 332 >> 2] | 0;
d = r[t + 336 >> 2] | 0;
for (n = 0; (n | 0) < (e | 0); n = n + 64 | 0) {
u = i;
s = a;
f = c;
l = p;
h = d;
for (o = 0; (o | 0) < 64; o = o + 4 | 0) {
v = r[n + o >> 2] | 0;
y = ((i << 5 | i >>> 27) + (a & c | ~a & p) | 0) + ((v + d | 0) + 1518500249 | 0) | 0;
d = p;
p = c;
c = a << 30 | a >>> 2;
a = i;
i = y;
r[e + o >> 2] = v
}
for (o = e + 64 | 0; (o | 0) < (e + 80 | 0); o = o + 4 | 0) {
v = (r[o - 12 >> 2] ^ r[o - 32 >> 2] ^ r[o - 56 >> 2] ^ r[o - 64 >> 2]) << 1 | (r[o - 12 >> 2] ^ r[o - 32 >> 2] ^ r[o - 56 >> 2] ^ r[o - 64 >> 2]) >>> 31;
y = ((i << 5 | i >>> 27) + (a & c | ~a & p) | 0) + ((v + d | 0) + 1518500249 | 0) | 0;
d = p;
p = c;
c = a << 30 | a >>> 2;
a = i;
i = y;
r[o >> 2] = v
}
for (o = e + 80 | 0; (o | 0) < (e + 160 | 0); o = o + 4 | 0) {
v = (r[o - 12 >> 2] ^ r[o - 32 >> 2] ^ r[o - 56 >> 2] ^ r[o - 64 >> 2]) << 1 | (r[o - 12 >> 2] ^ r[o - 32 >> 2] ^ r[o - 56 >> 2] ^ r[o - 64 >> 2]) >>> 31;
y = ((i << 5 | i >>> 27) + (a ^ c ^ p) | 0) + ((v + d | 0) + 1859775393 | 0) | 0;
d = p;
p = c;
c = a << 30 | a >>> 2;
a = i;
i = y;
r[o >> 2] = v
}
for (o = e + 160 | 0; (o | 0) < (e + 240 | 0); o = o + 4 | 0) {
v = (r[o - 12 >> 2] ^ r[o - 32 >> 2] ^ r[o - 56 >> 2] ^ r[o - 64 >> 2]) << 1 | (r[o - 12 >> 2] ^ r[o - 32 >> 2] ^ r[o - 56 >> 2] ^ r[o - 64 >> 2]) >>> 31;
y = ((i << 5 | i >>> 27) + (a & c | a & p | c & p) | 0) + ((v + d | 0) - 1894007588 | 0) | 0;
d = p;
p = c;
c = a << 30 | a >>> 2;
a = i;
i = y;
r[o >> 2] = v
}
for (o = e + 240 | 0; (o | 0) < (e + 320 | 0); o = o + 4 | 0) {
v = (r[o - 12 >> 2] ^ r[o - 32 >> 2] ^ r[o - 56 >> 2] ^ r[o - 64 >> 2]) << 1 | (r[o - 12 >> 2] ^ r[o - 32 >> 2] ^ r[o - 56 >> 2] ^ r[o - 64 >> 2]) >>> 31;
y = ((i << 5 | i >>> 27) + (a ^ c ^ p) | 0) + ((v + d | 0) - 899497514 | 0) | 0;
d = p;
p = c;
c = a << 30 | a >>> 2;
a = i;
i = y;
r[o >> 2] = v
}
i = i + u | 0;
a = a + s | 0;
c = c + f | 0;
p = p + l | 0;
d = d + h | 0
}
r[t + 320 >> 2] = i;
r[t + 324 >> 2] = a;
r[t + 328 >> 2] = c;
r[t + 332 >> 2] = p;
r[t + 336 >> 2] = d
}
return {
hash: o
}
}
}
, function(e, t) {
var n = this
, r = void 0;
"undefined" !== typeof self && "undefined" !== typeof self.FileReaderSync && (r = new self.FileReaderSync);
var o = function(e, t, n, r, o, i) {
var u = void 0
, a = i % 4
, s = (o + a) % 4
, c = o - s;
switch (a) {
case 0:
t[i] = e[r + 3];
case 1:
t[i + 1 - (a << 1) | 0] = e[r + 2];
case 2:
t[i + 2 - (a << 1) | 0] = e[r + 1];
case 3:
t[i + 3 - (a << 1) | 0] = e[r]
}
if (!(o < s + (4 - a))) {
for (u = 4 - a; u < c; u = u + 4 | 0)
n[i + u >> 2 | 0] = e[r + u] << 24 | e[r + u + 1] << 16 | e[r + u + 2] << 8 | e[r + u + 3];
switch (s) {
case 3:
t[i + c + 1 | 0] = e[r + c + 2];
case 2:
t[i + c + 2 | 0] = e[r + c + 1];
case 1:
t[i + c + 3 | 0] = e[r + c]
}
}
};
e.exports = function(e, t, i, u, a, s) {
if ("string" === typeof e)
return function(e, t, n, r, o, i) {
var u = void 0
, a = i % 4
, s = (o + a) % 4
, c = o - s;
switch (a) {
case 0:
t[i] = e.charCodeAt(r + 3);
case 1:
t[i + 1 - (a << 1) | 0] = e.charCodeAt(r + 2);
case 2:
t[i + 2 - (a << 1) | 0] = e.charCodeAt(r + 1);
case 3:
t[i + 3 - (a << 1) | 0] = e.charCodeAt(r)
}
if (!(o < s + (4 - a))) {
for (u = 4 - a; u < c; u = u + 4 | 0)
n[i + u >> 2] = e.charCodeAt(r + u) << 24 | e.charCodeAt(r + u + 1) << 16 | e.charCodeAt(r + u + 2) << 8 | e.charCodeAt(r + u + 3);
switch (s) {
case 3:
t[i + c + 1 | 0] = e.charCodeAt(r + c + 2);
case 2:
t[i + c + 2 | 0] = e.charCodeAt(r + c + 1);
case 1:
t[i + c + 3 | 0] = e.charCodeAt(r + c)
}
}
}(e, t, i, u, a, s);
if (e instanceof Array)
return o(e, t, i, u, a, s);
if (n && n.Buffer && n.Buffer.isBuffer(e))
return o(e, t, i, u, a, s);
if (e instanceof ArrayBuffer)
return o(new Uint8Array(e), t, i, u, a, s);
if (e.buffer instanceof ArrayBuffer)
return o(new Uint8Array(e.buffer,e.byteOffset,e.byteLength), t, i, u, a, s);
if (e instanceof Blob)
return function(e, t, n, o, i, u) {
var a = void 0
, s = u % 4
, c = (i + s) % 4
, f = i - c
, p = new Uint8Array(r.readAsArrayBuffer(e.slice(o, o + i)));
switch (s) {
case 0:
t[u] = p[3];
case 1:
t[u + 1 - (s << 1) | 0] = p[2];
case 2:
t[u + 2 - (s << 1) | 0] = p[1];
case 3:
t[u + 3 - (s << 1) | 0] = p[0]
}
if (!(i < c + (4 - s))) {
for (a = 4 - s; a < f; a = a + 4 | 0)
n[u + a >> 2 | 0] = p[a] << 24 | p[a + 1] << 16 | p[a + 2] << 8 | p[a + 3];
switch (c) {
case 3:
t[u + f + 1 | 0] = p[f + 2];
case 2:
t[u + f + 2 | 0] = p[f + 1];
case 1:
t[u + f + 3 | 0] = p[f]
}
}
}(e, t, i, u, a, s);
throw new Error("Unsupported data type.")
}
}
, function(e, t, n) {
var r = function() {
function e(e, t) {
for (var n = 0; n < t.length; n++) {
var r = t[n];
r.enumerable = r.enumerable || !1,
r.configurable = !0,
"value"in r && (r.writable = !0),
Object.defineProperty(e, r.key, r)
}
}
return function(t, n, r) {
return n && e(t.prototype, n),
r && e(t, r),
t
}
}()
, o = n(0)
, i = n(1).toHex
, u = function() {
function e() {
!function(e, t) {
if (!(e instanceof t))
throw new TypeError("Cannot call a class as a function")
}(this, e),
this._rusha = new o,
this._rusha.resetState()
}
return e.prototype.update = function(e) {
return this._rusha.append(e),
this
}
,
e.prototype.digest = function(e) {
var t = this._rusha.rawEnd().buffer;
if (!e)
return t;
if ("hex" === e)
return i(t);
throw new Error("unsupported digest encoding")
}
,
r(e, [{
key: "state",
get: function() {
return this._rusha.getState()
},
set: function(e) {
this._rusha.setState(e)
}
}]),
e
}();
e.exports = function() {
return new u
}
}
])
}
,
e.exports = r()
},
}]);
常见模型代码 1
var _e;
!(function (t) {
var i = {};
function e(s) {
if (i[s]) return i[s].exports;
var n = (i[s] = {
exports: {},
id: s,
loaded: !1,
});
return t[s].call(n.exports, n, n.exports, e), (n.loaded = !0), n.exports;
}
_e = e;
})(
{
0:function(){
console.log("0000")
},
1:function(){
console.log("11111")
},
}
);
var res = _e(0) //0000 只有这个输出
var res = _e(0) //这里不输出 因为 if (i[s]) return i[s].exports 这句话 有缓存直接返回了 来不及调用 这个函数的代码
// 也就是走不到这一句 return t[s].call(n.exports, n, n.exports, e), (n.loaded = !0), n.exports;
常见模型代码 2
var jzq;
!function (e) {
var a = {} //存放加载器
, s = {
app: 0
}
, n = [];
function r(t) {
if (a[t])
return a[t].exports;
var i = a[t] = {
i: t,
l: !1, // 标记当前模块是否被加载
exports: {} // 导入的模块存到空对象中
};
// 执行函数中的方法 e是接受的列表 t是调用下标 call方法是执行
return e[t].call(i.exports, i, i.exports, r),
i.l = !0,
i.exports
}
jzq = r;
r.m = e, // e获取的对应参数信息 会存放所有模块信息
r.c = a,
r.d = function (e, t, i) {
r.o(e, t) || Object.defineProperty(e, t, {
enumerable: !0,
get: i
})
}
r.hello = function(){
console.log("hello")
}
}(
[
function () {
console.log(11111)
},
function () {
console.log(22222)
}
]
)
// [里面的模块集合 也可以写成如下 等价下面的模块集合]
{
0: function () {
console.log(11111)
},
1: function () {
console.log(22222)
}
}
jzq(0) // 11111
jzq(1) // 22222
jzq.hello() //hello 这里在 加载器函数 r 上 直接写 方法 比如上面的 r.m r.c 是变量 r.d r.hello 是函数 可以像 r.d() 这样调用
var res = jzq.m // 显示定义的模式 因为 代码里面有 r.m = e, // e获取的对应参数信息 会存放所有模块信息 这一行
console.log(res)
常见模型代码 3
require("./webpackJson") // 引入外部的 模块集合 在本文件可以调用 看最下面调用代码 当然可以在本函数 实参传入模块 同时存在
var jzq,
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;
try {
e[r].call(t.exports, t, t.exports, u),
o = !1
} finally {
o && delete n[r]
}
return t.l = !0,
t.exports
}
jzq = u;
u.n = function(e) {
var r = e && e.__esModule ? function() {
return e.default
}
: function() {
return e
}
;
return u.d(r, "a", r),
r
}
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()
}([
function(e, r, t) {
console.log(11111)
},
function(e, r, t) {
console.log(22222)
}
]);//这里传入的模块 和 顶部 require("./webpackJson") 的 模块都可以引用
jzq("json_001") webpackJson 外部文件里面的 模块
jzq("json_002") webpackJson 外部文件里面的 模块
jzq(0) 本函数里面的 传入的模块
jzq(1) 本函数里面的 传入的模块
常见算法和编码类型
base64编码
base64常见特征
Base64算法的主要特点如下
1. 可打印性:Base64编码后的字符串只包含可打印的ASCII字符,这使得它可以在文本协议中传输,例如在电子邮件中嵌入二进制数据。
2. 字符集:Base64算法使用64个字符作为编码字符集。这些字符包括大小写字母(A-Z, a-z)、数字(0-9),以及两个特殊字符(+ 和 /)。
3. 固定长度:Base64编码后的字符串长度是原始数据长度的约4/3倍,如果原始数据长度不是3的倍数,则会进行填充。
4. 可逆性:Base64编码是可逆的,也就是说,可以将Base64编码的字符串解码回原始的二进制数据
常见转换方法
js中
window.btoa('123') // 编码
window.atob('MTIz') // 解码
nodejs中
// var a = "123"
// b = new Buffer(a).toString("base64"); 新版本弃用了 会出提示
// console.log(b)
// 编码
const a = "123";
const b = Buffer.from(a, "utf-8").toString("base64");
console.log(b);
// 解码
const c = Buffer.from(b, "base64").toString("utf-8");
console.log(c);
Hash 算法
特点
1. 固定长度:无论输入数据的长度如何,哈希算法都会生成固定长度的哈希值。这使得哈希算法适用于需要固定长度数据的应用场景。
2. 不可逆性:哈希算法是一种单向函数,即从哈希值无法推导出原始输入数据。这意味着无法通过哈希值恢复出原始数据,从而保护了数据的安全性。
3. 高效性:哈希算法通常具有高速计算的特点,能够在短时间内对大量数据进行哈希计算。
4. 唯一性:不同的输入数据很难生成相同的哈希值,保证了哈希值的唯一性。即使输入数据的微小变化,也会导致生成的哈希值发生显著变化
常见的哈希算法包括MD5、SHA-1、SHA-256等
MD5信息摘要算法(英语:MD5 Message-Digest Algorithm)
Js实现
npm install crypto-js --save // --save 添加到package.json中dependencies对象中 以便重装项目时会安装
var CryptoJS = require('crypto-js')
var text = "123456"
md5Text = CryptoJS.MD5(text).toString()
console.log(md5Text)
//输出: e10adc3949ba59abbe56e057f20f883e
python实现
import hashlib
def md5():
md5 = hashlib.md5()
md5.update('123456'.encode('utf-8'))
print(md5.hexdigest())
if __name__ == '__main__':
md5() # e10adc3949ba59abbe56e057f20f883e
SHA(Secure Hash Algorithm)是一系列密码学哈希函数的缩写
特点
- 不可逆性:SHA算法将输入数据映射为固定长度的哈希值,但无法从哈希值还原出原始数据。
- 唯一性:不同的输入数据很难生成相同的哈希值,保证了哈希值的唯一性。
- 散列性:输入数据的微小变化会导致哈希值的显著变化,即使输入数据的长度非常大。
常见Sha算法长度
以加密123456为例 sha系列加密位数:
"SHA1": "7c4a8d09ca3762af61e59520943dc26494f8941b", # 40位
"SHA256":"8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92" # 64位
"SHA512":"ba3253876aed6bc22d4a6ff53d8406c6ad864195ed144ab5c87621b6c233b548baeae6956df346ec8c17f5ea10f35ee3cbc514797ed7ddd3145464e2a0bab413" # 128位
"SHA3-512":"808d63ba47fcef6a7c52ec47cb63eb1b747a9d527a77385fc05c8a5ce8007586265d003b4130f6b0c8f3bb2ad89965a5da07289ba5d1e35321e160bea4f766f8" # 128位
"SHA3-384":"b306d3569477576ab9c8a9d69b514df7acc89f4617d98af67fd04530b9937241a8a94f25ab5d114192c82cfedc2ce545" #96位
"SHA3-256":"c888c9ce9e098d5864d3ded6ebcc140a12142263bace3a23a36f9905f12bd64a" # 64位
"SHA3-224":"0811eedf8207e4d497dc45ba964d58ada516bfea1e72efb8721efca8" # 56位
Js实现
// 引用 crypto-js 加密模块
var CryptoJS = require('crypto-js')
function SHA1Encrypt(text) {
return CryptoJS.SHA1(text).toString();
}
var text = "123456"
console.log(SHA1Encrypt(text))
Python实现
import hashlib
def sha1test(t):
sha1 = hashlib.sha1()
sha1.update(t.encode('utf-8'))
return sha1.hexdigest()
if __name__ == '__main__':
res = sha1test("123456")
print(res)
HMAC(Hash-based Message Authentication Code)是一种基于哈希函数的消息认证码算法
HMAC算法的主要特点包括:
1. 密钥:HMAC算法使用一个密钥来增加数据的安全性。密钥只有发送方和接收方知道,用于生成和验证认证码。
2. 哈希函数:HMAC算法使用一个哈希函数,如SHA-256或SHA-512,来将密钥和数据进行处理。哈希函数的选择取决于所需的安全级别和性能要求。
3. 数据完整性:HMAC算法通过生成认证码来验证数据的完整性。如果数据在传输过程中被修改或篡改,接收方计算生成的认证码将与接收到的认证码不匹配,从而发现数据的篡改.
4. 身份验证:HMAC算法可以用于验证数据的发送方身份。由于只有发送方和接收方知道密钥,接收方可以使用相同的密钥和哈希函数对接收到的数据进行处理,并与发送方提供的认证码进行比较,从而验证发送方的身份
Js实现
var CryptoJS = require('crypto-js')
function HMACEncrypt() {
var text = "123456"
var key = "xxxxxxxxx" // 密钥文件
return CryptoJS.HmacMD5(text, key).toString();
// return CryptoJS.HmacSHA1(text, key).toString();
// return CryptoJS.HmacSHA256(text, key).toString();
}
console.log(HMACEncrypt())
Python实现
import hmac
def hmac_1():
message = 'text'.encode()
key = b'secret'
md5 = hmac.new(key, message, digestmod='MD5')
print(md5.hexdigest())
def hmac_2():
key = 'secret'.encode('utf8')
sha1 = hmac.new(key, digestmod='sha1')
sha1.update('I love '.encode('utf8'))
sha1.update('Python!'.encode('utf8'))
print(sha1.hexdigest())
if __name__ == '__main__':
hmac_1()
hmac_2()
对称加密算法(对称加密算法包括DES AES 3DES 等)
DES(Data Encryp 对称加密算法,由IBM研发并于1977年被美国国家标准局
Js实现1 有iv mode padding
const CryptoJS = require('crypto-js')
var key = CryptoJS.enc.Utf8.parse('dsa213d'),
iv = CryptoJS.enc.Utf8.parse('dsads23d'),
text = CryptoJS.enc.Utf8.parse('text'),
encrypted = CryptoJS.DES.encrypt(text, key,
{
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
}
).toString();
console.log(encrypted)
// nNGZ4YRQbSU=
Js实现 2 只有 key 和 text 并且是文本类型
CryptoJS.AES.encrypt(text, key).toString();
3DES(TripleDES)
1.代码
const CryptoJS = require('crypto-js');
var userName = "13111111111@163.com"
var pwd = 'aaaaaaaa'
function encry(text, userName) {
var key = CryptoJS.enc.Utf8.parse(userName);
// text = CryptoJS.enc.Utf8.parse(text), 这里和DES的区别在于 text 不用 parse 直接文本模式参与
encrypted = CryptoJS.TripleDES.encrypt(text, key,
{
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
}
).toString();
console.log(encrypted) // 2p50P79dZ9M34YIt9pLoqQ==
}
encry(pwd, userName + "00000")
AES算法 AES(Advanced Encryption Standard)是一种对称加密算法,被广泛用于保护敏感数据的机密性。它是目前最常用的加密算法之一
Js实现
const CryptoJS = require('crypto-js')
var key = CryptoJS.enc.Utf8.parse('dsa213d'),
iv = CryptoJS.enc.Utf8.parse('dsads23d'),
text = CryptoJS.enc.Utf8.parse('text'),
encrypted = CryptoJS.AES.encrypt(text, key,
{
iv: iv, //init vector
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
}
).toString();
console.log(encrypted)
// cvzvbPXffZbVIqRKKfxAVQ==
非对称加密算法 RSA
非对称加密算法的主要特点包括:
1.密钥对:非对称加密算法使用密钥对,包括公钥和私钥。公钥可以公开,任何人都可以使用公钥进行加密操作。私钥是保密的,只有密钥的拥有者可以使用私钥进行解密操作。
2.加密和解密:使用公钥对数据进行加密,只有对应的私钥才能解密加密后的数据。这种加密和解密的过程是互逆的,即使用公钥加密的数据只能使用私钥解密,使用私钥加密的数据只能使用公钥解密
3.安全性:非对称加密算法的安全性基于数学问题的难解性。目前没有已知的高效算法可以在合理的时间内破解非对称加密算法,只有拥有私钥的人才能解密加密的数据.
4.加密后的密文每次都不一样。
5.要想解密只能用私钥,私钥是服务端自己保留并不公开,所以如果被人抓包拿到密文也无法解密。
6.由于算法比对称加密更复杂,所以速度也比对称加密慢,但安全性更高
如何生成一对密钥对
1.在dos窗口中
openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:2048
openssl rsa -pubout -in private_key.pem -out public_key.pem
2.注意
public_key 为公钥 加密用
private_key 为私钥 解密用
Js实现1
npm install jsencrypt --save
window = global;
const JSEncrypt = require('jsencrypt');
var encrypt = new JSEncrypt();
const publicKey = '-----BEGIN PUBLIC KEY-----MIIBAB-----END PUBLIC KEY-----'; // 公钥
const privateKey = '-----BEGIN PRIVATE KEY-----MIIEvwIBADAPxRMw+Cw==-----END PRIVATE KEY-----'; // 私钥
// 使用公钥进行加密
function encryptMessage(message, publicKey) {
encrypt.setPublicKey(publicKey);
var encrypted = encrypt.encrypt(data);
return encrypted;
};
// 使用私钥进行解密
function decryotMessage(encrypted,privateKey){
encrypt.setPrivateKey(privateKey);
var decrypted = encrypt.decrypt(encrypted);
return decrypted;
};
var data = 'Hello';
var encrypted = encryptMessage(data,publicKey);
console.log('加密后的密文:', encrypted);
var decrypted = decryotMessage(encrypted,privateKey);
console.log('解密后的明文:', decrypted);
Js实现2
npm install node-forge --save
const forge = require('node-forge');
// 使用公钥进行加密
function encryptMessage(message, publicKeyPem) {
const publicKey = forge.pki.publicKeyFromPem(publicKeyPem);
const encrypted = publicKey.encrypt(message, 'RSA-OAEP'); // RSA-OAEP 公钥加密算法
const encryptedBase64 = forge.util.encode64(encrypted);
return encryptedBase64;
}
// 使用私钥进行解密
function decryptMessage(encryptedBase64, privateKeyPem) {
const privateKey = forge.pki.privateKeyFromPem(privateKeyPem);
const encrypted = forge.util.decode64(encryptedBase64);
const decrypted = privateKey.decrypt(encrypted, 'RSA-OAEP');
return decrypted;
}
const publicKeyPem = '-----BEGIN PUBLIC KEY-----MIIIDAQAB-----END PUBLIC KEY-----'; // 公钥
const privateKeyPem = '-----BEGIN PRIVATE KEY-----MIIEvPxRMw+Cw==-----END PRIVATE KEY-----'; // 私钥
const message = 'abc';
console.log('原始消息:', message);
const encrypted = encryptMessage(message, publicKeyPem);
console.log('加密后的密文:', encrypted);
const decrypted = decryptMessage(encrypted, privateKeyPem);
console.log('解密后的明文:', decrypted);
SM 国密算法
常见国米算法:
SM2非对称(基于椭圆曲线 ECC)加密算法 用于数据加密 ECC 椭圆曲线密码机制 256 位,相比 RSA 处理速度快,消耗更少
SM3散列(hash)函数算法 用于完整性校验 安全性及效率与 SHA-256 相当,压缩函数更复杂
SM4对称(分组)加密算法 用于数据加密和局域网产品 分组长度、密钥长度均为 128 比特,计算轮数多
SM2是非对称 替代RSA
SM3 是哈希算法 替代哈希
SM4是对称 替代AES
SM2
Js实现
npm install sm-crypto --save
// 引入sm-crypto库
const sm = require('sm-crypto').sm2;
// 待加密的明文数据
const plaintext = 'babababababababababa';
// 生成密钥对
const keypair = sm.generateKeyPairHex();
// 获取公钥和私钥
const publicKey = keypair.publicKey;
const privateKey = keypair.privateKey;
// 加密
const ciphertext = sm.doEncrypt(plaintext, publicKey);
console.log('加密后的密文:', ciphertext);
// 解密
const decryptedText = sm.doDecrypt(ciphertext, privateKey);
console.log('解密后的明文:', decryptedText);
SM3
Js实现
const sm3 = require('sm-crypto').sm3;
var data = "333333333333333333"
var res = sm3(data)
console.log(res)
console.log(res.length)
SM4
JS实现
无config配置
const sm4 = require('sm-crypto').sm4;
const key = '0123456789abcdef0123456789abcdef';
var data = '444444444safdsafdsafdsafs4dsadsada44444';
const ciphertext = sm4.encrypt(data,key)
console.log('加密:',ciphertext)
const decryptedText = sm4.decrypt(ciphertext,key)
console.log('解密:',decryptedText)
有config配置
// npm install gm-crypt
function SM4(config, text) {
const sm4 = require("gm-crypt").sm4;
i = new sm4(config).encrypt(text);
return i
}
config = {
"key": "a85ec9f77459825e",
"mode": "ecb",
"cipherType": "base64"
}
console.log(SM4(config, '1234567'))
常见hook大法
JSON 相关
JSON代码
(function() {
var parse_ = JSON.parse;
JSON.parse = function(arg) {
console.log("您猜怎么着?断住了! ——> ",arg);
debugger;
return parse_(arg); // 不改变原来的执行逻辑
}})();
(function() {
var stringify_ = JSON.stringify;
JSON.stringify = function(arg) {
console.log("您猜怎么着?断住了! ——> ",arg);
debugger;
return stringify(arg); // 不改变原来的执行逻辑
}})();
XHR 相关
XHR代码
(function () {
var open = window.XMLHttpRequest.prototype.open;
window.XMLHttpRequest.prototype.open = function (method, url, async) {
if (url.indexOf("参数名称") != -1) {
debugger;
}
return open.apply(this, arguments);
};
})();
(function (){
var sh = window.XMLHttpRequest.prototype.setRequestHeader;
window.XMLHttpRequest.prototype.setRequestHeader=function(key,value){
if(key == 'header的参数key'){
debugger;
}
return sh.apply(this,arguments);
};
})();
Cookie 相关
cookie 代码
(function () {
var cookieTemp = '';
Object.defineProperty(document, 'cookie', {
set: function (val) {
if (val.indexOf('v') != -1) {
debugger;
}
console.log('Hook捕获到cookie设置->', val);
cookieTemp = val;
return val;
},
get: function () {
return cookieTemp;
},
});
})();
方法置空
点击查看代码
function deg(){
debugger;
}
//debugger的方法deg 直接控制台输入
deg = function(){
debugger() # 对于这一种也可以不重置函数 在此句代码前设置条件断点 false 让他用于在这里断不住
}
setInterval = function(){} //置空
setTimeout = function(){}
console = function(){}
//关于 constructor 函数的 Hook
Function.prototype.constructor = function(){}
(function(){
var _constructor = Function.prototype.constructor
Function.prototype.constructor = function(s){
if(s === "debugger"){
//console.log(s)
return null;
}
return _constructor(s);
}
})()
//关于 eval 函数的 Hook
var eval_ = eval;
eval = function(code) {
if (code.indexOf("altrt('abc')") != -1) {
console.log("eval: " + code);
return null;
}
return eval_(code);
};
实操篇
1.跟入断点后 进入 断点里面的 函数 临时打断点 点 继续执行脚本 就会 断到 这个临时的断点上
2.抠出的部分代码 可以直接 放在 代码片段 去暂时修改执行 通过后 再去 vs 上补环境去运行 这样就避免调试过程中频繁补环境
3.对于 DES 和 AES
1.有时候 分析 key iv 的时候 要调试看一下 转换后的 key 和 iv 是否和 vs 中 扣出的 是否相同 因为 有时候 key 和 iv
1.因为很小的区别 转出来 不一样 是个坑
4.堆栈调试的时候 遇到 Promise
1.遇到promise 返回 promise 循环 调用 then 返回 promise 又 调用 then
1.代码1
c = Promise.resolve(n);//成功后 resolve 返回一个 Promise 然后 then
c = c.then(h[d++], h[d++]);//then 前面 h[d++] 前面函数 成功 后面失败
//下面是这个的原始代码 [注意for的用法]
if (!a) {
const h = [tg.bind(this), void 0];
for (h.unshift.apply(h, i),
h.push.apply(h, l),
f = h.length,
c = Promise.resolve(n); d < f;)
c = c.then(h[d++], h[d++]
);
return c
}
return c
2.遇到 for 如果只跟一条语句 可以不用{}
for(
let i = 1,a=3,b=4;
i < j;
)
console.log(i++,j,a,b)
3.遇到这种类型的要敏锐的感觉到 是 加密后的结果 用 .toString() 后 就是加密后的结果
1.oriText = u + o + decodeURIComponent(r) + n // 这里是一串拼接好的文本
2.resSha256 = uK(u + o + decodeURIComponent(r) + n) // resSha256 如下:
resSha256 = {
"words": [
-503262144,
-1740479842,
-752929019,
-253769511,
654158390,
-1615402538,
1298469063,
-1235272696
],
"sigBytes": 32
}
3.resSha256.toString() // e200d4409842629ed31f3705f0dfc8d926fdaa369fb6e9d64d6510c7b65f3c08
4.把 1.里面的文本 在 spidertools 里面放入加密里面 出结果后 拿 3 里面的文本去结果中查找 看是哪一种加密方式
4.遇到 promise 可以在 resolve reject then 处下断点
1.如果发现 断住后要的数据 在 promise 之前就出现 就往前跟栈 进入到这个 promise 的空间
2.如果发现要的数据 断住还没有加密 在 resolve 方法 或者 then 的参数函数 里面进行 加密 就跟进 去
5.在vscode中调试代码 在引用的地方 按住 ctrl 点击 可以查看 定义的地方 可以 无限循环持续下去
1.shift + alt + f12 可以查看哪里引用了这个定义
6.找参数 下断点 一般在 XHR 的 send 的地方
1.解返回代码加密 一般在 send 后 下面的 try 给 4 === l.readyState 下个条件断点
try {
if (r && (i || 4 === l.readyState)){
// 在这里下个条件断点 4 === l.readyState 这样跟这这个代码一步一步调式 就看到解密了
"string" == typeof l.responseText && (p.text = l.responseText);
}
} catch (d) {
}
7.对于 webpack 模型 找加载器有两个途径
1.通过 n("1111") 下断点 刷新页面 自动暂停 跟进去
20通过 window["webpackJsonp"] 选中后 看 push 函数 点进去 加载器在这个地方附近 上下几行
8.对于 下断点后 断住了 分析代码
1.var password = encodeURI(Object(w["c"])(a.value, Object(w["f"])(Object(w["g"])(r.value))))
1..比如上面 函数 套 函数 但是 分析后 发现 后面两个函数执行后 对数据影响不大 可以定死 于是变成
2.var password = encodeURI(Object(w["c"])(pwd, userName + "00000"));
3.然后 分析 这个函数 Object(w["c"]) 点进去 下断点 此时 原始的代码 只是分析没有运行 如果 一步一步跟 很麻烦
4.直接在 Object(w["c"]) 里面下个断点后 点击 继续 执行脚本 就可以一步断住 非常方便