反编译某听书网站直接获取音频地址
本帖最后由 GstYon 于 2020-11-13 10:50 编辑从来吾爱后,第一次发这种帖子,以前最多就是分享一些福利资源而已。
最近在听这本小说, 不过资源部好找, 找到一个在线听书的,想把资源下载下来,就尝试反编译一下,然后把过程分享一下。
F12获取他播放的音频文件 是m4a的。
在查看对应的目录结构,里面是没有m4a的文件,只有data-path一个 加密字符串,看起来是base64的。
通过地址、文件名等关键词搜索,也没有搜索到相关信息,怎么办呢,继续找找其他的吧。
通过断点找到一个这个加密解密相关的文件,,把他格式化一下。
var CryptoJS = CryptoJS ||
function(u, p) {
var d = {},
l = d.lib = {},
s = function() {},
t = l.Base = {
extend: function(a) {
s.prototype = this;
var c = new s;
a && c.mixIn(a);
c.hasOwnProperty("init") || (c.init = function() {
c.$super.init.apply(this, arguments)
});
c.init.prototype = c;
c.$super = this;
return c
},
create: function() {
var a = this.extend();
a.init.apply(a, arguments);
return a
},
init: function() {},
mixIn: function(a) {
for (var c in a) a.hasOwnProperty(c) && (this = a);
a.hasOwnProperty("toString") && (this.toString = a.toString)
},
clone: function() {
return this.init.prototype.extend(this)
}
},
r = l.WordArray = t.extend({
init: function(a, c) {
a = this.words = a || [];
this.sigBytes = c != p ? c : 4 * a.length
},
toString: function(a) {
return (a || v).stringify(this)
},
concat: function(a) {
var c = this.words,
e = a.words,
j = this.sigBytes;
a = a.sigBytes;
this.clamp();
if (j % 4) for (var k = 0; k < a; k++) c |= (e >>> 24 - 8 * (k % 4) & 255) << 24 - 8 * ((j + k) % 4);
else if (65535 < e.length) for (k = 0; k < a; k += 4) c = e;
else c.push.apply(c, e);
this.sigBytes += a;
return this
},
clamp: function() {
var a = this.words,
c = this.sigBytes;
a &= 4294967295 << 32 - 8 * (c % 4);
a.length = u.ceil(c / 4)
},
clone: function() {
var a = t.clone.call(this);
a.words = this.words.slice(0);
return a
},
random: function(a) {
for (var c = [], e = 0; e < a; e += 4) c.push(4294967296 * u.random() | 0);
return new r.init(c, a)
}
}),
w = d.enc = {},
v = w.Hex = {
stringify: function(a) {
var c = a.words;
a = a.sigBytes;
for (var e = [], j = 0; j < a; j++) {
var k = c >>> 24 - 8 * (j % 4) & 255;
e.push((k >>> 4).toString(16));
e.push((k & 15).toString(16))
}
return e.join("")
},
parse: function(a) {
for (var c = a.length, e = [], j = 0; j < c; j += 2) e |= parseInt(a.substr(j, 2), 16) << 24 - 4 * (j % 8);
return new r.init(e, c / 2)
}
},
b = w.Latin1 = {
stringify: function(a) {
var c = a.words;
a = a.sigBytes;
for (var e = [], j = 0; j < a; j++) e.push(String.fromCharCode(c >>> 24 - 8 * (j % 4) & 255));
return e.join("")
},
parse: function(a) {
for (var c = a.length, e = [], j = 0; j < c; j++) e |= (a.charCodeAt(j) & 255) << 24 - 8 * (j % 4);
return new r.init(e, c)
}
},
x = w.Utf8 = {
stringify: function(a) {
try {
return decodeURIComponent(escape(b.stringify(a)))
} catch (c) {
throw Error("Malformed UTF-8 data");
}
},
parse: function(a) {
return b.parse(unescape(encodeURIComponent(a)))
}
},
q = l.BufferedBlockAlgorithm = t.extend({
reset: function() {
this._data = new r.init;
this._nDataBytes = 0
},
_append: function(a) {
"string" == typeof a && (a = x.parse(a));
this._data.concat(a);
this._nDataBytes += a.sigBytes
},
_process: function(a) {
var c = this._data,
e = c.words,
j = c.sigBytes,
k = this.blockSize,
b = j / (4 * k),
b = a ? u.ceil(b) : u.max((b | 0) - this._minBufferSize, 0);
a = b * k;
j = u.min(4 * a, j);
if (a) {
for (var q = 0; q < a; q += k) this._doProcessBlock(e, q);
q = e.splice(0, a);
c.sigBytes -= j
}
return new r.init(q, j)
},
clone: function() {
var a = t.clone.call(this);
a._data = this._data.clone();
return a
},
_minBufferSize: 0
});
l.Hasher = q.extend({
cfg: t.extend(),
init: function(a) {
this.cfg = this.cfg.extend(a);
this.reset()
},
reset: function() {
q.reset.call(this);
this._doReset()
},
update: function(a) {
this._append(a);
this._process();
return this
},
finalize: function(a) {
a && this._append(a);
return this._doFinalize()
},
blockSize: 16,
_createHelper: function(a) {
return function(b, e) {
return (new a.init(e)).finalize(b)
}
},
_createHmacHelper: function(a) {
return function(b, e) {
return (new n.HMAC.init(a, e)).finalize(b)
}
}
});
var n = d.algo = {};
return d
}(Math);
(function() {
var h = CryptoJS,
j = h.lib.WordArray;
h.enc.Base64 = {
stringify: function(b) {
var e = b.words,
f = b.sigBytes,
c = this._map;
b.clamp();
b = [];
for (var a = 0; a < f; a += 3) for (var d = (e >>> 24 - 8 * (a % 4) & 255) << 16 | (e >>> 24 - 8 * ((a + 1) % 4) & 255) << 8 | e >>> 24 - 8 * ((a + 2) % 4) & 255, g = 0; 4 > g && a + 0.75 * g < f; g++) b.push(c.charAt(d >>> 6 * (3 - g) & 63));
if (e = c.charAt(64)) for (; b.length % 4;) b.push(e);
return b.join("")
},
parse: function(b) {
var e = b.length,
f = this._map,
c = f.charAt(64);
c && (c = b.indexOf(c), -1 != c && (e = c));
for (var c = [], a = 0, d = 0; d < e; d++) if (d % 4) {
var g = f.indexOf(b.charAt(d - 1)) << 2 * (d % 4),
h = f.indexOf(b.charAt(d)) >>> 6 - 2 * (d % 4);
c |= (g | h) << 24 - 8 * (a % 4);
a++
}
return j.create(c, a)
},
_map: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
}
})();
CryptoJS.lib.Cipher ||
function(u) {
var p = CryptoJS,
d = p.lib,
l = d.Base,
s = d.WordArray,
t = d.BufferedBlockAlgorithm,
r = p.enc.Base64,
w = p.algo.EvpKDF,
v = d.Cipher = t.extend({
cfg: l.extend(),
createEncryptor: function(e, a) {
return this.create(this._ENC_XFORM_MODE, e, a)
},
createDecryptor: function(e, a) {
return this.create(this._DEC_XFORM_MODE, e, a)
},
init: function(e, a, b) {
this.cfg = this.cfg.extend(b);
this._xformMode = e;
this._key = a;
this.reset()
},
reset: function() {
t.reset.call(this);
this._doReset()
},
process: function(e) {
this._append(e);
return this._process()
},
finalize: function(e) {
e && this._append(e);
return this._doFinalize()
},
keySize: 4,
ivSize: 4,
_ENC_XFORM_MODE: 1,
_DEC_XFORM_MODE: 2,
_createHelper: function(e) {
return {
encrypt: function(b, k, d) {
return ("string" == typeof k ? c : a).encrypt(e, b, k, d)
},
decrypt: function(b, k, d) {
return ("string" == typeof k ? c : a).decrypt(e, b, k, d)
}
}
}
});
d.StreamCipher = v.extend({
_doFinalize: function() {
return this._process(!0)
},
blockSize: 1
});
var b = p.mode = {},
x = function(e, a, b) {
var c = this._iv;
c ? this._iv = u : c = this._prevBlock;
for (var d = 0; d < b; d++) e ^= c
},
q = (d.BlockCipherMode = l.extend({
createEncryptor: function(e, a) {
return this.Encryptor.create(e, a)
},
createDecryptor: function(e, a) {
return this.Decryptor.create(e, a)
},
init: function(e, a) {
this._cipher = e;
this._iv = a
}
})).extend();
q.Encryptor = q.extend({
processBlock: function(e, a) {
var b = this._cipher,
c = b.blockSize;
x.call(this, e, a, c);
b.encryptBlock(e, a);
this._prevBlock = e.slice(a, a + c)
}
});
q.Decryptor = q.extend({
processBlock: function(e, a) {
var b = this._cipher,
c = b.blockSize,
d = e.slice(a, a + c);
b.decryptBlock(e, a);
x.call(this, e, a, c);
this._prevBlock = d
}
});
b = b.CBC = q;
q = (p.pad = {}).Pkcs7 = {
pad: function(a, b) {
for (var c = 4 * b, c = c - a.sigBytes % c, d = c << 24 | c << 16 | c << 8 | c, l = [], n = 0; n < c; n += 4) l.push(d);
c = s.create(l, c);
a.concat(c)
},
unpad: function(a) {
a.sigBytes -= a.words & 255
}
};
d.BlockCipher = v.extend({
cfg: v.cfg.extend({
mode: b,
padding: q
}),
reset: function() {
v.reset.call(this);
var a = this.cfg,
b = a.iv,
a = a.mode;
if (this._xformMode == this._ENC_XFORM_MODE) var c = a.createEncryptor;
else c = a.createDecryptor, this._minBufferSize = 1;
this._mode = c.call(a, this, b && b.words)
},
_doProcessBlock: function(a, b) {
this._mode.processBlock(a, b)
},
_doFinalize: function() {
var a = this.cfg.padding;
if (this._xformMode == this._ENC_XFORM_MODE) {
a.pad(this._data, this.blockSize);
var b = this._process(!0)
} else b = this._process(!0), a.unpad(b);
return b
},
blockSize: 4
});
var n = d.CipherParams = l.extend({
init: function(a) {
this.mixIn(a)
},
toString: function(a) {
return (a || this.formatter).stringify(this)
}
}),
b = (p.format = {}).OpenSSL = {
stringify: function(a) {
var b = a.ciphertext;
a = a.salt;
return (a ? s.create().concat(a).concat(b) : b).toString(r)
},
parse: function(a) {
a = r.parse(a);
var b = a.words;
if (1398893684 == b && 1701076831 == b) {
var c = s.create(b.slice(2, 4));
b.splice(0, 4);
a.sigBytes -= 16
}
return n.create({
ciphertext: a,
salt: c
})
}
},
a = d.SerializableCipher = l.extend({
cfg: l.extend({
format: b
}),
encrypt: function(a, b, c, d) {
d = this.cfg.extend(d);
var l = a.createEncryptor(c, d);
b = l.finalize(b);
l = l.cfg;
return n.create({
ciphertext: b,
key: c,
iv: l.iv,
algorithm: a,
mode: l.mode,
padding: l.padding,
blockSize: a.blockSize,
formatter: d.format
})
},
decrypt: function(a, b, c, d) {
d = this.cfg.extend(d);
b = this._parse(b, d.format);
return a.createDecryptor(c, d).finalize(b.ciphertext)
},
_parse: function(a, b) {
return "string" == typeof a ? b.parse(a, this) : a
}
}),
p = (p.kdf = {}).OpenSSL = {
execute: function(a, b, c, d) {
d || (d = s.random(8));
a = w.create({
keySize: b + c
}).compute(a, d);
c = s.create(a.words.slice(b), 4 * c);
a.sigBytes = 4 * b;
return n.create({
key: a,
iv: c,
salt: d
})
}
},
c = d.PasswordBasedCipher = a.extend({
cfg: a.cfg.extend({
kdf: p
}),
encrypt: function(b, c, d, l) {
l = this.cfg.extend(l);
d = l.kdf.execute(d, b.keySize, b.ivSize);
l.iv = d.iv;
b = a.encrypt.call(this, b, c, d.key, l);
b.mixIn(d);
return b
},
decrypt: function(b, c, d, l) {
l = this.cfg.extend(l);
c = this._parse(c, l.format);
d = l.kdf.execute(d, b.keySize, b.ivSize, c.salt);
l.iv = d.iv;
return a.decrypt.call(this, b, c, d.key, l)
}
})
}();
(function() {
for (var u = CryptoJS, p = u.lib.BlockCipher, d = u.algo, l = [], s = [], t = [], r = [], w = [], v = [], b = [], x = [], q = [], n = [], a = [], c = 0; 256 > c; c++) a = 128 > c ? c << 1 : c << 1 ^ 283;
for (var e = 0, j = 0, c = 0; 256 > c; c++) {
var k = j ^ j << 1 ^ j << 2 ^ j << 3 ^ j << 4,
k = k >>> 8 ^ k & 255 ^ 99;
l = k;
s = e;
var z = a,
F = a,
G = a,
y = 257 * a ^ 16843008 * k;
t = y << 24 | y >>> 8;
r = y << 16 | y >>> 16;
w = y << 8 | y >>> 24;
v = y;
y = 16843009 * G ^ 65537 * F ^ 257 * z ^ 16843008 * e;
b = y << 24 | y >>> 8;
x = y << 16 | y >>> 16;
q = y << 8 | y >>> 24;
n = y;
e ? (e = z ^ a]], j ^= a]) : e = j = 1
}
var H = ,
d = d.AES = p.extend({
_doReset: function() {
for (var a = this._key, c = a.words, d = a.sigBytes / 4, a = 4 * ((this._nRounds = d + 6) + 1), e = this._keySchedule = [], j = 0; j < a; j++) if (j < d) e = c;
else {
var k = e;
j % d ? 6 < d && 4 == j % d && (k = l << 24 | l << 16 | l << 8 | l) : (k = k << 8 | k >>> 24, k = l << 24 | l << 16 | l << 8 | l, k ^= H << 24);
e = e ^ k
}
c = this._invKeySchedule = [];
for (d = 0; d < a; d++) j = a - d, k = d % 4 ? e : e, c = 4 > d || 4 >= j ? k : b] ^ x] ^ q] ^ n]
},
encryptBlock: function(a, b) {
this._doCryptBlock(a, b, this._keySchedule, t, r, w, v, l)
},
decryptBlock: function(a, c) {
var d = a;
a = a;
a = d;
this._doCryptBlock(a, c, this._invKeySchedule, b, x, q, n, s);
d = a;
a = a;
a = d
},
_doCryptBlock: function(a, b, c, d, e, j, l, f) {
for (var m = this._nRounds, g = a ^ c, h = a ^ c, k = a ^ c, n = a ^ c, p = 4, r = 1; r < m; r++) var q = d ^ e ^ j ^ l ^ c,
s = d ^ e ^ j ^ l ^ c,
t = d ^ e ^ j ^ l ^ c,
n = d ^ e ^ j ^ l ^ c,
g = q,
h = s,
k = t;
q = (f << 24 | f << 16 | f << 8 | f) ^ c;
s = (f << 24 | f << 16 | f << 8 | f) ^ c;
t = (f << 24 | f << 16 | f << 8 | f) ^ c;
n = (f << 24 | f << 16 | f << 8 | f) ^ c;
a = q;
a = s;
a = t;
a = n
},
keySize: 8
});
u.AES = p._createHelper(d)
})();
function Base64() {
_keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
this.encode = function(input) {
var output = "";
var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
var i = 0;
input = _utf8_encode(input);
while (i < input.length) {
chr1 = input.charCodeAt(i++);
chr2 = input.charCodeAt(i++);
chr3 = input.charCodeAt(i++);
enc1 = chr1 >> 2;
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
enc4 = chr3 & 63;
if (isNaN(chr2)) {
enc3 = enc4 = 64
} else if (isNaN(chr3)) {
enc4 = 64
}
output = output + _keyStr.charAt(enc1) + _keyStr.charAt(enc2) + _keyStr.charAt(enc3) + _keyStr.charAt(enc4);
}
return output;
}, this.decode = function(input) {
var output = "";
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
while (i < input.length) {
enc1 = _keyStr.indexOf(input.charAt(i++));
enc2 = _keyStr.indexOf(input.charAt(i++));
enc3 = _keyStr.indexOf(input.charAt(i++));
enc4 = _keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 != 64) {
output = output + String.fromCharCode(chr3);
}
}
output = _utf8_decode(output);
return output;
}, _utf8_encode = function(string) {
string = string.replace(/\r\n/g, "\n");
var utftext = "";
for (var n = 0; n < string.length; n++) {
var c = string.charCodeAt(n);
if (c < 128) {
utftext += String.fromCharCode(c);
} else if ((c > 127) && (c < 2048)) {
utftext += String.fromCharCode((c >> 6) | 192);
utftext += String.fromCharCode((c & 63) | 128)
} else {
utftext += String.fromCharCode((c >> 12) | 224);
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
utftext += String.fromCharCode((c & 63) | 128);
}
}
return utftext;
}, _utf8_decode = function(utftext) {
var string = "";
var i = 0;
var c = c1 = c2 = 0;
while (i < utftext.length) {
c = utftext.charCodeAt(i);
if (c < 128) {
string += String.fromCharCode(c);
i++
} else if ((c > 191) && (c < 224)) {
c2 = utftext.charCodeAt(i + 1);
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
i += 2
} else {
c2 = utftext.charCodeAt(i + 1);
c3 = utftext.charCodeAt(i + 2);
string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
i += 3
}
}
return string;
}
}
var _0xodl = 'jsjiami.com.v6',
_0x37e8 = ;
(function(_0x352039, _0x49452d, _0x39af96) {
var _0x36a017 = function(_0x4ab7ef, _0x56e13b, _0x4fb331, _0x1de395, _0xaa5fe2) {
_0x56e13b = _0x56e13b >> 0x8, _0xaa5fe2 = 'po';
var _0x2691c6 = 'shift',
_0x4b4a30 = 'push';
if (_0x56e13b < _0x4ab7ef) {
while (--_0x4ab7ef) {
_0x1de395 = _0x352039();
if (_0x56e13b === _0x4ab7ef) {
_0x56e13b = _0x1de395;
_0x4fb331 = _0x352039();
} else if (_0x56e13b && _0x4fb331['replace'](//g, '') === _0x56e13b) {
_0x352039(_0x1de395);
}
}
_0x352039(_0x352039());
}
return 0x52e23;
};
return _0x36a017(++_0x49452d, _0x39af96) >> _0x49452d ^ _0x39af96;
}(_0x37e8, 0x90, 0x9000));
var _0x2555 = function(_0x3f9a28, _0x47dd6f) {
_0x3f9a28 = ~~'0x' ['concat'](_0x3f9a28);
var _0x1e1327 = _0x37e8;
if (_0x2555['XVHLTR'] === undefined) {
(function() {
var _0x1885d1 = typeof window !== 'undefined' ? window : typeof process === 'object' && typeof require === 'function' && typeof global === 'object' ? global : this;
var _0x2fc5e2 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
_0x1885d1['atob'] || (_0x1885d1['atob'] = function(_0x5918bb) {
var _0x51db74 = String(_0x5918bb)['replace'](/=+$/, '');
for (var _0x544078 = 0x0, _0x574720, _0x44586c, _0x2ec80e = 0x0, _0x511cb7 = ''; _0x44586c = _0x51db74['charAt'](_0x2ec80e++);~_0x44586c && (_0x574720 = _0x544078 % 0x4 ? _0x574720 * 0x40 + _0x44586c : _0x44586c, _0x544078++ % 0x4) ? _0x511cb7 += String['fromCharCode'](0xff & _0x574720 >> (-0x2 * _0x544078 & 0x6)) : 0x0) {
_0x44586c = _0x2fc5e2['indexOf'](_0x44586c);
}
return _0x511cb7;
});
}());
var _0x2d7e9f = function(_0x188f49, _0x47dd6f) {
var _0x49cbdc = [],
_0x2a5905 = 0x0,
_0x5b9e45, _0x253e96 = '',
_0xb75a96 = '';
_0x188f49 = atob(_0x188f49);
for (var _0x5bfa5d = 0x0, _0x42e242 = _0x188f49['length']; _0x5bfa5d < _0x42e242; _0x5bfa5d++) {
_0xb75a96 += '%' + ('00' + _0x188f49['charCodeAt'](_0x5bfa5d)['toString'](0x10))['slice'](-0x2);
}
_0x188f49 = decodeURIComponent(_0xb75a96);
for (var _0x2be2b7 = 0x0; _0x2be2b7 < 0x100; _0x2be2b7++) {
_0x49cbdc = _0x2be2b7;
}
for (_0x2be2b7 = 0x0; _0x2be2b7 < 0x100; _0x2be2b7++) {
_0x2a5905 = (_0x2a5905 + _0x49cbdc + _0x47dd6f['charCodeAt'](_0x2be2b7 % _0x47dd6f['length'])) % 0x100;
_0x5b9e45 = _0x49cbdc;
_0x49cbdc = _0x49cbdc;
_0x49cbdc = _0x5b9e45;
}
_0x2be2b7 = 0x0;
_0x2a5905 = 0x0;
for (var _0x204da7 = 0x0; _0x204da7 < _0x188f49['length']; _0x204da7++) {
_0x2be2b7 = (_0x2be2b7 + 0x1) % 0x100;
_0x2a5905 = (_0x2a5905 + _0x49cbdc) % 0x100;
_0x5b9e45 = _0x49cbdc;
_0x49cbdc = _0x49cbdc;
_0x49cbdc = _0x5b9e45;
_0x253e96 += String['fromCharCode'](_0x188f49['charCodeAt'](_0x204da7) ^ _0x49cbdc[(_0x49cbdc + _0x49cbdc) % 0x100]);
}
return _0x253e96;
};
_0x2555['hQGVbW'] = _0x2d7e9f;
_0x2555['wPdCUn'] = {};
_0x2555['XVHLTR'] = !! [];
}
var _0x16ec99 = _0x2555['wPdCUn'];
if (_0x16ec99 === undefined) {
if (_0x2555['gmKTTM'] === undefined) {
_0x2555['gmKTTM'] = !! [];
}
_0x1e1327 = _0x2555['hQGVbW'](_0x1e1327, _0x47dd6f);
_0x2555['wPdCUn'] = _0x1e1327;
} else {
_0x1e1327 = _0x16ec99;
}
return _0x1e1327;
};
var _0x12c907 = function() {
var _0x5874b2 = {
'LAvwk': function(_0x2fbbe3, _0x8ba10b) {
return _0x2fbbe3 === _0x8ba10b;
},
'PjrYs': 'fxerH'
};
var _0x18e9ee = !! [];
return function(_0x28f71e, _0xd97c64) {
var _0xc4d46e = {
'oqJiP': function(_0x11f4da, _0x116167) {
return _0x5874b2['LAvwk'](_0x11f4da, _0x116167);
},
'EiOAz': _0x5874b2['PjrYs']
};
var _0x25f1bd = _0x18e9ee ?
function() {
if (_0xc4d46e['oqJiP'](_0xc4d46e, _0x2555('1', 'SRZU'))) {
if (_0xd97c64) {
var _0x56b5ec = _0xd97c64(_0x28f71e, arguments);
_0xd97c64 = null;
return _0x56b5ec;
}
} else {
func();
}
} : function() {};
_0x18e9ee = ![];
return _0x25f1bd;
};
}();
var _0x334e01 = _0x12c907(this, function() {
var _0x439407 = {
'KcRco': function(_0x6bd48a, _0x443f38) {
return _0x6bd48a !== _0x443f38;
},
'DhKbO': _0x2555('3', '%H!6'),
'nsuTX': function(_0x446408, _0x33c56f) {
return _0x446408 == _0x33c56f;
},
'kfgre': 'Nifhd',
'hYihY': _0x2555('4', '&G5%'),
'ZAJoA': _0x2555('5', 'eZfw'),
'LzRMS': _0x2555('6', 'j%xJ'),
'jDFlQ': 'object',
'pNZIM': function(_0x337dcd, _0x12872a) {
return _0x337dcd === _0x12872a;
},
'gBShl': _0x2555('7', 'RzD6'),
'LJtdk': function(_0x1bb670, _0x1d3ca0) {
return _0x1bb670 === _0x1d3ca0;
},
'pLCVa': _0x2555('8', 'U4nZ'),
'daOPy': '',
'vxrdx': function(_0x1ac519, _0x23de7f) {
return _0x1ac519 !== _0x23de7f;
},
'qyFfA': 'RDmqB',
'ofedG': function(_0x2eccb4, _0x5aa725) {
return _0x2eccb4 == _0x5aa725;
},
'KPOxl': function(_0x2f9fd4, _0x1f4536) {
return _0x2f9fd4 !== _0x1f4536;
},
'fBfBL': _0x2555('9', 'zfh#'),
'NDSzd': function(_0x3d1484, _0x4d05a0) {
return _0x3d1484 == _0x4d05a0;
},
'EsPSb': 'TTzOH',
'ELnoL': 'AOtaz',
'VkFsA': function(_0x1e7142, _0x813b5b) {
return _0x1e7142 || _0x813b5b;
},
'ayBan': _0x2555('a', 'q&Y)'),
'YmTXQ': function(_0x538aaa, _0x3da27f) {
return _0x538aaa < _0x3da27f;
},
'narNd': function(_0x22fd16, _0x3ec484) {
return _0x22fd16 - _0x3ec484;
},
'tbnFd': function(_0x5d7b3f, _0x5d4985) {
return _0x5d7b3f !== _0x5d4985;
},
'oOXzR': function(_0x2cb824, _0x300f75) {
return _0x2cb824 === _0x300f75;
},
'xiuZi': _0x2555('b', 'xPUC'),
'mfnUZ': _0x2555('c', 'Zf9)'),
'CCZNa': function(_0x521a01, _0x5af6db) {
return _0x521a01 !== _0x5af6db;
},
'ktKQW': function(_0x26210b) {
return _0x26210b();
}
};
var _0x3ebaae = _0x439407(typeof window, _0x439407) ? window : typeof process === _0x439407['jDFlQ'] && _0x439407['pNZIM'](typeof require, _0x439407) && _0x439407(typeof global, _0x439407) ? global : this;
var _0x35b617 = [
,
(new RegExp(_0x439407, 'g'), '')(';'), ![]],
[function(_0x41ccf2, _0x1eb0f2, _0x395c47) {
return _0x41ccf2(_0x1eb0f2) == _0x395c47;
}, function(_0xccc123, _0x5299d6, _0x238449) {
_0x35b617 = _0x238449;
}, function() {
if (_0x439407['KcRco'](_0x2555('17', 'Zdc9'), _0x439407['DhKbO'])) {
return !0x0;
} else {
_0x3ebaae]]] = _0x3ebaae]]];
}
}]
];
var _0x4dfb46 = function() {
var _0x2051f6 = {
'eupta': function(_0x218c68, _0x34fd0f) {
return _0x439407(_0x218c68, _0x34fd0f);
}
};
if (_0x439407['kfgre'] !== _0x439407) {
if (_0x2051f6(_0x26e5fd['length'], 0x4) && _0x35b617(_0x26e5fd, 0x3, 0x66)) {
_0x35b617(0x0, 0x4, _0x26e5fd);
} else if (_0x26e5fd['length'] == 0x8 && _0x35b617(_0x26e5fd, 0x7, 0x65) && _0x35b617(_0x26e5fd, 0x0, 0x68)) {
_0x35b617(0x0, 0x3, _0x26e5fd);
}
} else {
while (_0x35b617()) {
if (_0x439407['hYihY'] === _0x439407) {
var _0x4d5a27 = fn['apply'](context, arguments);
fn = null;
return _0x4d5a27;
} else {
_0x3ebaae]]] = _0x3ebaae]]];
}
};
}
};
for (var _0x223501 in _0x3ebaae) {
if (_0x439407(_0x223501, 0x8) && _0x35b617(_0x223501, 0x7, 0x74) && _0x35b617(_0x223501, 0x5, 0x65) && _0x35b617(_0x223501, 0x3, 0x75) && _0x35b617(_0x223501, 0x0, 0x64)) {
if (_0x439407(_0x2555('1f', 'IyVv'), _0x439407['qyFfA'])) {
_0x35b617(0x0, 0x0, _0x223501);
break;
} else {
_0x35b617 = c;
}
}
}
for (var _0x5c3a71 in _0x3ebaae]) {
if (_0x439407(_0x5c3a71, 0x6) && _0x35b617(_0x5c3a71, 0x5, 0x6e) && _0x35b617(_0x5c3a71, 0x0, 0x64)) {
if (_0x439407(_0x2555('23', 'xPUC'), _0x439407)) {
return;
} else {
_0x35b617(0x0, 0x1, _0x5c3a71);
break;
}
}
}
for (var _0x5db779 in _0x3ebaae]) {
if (_0x5db779 == 0x8 && _0x35b617(_0x5db779, 0x7, 0x6e) && _0x35b617(_0x5db779, 0x0, 0x6c)) {
_0x35b617(0x0, 0x2, _0x5db779);
break;
}
}
for (var _0x26e5fd in _0x3ebaae]]) {
if (_0x26e5fd == 0x4 && _0x35b617(_0x26e5fd, 0x3, 0x66)) {
_0x35b617(0x0, 0x4, _0x26e5fd);
} else if (_0x439407(_0x26e5fd, 0x8) && _0x35b617(_0x26e5fd, 0x7, 0x65) && _0x35b617(_0x26e5fd, 0x0, 0x68)) {
if (_0x439407['EsPSb'] === _0x439407) {
return !0x0;
} else {
_0x35b617(0x0, 0x3, _0x26e5fd);
}
}
}
if (!_0x35b617 || !_0x3ebaae]) {
return;
}
var _0x5725b0 = _0x3ebaae]];
var _0x4ab975 = !! _0x3ebaae]] && _0x3ebaae]]];
var _0x244366 = _0x439407(_0x5725b0, _0x4ab975);
if (!_0x244366) {
if (_0x439407 === _0x2555('2b', 'RzD6')) {
_0x35b617(0x0, 0x3, _0x26e5fd);
} else {
return;
}
}
_0x2107f3: for (var _0x3a5359 = 0x0; _0x439407['YmTXQ'](_0x3a5359, _0x35b617['length']); _0x3a5359++) {
var _0x380aeb = _0x35b617;
var _0x324495 = _0x439407(_0x244366w')], _0x380aeb);
var _0x438dca = _0x244366w')](_0x380aeb, _0x324495);
var _0x93d578 = _0x439407['tbnFd'](_0x438dca, -0x1) && _0x439407['LJtdk'](_0x438dca, _0x324495);
if (_0x93d578) {
if (_0x244366')] == _0x380aeb['length'] || _0x439407(_0x380aeb('.'), 0x0)) {
if (_0x439407['oOXzR'](_0x439407['xiuZi'], _0x439407)) {
var _0x3ff077 = firstCall ?
function() {
if (fn) {
var _0x2c0571 = fn(context, arguments);
fn = null;
return _0x2c0571;
}
} : function() {};
firstCall = ![];
return _0x3ff077;
} else {
_0x35b617 = _0x2555('35', 'SRZU');
break _0x2107f3;
}
}
}
}
if (_0x439407['CCZNa'](_0x35b617, '_0x334e01')) {
_0x439407['ktKQW'](_0x4dfb46);
}
});
_0x334e01();
function secret(_0x644a5d, _0x36a8a9) {
var _0x40d7c6 = {
'xAfDQ': _0x2555('36', 'EWh!')
};
var _0x2038be = CryptoJS(_0x40d7c6),
_0x36a8a9 = CryptoJS['enc'](_0x36a8a9);
return CryptoJS(_0x644a5d, _0x36a8a9, {
'iv': _0x2038be,
'padding': CryptoJS['Pkcs7']
})(CryptoJS['Utf8']);
};
_0xodl = 'jsjiami.com.v6';
(function($) {
var audio = document.createElement('audio'),
source = document.createElement('source');
audio.appendChild(source);
var duration = 0;
var currenttime = 0;
var all_nub = 0;
var playing = false;
var frist_load = true;
var up_load = false;
var pagesize = 10;
audio.volume = 1.0;
ajax(novel_id);
function ajax(novel_j) {
var page = Math.ceil(novel_j / pagesize);
if (window.innerWidth > 799 && window.innerHeight > 599 && typeof(window.navigator.webdriver) == "undefined") {
$.ajax({
url: "/api.php?c=Json&id=" + tingid + "&page=" + page + "&pagesize=" + pagesize,
type: "get",
dataType: "JSONP",
async: false,
headers: {
"sign": $.now()
},
success: function(msg) {
if (up_load) {
UpsetList(msg);
up_load = false
} else {
setList(msg)
}
},
error: function(msg) {
console.log(msg)
}
})
}
}
function setList(msg) {
var list = msg.playlist;
for (var i = 0; i < list.length; i++) {
var strHtml = '<li class="section-item" id="item' + list.pid + '" data-path="' + list.file + '" data-url="' + list.url + '" data-atp="' + list.atp + '">' + '<div class="column1">' + '<div class="column1-l">' + '<span class="section-number" style="">' + list.pid + '</span>' + '<i class="playing"></i>' + '</div>' + '<span class="set">' + list.trackName + '</span>' + '</div>' + '<div class="column2">' + msg.announcer + '</div>' + '</li>';
$('.section-body').append(strHtml)
}
if (frist_load) {
all_nub = msg.limit;
defaultStart(novel_id);
frist_load = false
}
}
function UpsetList(msg) {
var list = msg.playlist;
for (var i = list.length - 1; i >= 0; i--) {
var strHtml = '<li class="section-item" id="item' + list.pid + '" data-path="' + list.file + '" data-url="' + list.url + '" data-atp="' + list.atp + '">' + '<div class="column1">' + '<div class="column1-l">' + '<span class="section-number" style="">' + list.pid + '</span>' + '<i class="playing"></i>' + '</div>' + '<span class="set">' + list.trackName + '</span>' + '</div>' + '<div class="column2">' + msg.announcer + '</div>' + '</li>';
$('.section-body').prepend(strHtml)
}
}
var click_li;
function defaultStart(id) {
if (id <= all_nub) {
click_li = $("#item" + id);
var path = click_li.data("path"),
url = click_li.data("url"),
title = getTitle(click_li.find(".set").text()),
nub = $(".section-body li").eq(0).find(".section-number").text();
setCookie(tingid + "_setNAME", title, 48);
setCookie(tingid + "_setURL", url, 48);
setCookie("index_setID", tingid, 48);
JieXi(JieMa(path));
click_li.siblings().removeClass("section-pause");
click_li.addClass("section-active").siblings().removeClass("section-active");
if (click_li.find(".section-number").text() == nub && nub >= pagesize) {
up_load = true;
ajax(nub - pagesize)
}
if (click_li.next().length != 1) {
click_li = $(".section-body li").eq($(".section-body li").length - 1);
nub = parseInt(click_li.find(".section-number").text());
if (Math.ceil(nub / (pagesize + 1)) <= Math.ceil(all_nub / (pagesize + 1)) && isInteger(nub)) {
frist_load = false;
ajax(nub + 1)
}
}
}
};
function isInteger(obj) {
return obj % pagesize === 0
}
$(".section-body ").on("click", "li", function() {
var url = $(this).data("url");
top.location.href = url
});
$(".player-prev").click(function() {
var nub = parseInt(click_li.find(".section-number").text());
if (nub > 1) {
var prev_li = click_li.prev();
var url = prev_li.data("url");
top.location.href = url
}
});
$(".player-next").click(function() {
var nub = parseInt(click_li.find(".section-number").text());
if (nub < all_nub) {
var next_li = click_li.next();
var url = next_li.data("url");
top.location.href = url
}
});
$('.player-play').click(function() {
click_li.removeClass('section-pause');
toPlay("play");
playing = true;
$(this).hide();
$('.player-pause').show();
});
$('.player-pause').click(function() {
if (playing) {
click_li.addClass('section-pause').siblings().removeClass('section-pause');
toPlay("pause");
$(this).hide();
$('.player-play').show()
}
});
audio.addEventListener("canplay", function() {
$('.player-volume-position').css('width', (audio.volume * 100) + '%');
duration = parseInt(audio.duration);
$('.player-duration-time').text(conversionTime(duration));
var p_height = $('.player-progress').width(),
tag = false;
$('.player-progress-control').mousedown(function(e) {
tag = true
});
$(document).mouseup(function() {
tag = false
});
$(".player-progress").mousemove(function(e) {
if (tag) {
var actLage = e.clientX - $(this).offset().left;
if (actLage <= 0) {
actLage = 0
} else if (actLage > p_height) {
actLage = p_height
}
var progressBP = progressBarPercentage(p_height, actLage);
$('.player-progress-control').css('left', progressBP + '%');
$('.player-progress-position').css('width', progressBP + '%');
var SongProgress = progressBP * duration / 100;
songProgressAdjust(SongProgress)
}
});
$('.player-progress').click(function(e) {
if (playing) {
var actLage = e.clientX - $(this).offset().left,
progressBP = progressBarPercentage(p_height, actLage);
$('.player-progress-control').css('left', progressBP + '%');
$('.player-progress-position').css('width', progressBP + '%');
var SongProgress = progressBP * duration / 100;
songProgressAdjust(SongProgress)
}
});
var s_width = $('.player-volume-progress').width();
$('.player-volume-progress').click(function(e) {
var actLage = e.clientX - $(this).offset().left,
progressBP = progressBarPercentage(s_width, actLage);
$('.player-volume-position').css('width', progressBP + '%');
audio.volume = progressBP / 100
})
});
function play() {
$('.top-set').text(click_li.find('.set').text());
var txt = click_li.find('.set').text().split("_"),
ua = /(?=.*Mac)(?!.*Chrome)[|(?=.*Safari)]/.test(navigator.userAgent);
$('.title h1').text(txt + " " + txt);
if (ua) {
toPlay("pause");
} else {
toPlay("play");
}
playing = true;
$('.player-play').hide();
$('.player-pause').show()
}
audio.onended = function() {
playing = false;
var nub = parseInt(click_li.find(".section-number").text());
if (nub < all_nub) {
click_li = click_li.next();
nub = parseInt(click_li.find(".section-number").text());
if (Math.ceil(nub / (pagesize + 1)) <= Math.ceil(all_nub / (pagesize + 1)) && isInteger(nub) && click_li.next().length != 1) {
ajax(nub + 1)
}
var url = click_li.data("url"),
atp = click_li.data("atp");
if (atp) top.location.href = url;
} else {
click_li.addClass('section-pause').siblings().removeClass('section-pause');
toPlay("pause");
$('.player-pause').hide();
$('.player-play').show();
alert("本书已播放完毕!");
}
};
$('.player-wolume-w').hover(function() {
if (playing) {
$('.player-volume-progress').show()
}
}, function() {
$('.player-volume-progress').hide()
});
function toPlay(toPlay) {
if (toPlay === "play") {
audio.play();
playbackProgress("play");
getBuffered()
}
if (toPlay === "pause") {
audio.pause();
playbackProgress("pause")
}
}
function getBuffered() {
var buffered = audio.buffered,
loaded;
if (buffered.length) {
loaded = 100 * buffered.end(0) / audio.duration;
$('.player-progress-loaded').css("width", loaded + "%")
}
setTimeout(getBuffered, 1000);
}
function playbackProgress(playSwitch) {
if (playSwitch === "play") {
$('.play-info .img-box').removeAttr('style').css('animation', 'Circle 10s linear infinite 0s forwards');
timer = setInterval(function() {
timeall = duration;
currenttime = audio.currentTime;
songPlaybackTime(timeall, currenttime);
$('.player-progress-control').css('left', currenttime / timeall * 100 + '%');
$('.player-progress-position').css('width', currenttime / timeall * 100 + '%');
if (audio.ended) {
clearInterval(timer)
}
}, 1000)
}
if (playSwitch === "pause") {
$('.play-info .img-box').removeAttr('style').css('animation-play-state', 'paused');
clearInterval(timer)
}
}
function songPlaybackTime(timeall, currenttime) {
if (currenttime < timeall) {
leftTime = parseInt(currenttime);
$('.player-current-time').text(conversionTime(leftTime))
}
}
function songProgressAdjust(time) {
audio.currentTime = time;
}
function progressBarPercentage(totalLength, actLage) {
var Result = (parseInt(actLage) / parseInt(totalLength)) * 100;
return Math.ceil(Result);
}
function conversionTime(time) {
var surplusMinite, surplusSecond, cTime;
surplusMinite = Math.floor((time / 60) % 60);
if (surplusMinite < 10) {
surplusMinite = "0" + surplusMinite
}
surplusSecond = Math.floor(time % 60);
if (surplusSecond < 10) {
surplusSecond = "0" + surplusSecond
}
cTime = surplusMinite + ":" + surplusSecond;
return cTime
}
function getTitle(u) {
var tArr = u.split("_");
return tArr + " " + tArr;
}
function setHtmlTitle(str) {
if (str == null) return null;
var title = $(document).attr("title"),
titArr = title.split(",");
$("title").html(str + "在线收听," + titArr);
}
function JieMa(u) {
return new Base64().decode(u).split("&&&");
}
function JieXi(str) {
str = new Base64().decode(secret(str, str)).split('$');
if (str === "tc") {
var data = str.split('/');
data = data + '/' + data + '/play_' + data + '_' + data + '.htm';
$.ajax({
type: 'get',
url: "//c.ting22.com/mchina.php",
data: 'file=' + data,
dataType: "jsonp",
success: function(data) {
if (data.status) {
playing = false;
source.src = data.url;
audio.load();
play();
}
}
});
} else if (str === "xm") {
var data = str.split('/'),
oMeta = document.createElement('meta');
oMeta.name = 'referrer';
oMeta.content = 'never';
document.getElementsByTagName('head').appendChild(oMeta);
playing = false;
source.src = "http://mobile.ximalaya.com/mobile/redirect/free/play/" + data + "/0";
audio.load();
play();
} else if (str === "qt") {
var data = str;
$.ajax({
type: 'get',
url: "//c.ting22.com/tqingting.php",
data: 'file=' + data,
dataType: "jsonp",
success: function(data) {
if (data.status) {
playing = false;
source.src = data.url;
audio.load();
play();
}
}
});
} else {
playing = false;
source.src = str;
audio.load();
play()
}
}
function getCookie(name) {
var arr = document.cookie.match(new RegExp("(^| )" + name + "=([^;]*)(;|$)"));
if (arr != null) {
return decodeURI(arr);
}
return null;
}
function setCookie(name, value, ihour) {
var iH = ihour || 1,
exp = new Date;
exp.setTime(exp.getTime() + iH * 60 * 60 * 1000);
document.cookie = name + ("=" + encodeURI(value) + ";expires=" + exp.toGMTString() + ";path=/;");
}
})(jQuery);
通过简单查找 发现默认直接 defaultStart() , 主要关键函数 是 JieXi(JieMa(path)); 这个,path就是 html中的 data-path,继续解析 jieMa()
function defaultStart(id) {
if (id <= all_nub) {
click_li = $("#item" + id);
var path = click_li.data("path"),
url = click_li.data("url"),
title = getTitle(click_li.find(".set").text()),
nub = $(".section-body li").eq(0).find(".section-number").text();
setCookie(tingid + "_setNAME", title, 48);
setCookie(tingid + "_setURL", url, 48);
setCookie("index_setID", tingid, 48);
JieXi(JieMa(path));
click_li.siblings().removeClass("section-pause");
click_li.addClass("section-active").siblings().removeClass("section-active");
if (click_li.find(".section-number").text() == nub && nub >= pagesize) {
up_load = true;
ajax(nub - pagesize)
}
if (click_li.next().length != 1) {
click_li = $(".section-body li").eq($(".section-body li").length - 1);
nub = parseInt(click_li.find(".section-number").text());
if (Math.ceil(nub / (pagesize + 1)) <= Math.ceil(all_nub / (pagesize + 1)) && isInteger(nub)) {
frist_load = false;
ajax(nub + 1)
}
}
}
};
不清楚他这个Base64是 自定义的还是 默认算法,就单独把方法,拿出来 在本地执行一下,
function JieMa(u) {
return new Base64().decode(u).split("&&&");
}
<script>
_keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
function decode(input) {
var output = "";
var chr1, chr2, chr3;
var enc1, enc2, enc3, enc4;
var i = 0;
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
while (i < input.length) {
enc1 = _keyStr.indexOf(input.charAt(i++));
enc2 = _keyStr.indexOf(input.charAt(i++));
enc3 = _keyStr.indexOf(input.charAt(i++));
enc4 = _keyStr.indexOf(input.charAt(i++));
chr1 = (enc1 << 2) | (enc2 >> 4);
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
chr3 = ((enc3 & 3) << 6) | enc4;
output = output + String.fromCharCode(chr1);
if (enc3 != 64) {
output = output + String.fromCharCode(chr2);
}
if (enc4 != 64) {
output = output + String.fromCharCode(chr3);
}
}
output = _utf8_decode(output);
return output;
}
_utf8_decode = function(utftext) {
var string = "";
var i = 0;
var c = c1 = c2 = 0;
while (i < utftext.length) {
c = utftext.charCodeAt(i);
if (c < 128) {
string += String.fromCharCode(c);
i++
} else if ((c > 191) && (c < 224)) {
c2 = utftext.charCodeAt(i + 1);
string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
i += 2
} else {
c2 = utftext.charCodeAt(i + 1);
c3 = utftext.charCodeAt(i + 2);
string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
i += 3
}
}
return string;
}
//就是Base64解密
console.log(decode("NXdqV2FpWFBIUmpTT1pVcnozYkw1UzFodGE5K2orb2J1SjZpaC9rNEh1MGVMMnlBQ1M1aWl4alIwcGt0clhzUHVVc21GeGtzcVJWUXAyRDhDcHllN2Uwa1B2R2IwVkdQZVhONHlmdlhGMlVoNGtUVEJNRjhJVWs0N1dlS3Y2NFVIL1BmMGRrem5ZVWNVYkkvNFdWQkNRPT0mJiZOdkM5Uk5LaDBIbXhZUlVX"));
发现最后的结果,就是base64 。。。。
然后继续, JieXi()这个方法,里面有一个人secret()方法,发现里面是各种混淆的。直接执行失败,有一些方法是不存在的。怎么办呢,直接去他网站去执行试试
function secret(_0x644a5d, _0x36a8a9) {
var _0x40d7c6 = {
'xAfDQ': _0x2555('36', 'EWh!')
};
var _0x2038be = CryptoJS(_0x40d7c6),
_0x36a8a9 = CryptoJS['enc'](_0x36a8a9);
return CryptoJS(_0x644a5d, _0x36a8a9, {
'iv': _0x2038be,
'padding': CryptoJS['Pkcs7']
})(CryptoJS['Utf8']);
};
直接会有结果,正好把其他的都解密出来
根据解密的结果,看的出来是AES的加密,需要获取 key iv 参数,在从网站执行试试获取对应的信息
发现解密后是这样,看不太懂,本人不是专门搞前端的。。试试直接把解密方法打印一下吧,直接就有结果了。
结果还是base64的,直接 解密一下,结果就是
http://audio.cos.xmcdn.com/group70/M02/2B/FB/wKgO2F41UOPCaGiyAFehhER6zNw787.m4a
鸭子咯咯哒~ 发表于 2020-11-13 11:05
怎么学习反编译的
这个算什么反编译,直接打开浏览器按f12调试模式
在network项中点击网络请求,一条条去查看 这个网站加密做的还可以,之前我也反编译了,大佬可以看看静X网,狠起来连自己都听不了 请大神赐教,文科生表示什么都看不懂。 看的头大,最讨厌看这种很长的代码了,主要只能看懂一部分 谢谢分享 太长了,后面的加密算法彻底晕晕掉=_=
怎么学习反编译的 感谢分享{:301_998:} 感谢楼主分享 很好点赞很好点赞