最近有空在處理視頻去水印的需求,通過(guò)觀察調(diào)試和github資料最終成功完成??視頻的無(wú)水印視頻鏈接。本次分享一下逆向過(guò)程。
經(jīng)過(guò)比對(duì),某音、某條、某??前端加密、混淆技術(shù)基本相似,同時(shí)他們都是使用的xgplayer,基本上很多某音視頻、某條視頻鏈接都可以轉(zhuǎn)成??視頻鏈接(經(jīng)過(guò)我測(cè)試的很多都能轉(zhuǎn),目前還沒(méi)著重處理這塊兒,后期有機(jī)會(huì)穩(wěn)定了再分享)。
JSVMP 全稱 Virtual Machine based code Protection for JavaScript,即 JS 代碼虛擬化保護(hù)方案。
JSVMP 的概念最早應(yīng)該是由西北大學(xué)2015級(jí)碩士研究生匡開圓,在其2018年的學(xué)位論文中提出的,論文標(biāo)題為:《基于 WebAssembly 的 JavaScript 代碼虛擬化保護(hù)方法研究與實(shí)現(xiàn)》,同年還申請(qǐng)了國(guó)家專利,專利名稱:《一種基于前端字節(jié)碼技術(shù)的 JavaScript 虛擬化保護(hù)方法》,網(wǎng)上可以直接搜到。
我們?cè)L問(wèn)一個(gè)??視頻url,進(jìn)入后,開啟開發(fā)者工具,然后清空l(shuí)ocalstoreage、cookie等。
接著在url上復(fù)制詳情ID,如下圖的框框里的7440408860818407948。然后,打開網(wǎng)絡(luò),我們需要過(guò)濾出所有7440408860818407948相關(guān)的請(qǐng)求,因此就在過(guò)濾那里輸入7440408860818407948(具體的ID)。在接著,就刷新網(wǎng)頁(yè)。
在下面的圖里,我全出了3個(gè)相關(guān)的請(qǐng)求,從這3個(gè)請(qǐng)求,我們能看到__ac_signature、__ac_nonce等??參數(shù)生成的情況。因此我一個(gè)個(gè)來(lái)分析。
第一個(gè)請(qǐng)求,會(huì)得到__ac_nonce
,這個(gè)值會(huì)在響應(yīng)的cookie拿到,同時(shí)這個(gè)請(qǐng)求得到的是虛擬代碼$_jsvmprt
和調(diào)用sign生成__ac_nonce
,下面第一張圖可以看到返回了兩段腳本代碼。
第一個(gè)腳本就是虛擬化代碼。因?yàn)樘摂M化技術(shù),因此核心的sign 的操作的對(duì)象、函數(shù)代碼都被隱藏了。
第二個(gè)腳本就是調(diào)用sign,我們來(lái)美化代碼看下:
<script>
function _f1(e, t) {
if ("string" != typeof t) return;
var o, n = e + "=",
r = t.split(/[;&]/);
for (var e = 0; e < r.length; e++) {
for (o = r[e];
" " === o.charAt(0);) o = o.substring(1, o.length);
if (0 === o.indexOf(n)) return o.substring(n.length, o.length)
}
return ""
}
function _f2(e) {
return _f1(e, document.cookie)
}
function _f3(e, t, o) {
try {
o && (window.sessionStorage && window.sessionStorage.setItem(e, t), window.localStorage && window.localStorage.setItem(e, t));
var n = 31536e6;
document.cookie = e + "=; expires=Mon, 20 Sep 1970 00:00:00 UTC; path=/;" + (window.location.protocol == 'https:' ? 'SameSite=None; Secure;' : ''), document.cookie = e + "=" + t + "; expires=" + new Date((new Date).getTime() + n).toGMTString() + "; path=/;" + (window.location.protocol == 'https:' ? 'SameSite=None; Secure;' : '')
} catch (e) { }
}
window.byted_acrawler.init({
aid: 99999999,
dfp: 0
});
var __ac_nonce = _f2("__ac_nonce");
var __ac_signature = window.byted_acrawler.sign("", __ac_nonce);
_f3("__ac_signature", __ac_signature);
_f3("__ac_referer", document.referrer || "__ac_blank", !0);
try {
sessionStorage.setItem("__ac_ns", performance.timing.navigationStart)
} catch (e) { }
window.location.reload()
</script>
這段代碼window.byted_acrawler
就是核心的對(duì)象,從存儲(chǔ)中取出隨機(jī)字符串,然后作為簽名的第2個(gè)參數(shù),接著將簽名存儲(chǔ),最后刷新,就開始第二次請(qǐng)求
瀏覽器調(diào)試截圖:
第二個(gè)請(qǐng)求就是ttwid相關(guān)邏輯了,這個(gè)請(qǐng)求會(huì)攜帶第一個(gè)請(qǐng)求最后存儲(chǔ)的__ac_nonce
和__ac_signature
,接著響應(yīng)得到ttwid關(guān)聯(lián)的幾個(gè)cookie,以及下面的內(nèi)容代碼
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="utf-8" />
<link rel="shortcut icon" >
</head>
<body>
<script nonce="bfe55e58540f4e80ac63d499a935c2b9">
var startTime = Date.now()
</script>
<script nonce="bfe55e58540f4e80ac63d499a935c2b9">
;(function (w, d, u, b, n, pc, ga, ae, po, s, p, e, t, pp) {pc = 'precollect';ga
= 'getAttribute';ae = 'addEventListener';po = 'PerformanceObserver';s = function
(m) {p = [].slice.call(arguments);p.push(Date.now(), location.href);(m == pc ?
s.p.a : s.q).push(p)};s.q = [];s.p = { a: [] };w[n] = s;e =
document.createElement('script');e.src = u + '?bid=' + b + '&globalName=' +
n;e.crossOrigin = u.indexOf('sdk-web') > 0 ? 'anonymous' :
'use-credentials';d.getElementsByTagName('head')[0].appendChild(e);if (ae in w)
{s.pcErr = function (e) {e = e || w.event;t = e.target || e.srcElement;if (t
instanceof Element || t instanceof HTMLElement) {if (t[ga]('integrity'))
{w[n](pc, 'sri', t[ga]('href') || t[ga]('src'))} else {w[n](pc, 'st', { tagName:
t.tagName, url: t[ga]('href') || t[ga]('src') })}} else {w[n](pc, 'err', e.error
|| e.message)}};s.pcRej = function (e) {e = e || w.event;w[n](pc, 'err',
e.reason || (e.detail && e.detail.reason))};w[ae]('error', s.pcErr,
true);w[ae]('unhandledrejection', s.pcRej,
true);};if('PerformanceLongTaskTiming' in w) {pp = s.pp = { entries: []
};pp.observer = new PerformanceObserver(function (l) {pp.entries =
pp.entries.concat(l.getEntries())});pp.observer.observe({ entryTypes:
['longtask', 'largest-contentful-paint','layout-shift']
})}})(window,document,'https://lf3-short.ibytedapm.com/slardar/fe/sdk-web/browser.cn.js','xigua_video_web_pc','Slardar') </script>
<script defer nonce="bfe55e58540f4e80ac63d499a935c2b9" src="https://privacy.zijieapi.com/api/web-cmp/sdk/?project_key=b443652e7ef8089c"></script>
<script src="https://unpkg.byted-static.com/byted-ucenter/ttwid-js/1.0.1/dist/index.umd.production.js" nonce="bfe55e58540f4e80ac63d499a935c2b9"></script>
<script defer src="https://lf-c-flwb.bytetos.com/obj/rc-client-security/c-webmssdk/1.0.0.15/webmssdk.js"
nonce="bfe55e58540f4e80ac63d499a935c2b9"></script>
<script src="https://lf-cdn-tos.bytescm.com/obj/static/secsdk/secsdk-lastest.umd.js"
nonce="bfe55e58540f4e80ac63d499a935c2b9"></script>
<script nonce="bfe55e58540f4e80ac63d499a935c2b9">
secsdk.csrf.setProtectedHost({
'www.ixigua.com': {
'GET': '*',
'POST': '*',
"TOKEN_PATH": "/api/",
},
});
</script>
<script nonce="bfe55e58540f4e80ac63d499a935c2b9">
var retryTimes = 0
var maxRetryTimes = 2
var instance = null
try {
window.Slardar('init', {
bid: 'xigua_video_web_pc',
pid: 'ttwid'
})
window.Slardar('start')
window.Slardar('sendEvent', {
name: "ttwid-pv",
metrics: { count: 1 },
})
init()
} catch (err) {
ttwidInitError()
reloadPage()
}
function insertParamAndReload(key, value) {
var kvp = document.location.search ? document.location.search.substr(1).split('&') : [];
var i = 0;
// 替換已有的
for (; i < kvp.length; i++) {
if (new RegExp('^' + key + '=').test(kvp[i])) {
var pair = kvp[i].split('=');
pair[1] = value;
kvp[i] = pair.join('=');
break;
}
}
// 新增
if (i >= kvp.length) {
kvp[kvp.length] = [key, value].join('=');
}
var params = kvp.join('&');
document.location.search = params;
}
function init() {
setRealReferrer()
if (!instance) {
instance = new window.TTWidInstance({
region: undefined,
aid: 1768,
needFid: false,
service: window.location.host,
migrate_info: {"ticket":"","source":"node"},
cbUrlProtocol: window.location.protocol.slice(0, -1)
})
}
instance.registerUnionWebId({}, function(registerError, cbResponse){
var callbackError = !cbResponse || cbResponse.status_code !== 0
if (registerError || callbackError) {
if (retryTimes < maxRetryTimes) {
retryTimes ++
init()
return
}
ttwidRegisterError()
} else {
window.Slardar('sendEvent', {
name: "ttwid-success",
metrics: { count: 1 },
})
}
reloadPage()
})
}
function reloadPage() {
reportDuration()
insertParamAndReload('wid_try','1')
}
// 記錄正確的referrer, 優(yōu)先取風(fēng)控中間頁(yè)記錄的值
function setRealReferrer() {
var __AC_REFERER = '__ac_referer'
var acReferrer = window.sessionStorage.getItem(__AC_REFERER)
var realReferrer = acReferrer != null ? acReferrer : document.referrer
window.sessionStorage.setItem(__AC_REFERER, realReferrer || '__ac_blank')
}
function setTmpCookie() {
var maxAge = 60 * 60 * 24
document.cookie = 'ttwid_date=1; max-age=' + maxAge
}
function ttwidInitError() {
setTmpCookie()
window.Slardar('sendEvent', {
name: "ttwidInit-error",
metrics: { count: 1 },
})
}
function ttwidRegisterError() {
setTmpCookie()
window.Slardar('sendEvent', {
name: 'ttwidRegister-error',
metrics: { count: 1 },
})
}
function reportDuration() {
window.Slardar('sendEvent', {
name: 'ttwid-duration',
metrics: { count: Date.now() - startTime },
})
}
</script>
</body>
</html>
借用ai分析下上面代碼的過(guò)程,主要涉及到錯(cuò)誤處理、性能監(jiān)控和頁(yè)面初始化。以下是對(duì)該腳本的業(yè)務(wù)流程的分析:
初始化Slardar監(jiān)控:
Slardar
監(jiān)控工具。PerformanceObserver
監(jiān)控長(zhǎng)任務(wù)、最大內(nèi)容繪制和布局偏移。錯(cuò)誤處理:
error
和unhandledrejection
事件。Slardar
的precollect
方法記錄錯(cuò)誤信息。初始化TTWid實(shí)例:
init
函數(shù)用于初始化TTWidInstance
。ttwidInitError
記錄錯(cuò)誤并重載頁(yè)面。TTWidInstance
注冊(cè)成功后,發(fā)送ttwid-success
事件;否則,重試注冊(cè),最多重試兩次。頁(yè)面重載和參數(shù)插入:
reloadPage
函數(shù)用于在錯(cuò)誤或成功后重載頁(yè)面。insertParamAndReload
函數(shù)用于在URL中插入或更新參數(shù)。設(shè)置真實(shí)的referrer:
setRealReferrer
函數(shù)用于設(shè)置真實(shí)的referrer
,優(yōu)先使用風(fēng)控中間頁(yè)記錄的值。臨時(shí)Cookie設(shè)置:
setTmpCookie
函數(shù)用于設(shè)置一個(gè)臨時(shí)的Cookie,可能用于標(biāo)記錯(cuò)誤狀態(tài)。錯(cuò)誤事件記錄:
ttwidInitError
和ttwidRegisterError
函數(shù)用于記錄初始化和注冊(cè)過(guò)程中的錯(cuò)誤。性能報(bào)告:
reportDuration
函數(shù)用于記錄從頁(yè)面加載到當(dāng)前時(shí)間的持續(xù)時(shí)間。這個(gè)腳本的主要目的是通過(guò)Slardar
工具監(jiān)控頁(yè)面性能和錯(cuò)誤,并通過(guò)TTWidInstance
進(jìn)行某種身份驗(yàn)證或注冊(cè)操作。錯(cuò)誤處理和重試機(jī)制確保在失敗時(shí)能夠進(jìn)行適當(dāng)?shù)幕謴?fù)和記錄。
因此也引出了我們的第三個(gè)請(qǐng)求。
第三個(gè)請(qǐng)求是核心逆向的請(qǐng)求。這個(gè)請(qǐng)求最后的鏈接:https://www.ixigua.com/7440408860818407948?logTag=a226ed00791b3c5fd17f&wid_try=1
,logTag
不用關(guān)心,wid_try
是重要的參數(shù),因?yàn)橛兴覀兡軓捻憫?yīng)內(nèi)容里面得到window.getSSRHydratedData
這個(gè)函數(shù)(在響應(yīng)內(nèi)容可找到)。同時(shí),這個(gè)請(qǐng)求也會(huì)在響應(yīng)cookie 得到xiguavideopcwebid
相關(guān)的參數(shù)。更重要的是,這個(gè)請(qǐng)求也生成了整個(gè)頁(yè)面了。
最后一個(gè)環(huán)節(jié),我們通過(guò)開源node補(bǔ)環(huán)境框架在終端環(huán)境得到__ac_signture
,下面也推薦兩個(gè)框架
git地址:https://github.com/bnmgh1/node-sandbox
function?test_vm()?{
????const?sandbox?=?{
????????wanfeng:?wanfeng,
????????globalMy:?globalMy,
????????console:?console,
????}
????let?workCode?=?fs.readFileSync("./work/ac_sign.js");
????a?=?+new?Date;
????var?callCode?=?`window.byted_acrawler.init({
????????aid:?99999999,
????????dfp:?0
????});
????var?__ac_nonce?=?"06639eaa4009ab37b9a75";
????var?__ac_signature?=?window.byted_acrawler.sign("",__ac_nonce);
????console.log("__ac_signature:?",?__ac_signature)`;
????var?code?=?"debugger;\r\n"?+?globalMy_js?+?init_env?+?envCode?+?"\r\n"?+?workCode?+?"\r\n"?+?endCode?+?callCode;
????vm.runInNewContext(code,?sandbox);
????console.log("運(yùn)行環(huán)境Js?+?工作Js?耗時(shí):",?+new?Date?-?a,?"毫秒");
}
test_vm();
git地址:https://github.com/ylw00/qxVm
const fs = require('fs');
const QXVM_GENERATE = require('../qxVm_sanbox/qxVm.sanbox');
function ReadCode(name, dir) {
let file_path = dir === undefined ? `${__dirname}/${name}` : `${__dirname}/${dir}/${name}`;
return fs.readFileSync(file_path) + "\r\n"
}
const js_code = ReadCode(`./ac_sign.js`);
const user_config = {
isTest: false,
runConfig: {
proxy: true,
logOpen: true
},
window_attribute: {},
env: {
navigator: {
userAgent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36"
},
location: {
href: "https://www.ixigua.com/"
},
document: {
referrer: "https://www.ixigua.com/",
cookie: ''
}
}
}
let window = QXVM_GENERATE.sanbox(js_code, "byted_acrawler", user_config, false);
const ac_nonce = "06757b48300510d8954c7"
let ac_sign = window.byted_acrawler.sign("", ac_nonce)
console.log("__ac_nonce:", ac_nonce)
console.log("__ac_signature:", ac_sign)
在附上ac_sign.js
,這個(gè)其實(shí)就是上面說(shuō)的虛擬化代碼,把請(qǐng)求中第一個(gè)script腳本復(fù)制粘貼下來(lái)就可以了。
var glb;(glb="undefined"==typeof window?global:window)._$jsvmprt=function(b,e,f){function a(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Date.prototype.toString.call(Reflect.construct(Date,[],(function(){}))),!0}catch(b){return!1}}function d(b,e,f){return(d=a()?Reflect.construct:function(b,e,f){var a=[null];a.push.apply(a,e);var d=new(Function.bind.apply(b,a));return f&&c(d,f.prototype),d}).apply(null,arguments)}function c(b,e){return(c=Object.setPrototypeOf||function(b,e){return b.__proto__=e,b})(b,e)}function n(b){return function(b){if(Array.isArray(b)){for(var e=0,f=new Array(b.length);e<b.length;e++)f[e]=b[e];return f}}(b)||function(b){if(Symbol.iterator in Object(b)||"[object Arguments]"===Object.prototype.toString.call(b))return Array.from(b)}(b)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance")}()}for(var i=[],r=0,t=[],o=0,l=function(b,e){var f=b[e++],a=b[e],d=parseInt(""+f+a,16);if(d>>7==0)return[1,d];if(d>>6==2){var c=parseInt(""+b[++e]+b[++e],16);return d&=63,[2,c=(d<<=8)+c]}if(d>>6==3){var n=parseInt(""+b[++e]+b[++e],16),i=parseInt(""+b[++e]+b[++e],16);return d&=63,[3,i=(d<<=16)+(n<<=8)+i]}},u=function(b,e){var f=parseInt(""+b[e]+b[e+1],16);return f=f>127?-256+f:f},s=function(b,e){var f=parseInt(""+b[e]+b[e+1]+b[e+2]+b[e+3],16);return f=f>32767?-65536+f:f},p=function(b,e){var f=parseInt(""+b[e]+b[e+1]+b[e+2]+b[e+3]+b[e+4]+b[e+5]+b[e+6]+b[e+7],16);return f=f>2147483647?0+f:f},y=function(b,e){return parseInt(""+b[e]+b[e+1],16)},v=function(b,e){return parseInt(""+b[e]+b[e+1]+b[e+2]+b[e+3],16)},g=g||this||window,h=Object.keys||function(b){var e={},f=0;for(var a in b)e[f++]=a;return e.length=f,e},m=(b.length,0),I="",C=m;C<m+16;C++){var q=""+b[C++]+b[C];q=parseInt(q,16),I+=String.fromCharCode(q)}if("HNOJ@?RC"!=I)throw new Error("error magic number "+I);m+=16;parseInt(""+b[m]+b[m+1],16);m+=8,r=0;for(var w=0;w<4;w++){var S=m+2*w,R=""+b[S++]+b[S],x=parseInt(R,16);r+=(3&x)<<2*w}m+=16,m+=8;var z=parseInt(""+b[m]+b[m+1]+b[m+2]+b[m+3]+b[m+4]+b[m+5]+b[m+6]+b[m+7],16),O=z,E=m+=8,j=v(b,m+=z);j[1];m+=4,i={p:[],q:[]};for(var A=0;A<j;A++){for(var D=l(b,m),T=m+=2*D[0],$=i.p.length,P=0;P<D[1];P++){var U=l(b,T);i.p.push(U[1]),T+=2*U[0]}m=T,i.q.push([$,i.p.length])}var _={5:1,6:1,70:1,22:1,23:1,37:1,73:1},k={72:1},M={74:1},H={11:1,12:1,24:1,26:1,27:1,31:1},J={10:1},N={2:1,29:1,30:1,20:1},B=[],W=[];function F(b,e,f){for(var a=e;a<e+f;){var d=y(b,a);B[a]=d,a+=2;k[d]?(W[a]=u(b,a),a+=2):_[d]?(W[a]=s(b,a),a+=4):M[d]?(W[a]=p(b,a),a+=8):H[d]?(W[a]=y(b,a),a+=2):J[d]?(W[a]=v(b,a),a+=4):N[d]&&(W[a]=v(b,a),a+=4)}}return K(b,E,O/2,[],e,f);function G(b,e,f,a,c,l,m,I){null==l&&(l=this);var C,q,w,S=[],R=0;m&&(C=m);var x,z,O=e,E=O+2*f;if(!I)for(;O<E;){var j=parseInt(""+b[O]+b[O+1],16);O+=2;var A=3&(x=13*j%241);if(x>>=2,A<1){A=3&x;if(x>>=2,A>2)(A=x)>10?S[++R]=void 0:A>1?(C=S[R--],S[R]=S[R]>=C):A>-1&&(S[++R]=null);else if(A>1){if((A=x)>11)throw S[R--];if(A>7){for(C=S[R--],z=v(b,O),A="",P=i.q[z][0];P<i.q[z][1];P++)A+=String.fromCharCode(r^i.p[P]);O+=4,S[R--][A]=C}else A>5&&(S[R]=h(S[R]))}else if(A>0){(A=x)>8?(C=S[R--],S[R]=typeof C):A>6?S[R]=--S[R]:A>4?S[R-=1]=S[R][S[R+1]]:A>2&&(q=S[R--],(A=S[R]).x===G?A.y>=1?S[R]=K(b,A.c,A.l,[q],A.z,w,null,1):(S[R]=K(b,A.c,A.l,[q],A.z,w,null,0),A.y++):S[R]=A(q))}else{if((A=x)>14)z=s(b,O),(U=function e(){var f=arguments;return e.y>0?K(b,e.c,e.l,f,e.z,this,null,0):(e.y++,K(b,e.c,e.l,f,e.z,this,null,0))}).c=O+4,U.l=z-2,U.x=G,U.y=0,U.z=c,S[R]=U,O+=2*z-2;else if(A>12)q=S[R--],w=S[R--],(A=S[R--]).x===G?A.y>=1?S[++R]=K(b,A.c,A.l,q,A.z,w,null,1):(S[++R]=K(b,A.c,A.l,q,A.z,w,null,0),A.y++):S[++R]=A.apply(w,q);else if(A>5)C=S[R--],S[R]=S[R]!=C;else if(A>3)C=S[R--],S[R]=S[R]*C;else if(A>-1)return[1,S[R--]]}}else if(A<2){A=3&x;if(x>>=2,A<1){if((A=x)>9);else if(A>7)C=S[R--],S[R]=S[R]&C;else if(A>5)z=y(b,O),O+=2,S[R-=z]=0===z?new S[R]:d(S[R],n(S.slice(R+1,R+z+1)));else if(A>3){z=s(b,O);try{if(t[o][2]=1,1==(C=G(b,O+4,z-3,[],c,l,null,0))[0])return C}catch(m){if(t[o]&&t[o][1]&&1==(C=G(b,t[o][1][0],t[o][1][1],[],c,l,m,0))[0])return C}finally{if(t[o]&&t[o][0]&&1==(C=G(b,t[o][0][0],t[o][0][1],[],c,l,null,0))[0])return C;t[o]=0,o--}O+=2*z-2}}else if(A<2){if((A=x)>12)S[++R]=u(b,O),O+=2;else if(A>10)C=S[R--],S[R]=S[R]<<C;else if(A>8){for(z=v(b,O),A="",P=i.q[z][0];P<i.q[z][1];P++)A+=String.fromCharCode(r^i.p[P]);O+=4,S[R]=S[R][A]}else A>6&&(q=S[R--],C=delete S[R--][q])}else if(A<3){(A=x)<2?S[++R]=C:A<4?(C=S[R--],S[R]=S[R]<=C):A<11?(C=S[R-=2][S[R+1]]=S[R+2],R--):A<13&&(C=S[R],S[++R]=C)}else{if((A=x)>12)S[++R]=l;else if(A>5)C=S[R--],S[R]=S[R]!==C;else if(A>3)C=S[R--],S[R]=S[R]/C;else if(A>1){if((z=s(b,O))<0){I=1,F(b,e,2*f),O+=2*z-2;break}O+=2*z-2}else A>-1&&(S[R]=!S[R])}}else if(A<3){A=3&x;if(x>>=2,A>2)(A=x)>7?(C=S[R--],S[R]=S[R]|C):A>5?(z=y(b,O),O+=2,S[++R]=c["$"+z]):A>3&&(z=s(b,O),t[o][0]&&!t[o][2]?t[o][1]=[O+4,z-3]:t[o++]=[0,[O+4,z-3],0],O+=2*z-2);else if(A>1){if((A=x)<2){for(z=v(b,O),C="",P=i.q[z][0];P<i.q[z][1];P++)C+=String.fromCharCode(r^i.p[P]);S[++R]=C,O+=4}else if(A<4)if(S[R--])O+=4;else{if((z=s(b,O))<0){I=1,F(b,e,2*f),O+=2*z-2;break}O+=2*z-2}else A<6?(C=S[R--],S[R]=S[R]%C):A<8?(C=S[R--],S[R]=S[R]instanceof C):A<15&&(S[++R]=!1)}else if(A>0){(A=x)<1?S[++R]=g:A<3?(C=S[R--],S[R]=S[R]+C):A<5?(C=S[R--],S[R]=S[R]==C):A<14&&(C=S[R-1],q=S[R],S[++R]=C,S[++R]=q)}else{(A=x)<2?(C=S[R--],S[R]=S[R]>C):A<9?(z=v(b,O),O+=4,q=R+1,S[R-=z-1]=z?S.slice(R,q):[]):A<11?(z=y(b,O),O+=2,C=S[R--],c[z]=C):A<13?(C=S[R--],S[R]=S[R]>>C):A<15&&(S[++R]=s(b,O),O+=4)}}else{A=3&x;if(x>>=2,A>2)(A=x)>13?(S[++R]=p(b,O),O+=8):A>11?(C=S[R--],S[R]=S[R]>>>C):A>9?S[++R]=!0:A>7?(z=y(b,O),O+=2,S[R]=S[R][z]):A>0&&(C=S[R--],S[R]=S[R]<C);else if(A>1){(A=x)>10?(z=s(b,O),t[++o]=[[O+4,z-3],0,0],O+=2*z-2):A>8?(C=S[R--],S[R]=S[R]^C):A>6&&(C=S[R--])}else if(A>0){if((A=x)<3){var D=0,T=S[R].length,$=S[R];S[++R]=function(){var b=D<T;if(b){var e=$[D++];S[++R]=e}S[++R]=b}}else A<5?(z=y(b,O),O+=2,C=c[z],S[++R]=C):A<7?S[R]=++S[R]:A<9&&(C=S[R--],S[R]=S[R]in C)}else{if((A=x)>13)C=S[R],S[R]=S[R-1],S[R-1]=C;else if(A>4)C=S[R--],S[R]=S[R]===C;else if(A>2)C=S[R--],S[R]=S[R]-C;else if(A>0){for(z=v(b,O),A="",P=i.q[z][0];P<i.q[z][1];P++)A+=String.fromCharCode(r^i.p[P]);A=+A,O+=4,S[++R]=A}}}}if(I)for(;O<E;){j=B[O];O+=2;A=3&(x=13*j%241);if(x>>=2,A<1){var U;A=3&x;if(x>>=2,A<1){if((A=x)>14)z=W[O],(U=function e(){var f=arguments;return e.y>0?K(b,e.c,e.l,f,e.z,this,null,0):(e.y++,K(b,e.c,e.l,f,e.z,this,null,0))}).c=O+4,U.l=z-2,U.x=G,U.y=0,U.z=c,S[R]=U,O+=2*z-2;else if(A>12)q=S[R--],w=S[R--],(A=S[R--]).x===G?A.y>=1?S[++R]=K(b,A.c,A.l,q,A.z,w,null,1):(S[++R]=K(b,A.c,A.l,q,A.z,w,null,0),A.y++):S[++R]=A.apply(w,q);else if(A>5)C=S[R--],S[R]=S[R]!=C;else if(A>3)C=S[R--],S[R]=S[R]*C;else if(A>-1)return[1,S[R--]]}else if(A<2){(A=x)<4?(q=S[R--],(A=S[R]).x===G?A.y>=1?S[R]=K(b,A.c,A.l,[q],A.z,w,null,1):(S[R]=K(b,A.c,A.l,[q],A.z,w,null,0),A.y++):S[R]=A(q)):A<6?S[R-=1]=S[R][S[R+1]]:A<8?S[R]=--S[R]:A<10&&(C=S[R--],S[R]=typeof C)}else if(A<3){if((A=x)>11)throw S[R--];if(A>7){for(C=S[R--],z=W[O],A="",P=i.q[z][0];P<i.q[z][1];P++)A+=String.fromCharCode(r^i.p[P]);O+=4,S[R--][A]=C}else A>5&&(S[R]=h(S[R]))}else{(A=x)<1?S[++R]=null:A<3?(C=S[R--],S[R]=S[R]>=C):A<12&&(S[++R]=void 0)}}else if(A<2){A=3&x;if(x>>=2,A>2)(A=x)>12?S[++R]=l:A>5?(C=S[R--],S[R]=S[R]!==C):A>3?(C=S[R--],S[R]=S[R]/C):A>1?O+=2*(z=W[O])-2:A>-1&&(S[R]=!S[R]);else if(A>1){(A=x)<2?S[++R]=C:A<4?(C=S[R--],S[R]=S[R]<=C):A<11?(C=S[R-=2][S[R+1]]=S[R+2],R--):A<13&&(C=S[R],S[++R]=C)}else if(A>0){if((A=x)<8)q=S[R--],C=delete S[R--][q];else if(A<10){for(z=W[O],A="",P=i.q[z][0];P<i.q[z][1];P++)A+=String.fromCharCode(r^i.p[P]);O+=4,S[R]=S[R][A]}else A<12?(C=S[R--],S[R]=S[R]<<C):A<14&&(S[++R]=W[O],O+=2)}else{if((A=x)<5){z=W[O];try{if(t[o][2]=1,1==(C=G(b,O+4,z-3,[],c,l,null,0))[0])return C}catch(m){if(t[o]&&t[o][1]&&1==(C=G(b,t[o][1][0],t[o][1][1],[],c,l,m,0))[0])return C}finally{if(t[o]&&t[o][0]&&1==(C=G(b,t[o][0][0],t[o][0][1],[],c,l,null,0))[0])return C;t[o]=0,o--}O+=2*z-2}else A<7?(z=W[O],O+=2,S[R-=z]=0===z?new S[R]:d(S[R],n(S.slice(R+1,R+z+1)))):A<9&&(C=S[R--],S[R]=S[R]&C)}}else if(A<3){A=3&x;if(x>>=2,A<1)(A=x)<2?(C=S[R--],S[R]=S[R]>C):A<9?(z=W[O],O+=4,q=R+1,S[R-=z-1]=z?S.slice(R,q):[]):A<11?(z=W[O],O+=2,C=S[R--],c[z]=C):A<13?(C=S[R--],S[R]=S[R]>>C):A<15&&(S[++R]=W[O],O+=4);else if(A<2){(A=x)<1?S[++R]=g:A<3?(C=S[R--],S[R]=S[R]+C):A<5?(C=S[R--],S[R]=S[R]==C):A<14&&(C=S[R-1],q=S[R],S[++R]=C,S[++R]=q)}else if(A<3){if((A=x)<2){for(z=W[O],C="",P=i.q[z][0];P<i.q[z][1];P++)C+=String.fromCharCode(r^i.p[P]);S[++R]=C,O+=4}else A<4?S[R--]?O+=4:O+=2*(z=W[O])-2:A<6?(C=S[R--],S[R]=S[R]%C):A<8?(C=S[R--],S[R]=S[R]instanceof C):A<15&&(S[++R]=!1)}else{(A=x)>7?(C=S[R--],S[R]=S[R]|C):A>5?(z=W[O],O+=2,S[++R]=c["$"+z]):A>3&&(z=W[O],t[o][0]&&!t[o][2]?t[o][1]=[O+4,z-3]:t[o++]=[0,[O+4,z-3],0],O+=2*z-2)}}else{A=3&x;if(x>>=2,A>2)(A=x)>13?(S[++R]=W[O],O+=8):A>11?(C=S[R--],S[R]=S[R]>>>C):A>9?S[++R]=!0:A>7?(z=W[O],O+=2,S[R]=S[R][z]):A>0&&(C=S[R--],S[R]=S[R]<C);else if(A>1){(A=x)>10?(z=W[O],t[++o]=[[O+4,z-3],0,0],O+=2*z-2):A>8?(C=S[R--],S[R]=S[R]^C):A>6&&(C=S[R--])}else if(A>0){if((A=x)>7)C=S[R--],S[R]=S[R]in C;else if(A>5)S[R]=++S[R];else if(A>3)z=W[O],O+=2,C=c[z],S[++R]=C;else if(A>1){D=0,T=S[R].length,$=S[R];S[++R]=function(){var b=D<T;if(b){var e=$[D++];S[++R]=e}S[++R]=b}}}else{if((A=x)<2){for(z=W[O],A="",P=i.q[z][0];P<i.q[z][1];P++)A+=String.fromCharCode(r^i.p[P]);A=+A,O+=4,S[++R]=A}else A<4?(C=S[R--],S[R]=S[R]-C):A<6?(C=S[R--],S[R]=S[R]===C):A<15&&(C=S[R],S[R]=S[R-1],S[R-1]=C)}}}return[0,null]}function K(b,e,f,a,d,c,n,i){var r,t;null==c&&(c=this),d&&!d.d&&(d.d=0,d.$0=d,d[1]={});var o={},l=o.d=d?d.d+1:0;for(o["$"+l]=o,t=0;t<l;t++)o[r="$"+t]=d[r];for(t=0,l=o.length=a.length;t<l;t++)o[t]=a[t];return i&&!B[e]&&F(b,e,2*f),B[e]?G(b,e,f,0,o,c,null,1)[1]:G(b,e,f,0,o,c,null,0)[1]}},(glb="undefined"==typeof window?global:window)._$jsvmprt("文章內(nèi)容字?jǐn)?shù)有限,這里刪除了虛擬字節(jié)碼",[,,"undefined"!=typeof exports?exports:void 0,"undefined"!=typeof module?module:void 0,"undefined"!=typeof define?define:void 0,"undefined"!=typeof Object?Object:void 0,void 0,"undefined"!=typeof TypeError?TypeError:void 0,"undefined"!=typeof document?document:void 0,"undefined"!=typeof InstallTrigger?InstallTrigger:void 0,"undefined"!=typeof safari?safari:void 0,"undefined"!=typeof Date?Date:void 0,"undefined"!=typeof Math?Math:void 0,"undefined"!=typeof navigator?navigator:void 0,"undefined"!=typeof location?location:void 0,"undefined"!=typeof history?history:void 0,"undefined"!=typeof Image?Image:void 0,"undefined"!=typeof console?console:void 0,"undefined"!=typeof PluginArray?PluginArray:void 0,"undefined"!=typeof indexedDB?indexedDB:void 0,"undefined"!=typeof DOMException?DOMException:void 0,"undefined"!=typeof parseInt?parseInt:void 0,"undefined"!=typeof String?String:void 0,"undefined"!=typeof Array?Array:void 0,"undefined"!=typeof Error?Error:void 0,"undefined"!=typeof JSON?JSON:void 0,"undefined"!=typeof Promise?Promise:void 0,"undefined"!=typeof WebSocket?WebSocket:void 0,"undefined"!=typeof eval?eval:void 0,"undefined"!=typeof setTimeout?setTimeout:void 0,"undefined"!=typeof encodeURIComponent?encodeURIComponent:void 0,"undefined"!=typeof encodeURI?encodeURI:void 0,"undefined"!=typeof Request?Request:void 0,"undefined"!=typeof Headers?Headers:void 0,"undefined"!=typeof decodeURIComponent?decodeURIComponent:void 0,"undefined"!=typeof RegExp?RegExp:void 0]);
這個(gè)項(xiàng)目是抽空做的,項(xiàng)目地址: short-video-parse, 目前還不完善,有空就會(huì)更新,喜歡可以star、fork、和交流。
實(shí)際測(cè)試中,目前看來(lái)__ac_nonce
和 __ac_signature
可以直接瀏覽器獲取直接作為固定值用于請(qǐng)求中,但是也不能保證后期變化。最后,分享就到這了,以后有機(jī)會(huì)再來(lái)。
??