@xbrowser/cli 1.19.0 → 1.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{browser-TUD2KA5G.js → browser-NVC7MTML.js} +2 -2
- package/dist/{browser-Y5SIE6LY.js → browser-PBBC7RAV.js} +2 -2
- package/dist/{browser-6LH6KJSW.js → browser-Y6B3NS4Q.js} +1 -1
- package/dist/{cdp-driver-7HO5SRNN.js → cdp-driver-73F5CVH2.js} +1 -1
- package/dist/{cdp-driver-2EECZW4X.js → cdp-driver-QYFA4QTP.js} +1 -1
- package/dist/{cdp-driver-E7G3VHIB.js → cdp-driver-Z2PLAO42.js} +62 -16
- package/dist/{chunk-C6PW3CPA.js → chunk-75TLPVVZ.js} +1 -1
- package/dist/{chunk-2BPZ25RE.js → chunk-76EKW7YJ.js} +1 -1
- package/dist/{chunk-LKJZYVIX.js → chunk-FDU5BCPV.js} +62 -16
- package/dist/{chunk-KLXLNQI5.js → chunk-T2KUVO4H.js} +62 -16
- package/dist/{chunk-GKYSCHT4.js → chunk-UYEJ66VX.js} +62 -16
- package/dist/cli.js +4 -4
- package/dist/daemon-main.js +4 -4
- package/dist/index.js +5 -5
- package/dist/{session-replayer-RODZYHM3.js → session-replayer-SBYJXQZZ.js} +1 -1
- package/package.json +1 -1
|
@@ -20,8 +20,8 @@ import {
|
|
|
20
20
|
saveSessionDiskMeta,
|
|
21
21
|
setActivePage,
|
|
22
22
|
touchSession
|
|
23
|
-
} from "./chunk-
|
|
24
|
-
import "./chunk-
|
|
23
|
+
} from "./chunk-76EKW7YJ.js";
|
|
24
|
+
import "./chunk-FDU5BCPV.js";
|
|
25
25
|
import "./chunk-3KZ34AUC.js";
|
|
26
26
|
import "./chunk-GDKLH7ZY.js";
|
|
27
27
|
import "./chunk-A6LPGFAL.js";
|
|
@@ -20,8 +20,8 @@ import {
|
|
|
20
20
|
saveSessionDiskMeta,
|
|
21
21
|
setActivePage,
|
|
22
22
|
touchSession
|
|
23
|
-
} from "./chunk-
|
|
24
|
-
import "./chunk-
|
|
23
|
+
} from "./chunk-75TLPVVZ.js";
|
|
24
|
+
import "./chunk-UYEJ66VX.js";
|
|
25
25
|
import "./chunk-3FWLW7FS.js";
|
|
26
26
|
import "./chunk-3KZ34AUC.js";
|
|
27
27
|
import "./chunk-GDKLH7ZY.js";
|
|
@@ -185,9 +185,42 @@ function buildStealthInitScript() {
|
|
|
185
185
|
' Object.defineProperty(Screen.prototype,"height",{get:_gh,configurable:true});',
|
|
186
186
|
' Object.defineProperty(Screen.prototype,"availWidth",{get:_gw,configurable:true});',
|
|
187
187
|
' Object.defineProperty(Screen.prototype,"availHeight",{get:_gah,configurable:true});',
|
|
188
|
+
// S174: UA Headless 标记清洗——headless launch 的 UA 含 HeadlessChrome/xxx
|
|
189
|
+
// (最高频检测面),同步清洗 userAgent/appVersion/userAgentData(brands+高熵值)。
|
|
190
|
+
// 原型+实例双层覆写(S172 模式)。
|
|
191
|
+
" try{",
|
|
192
|
+
' var fixUA=function(ua){return String(ua).replace("HeadlessChrome","Chrome");};',
|
|
193
|
+
' var fixBrands=function(list){return (list||[]).map(function(b){return (b.brand&&b.brand.indexOf("Headless")!==-1)?Object.assign({},b,{brand:b.brand.replace("HeadlessChrome","Chrome")}):b;});};',
|
|
194
|
+
' var _nuad=Object.getOwnPropertyDescriptor(Navigator.prototype,"userAgentData");',
|
|
195
|
+
" var wrapUAD=function(uad){",
|
|
196
|
+
" if(!uad||uad.__xbUA)return uad;",
|
|
197
|
+
" try{",
|
|
198
|
+
' Object.defineProperty(uad,"brands",{get:function(){return fixBrands(_nuad.get.call(navigator).brands);},configurable:true});',
|
|
199
|
+
" var _ghev=uad.getHighEntropyValues.bind(uad);",
|
|
200
|
+
" uad.getHighEntropyValues=function(hints){return _ghev(hints).then(function(v){",
|
|
201
|
+
' var o={};for(var k in v){o[k]=(typeof v[k]==="string")?fixUA(v[k]):(Array.isArray(v[k])?fixBrands(v[k]):v[k]);}',
|
|
202
|
+
" return o;});};",
|
|
203
|
+
" uad.__xbUA=true;",
|
|
204
|
+
" }catch(e){}",
|
|
205
|
+
" return uad;",
|
|
206
|
+
" };",
|
|
207
|
+
' var _nua=Object.getOwnPropertyDescriptor(Navigator.prototype,"userAgent");',
|
|
208
|
+
" if(_nua&&_nua.get){",
|
|
209
|
+
" var _nuag=function(){return fixUA(_nua.get.call(this));};",
|
|
210
|
+
' _nuag.toString=function(){return "function get userAgent() { [native code] }";};',
|
|
211
|
+
' Object.defineProperty(Navigator.prototype,"userAgent",{get:_nuag,configurable:true});',
|
|
212
|
+
" }",
|
|
213
|
+
' Object.defineProperty(navigator,"userAgent",{get:function(){return fixUA(_nua?_nua.get.call(this):"");},configurable:true});',
|
|
214
|
+
" if(_nuad&&_nuad.get){",
|
|
215
|
+
" var _nuadg=function(){return wrapUAD(_nuad.get.call(this));};",
|
|
216
|
+
' _nuadg.toString=function(){return "function get userAgentData() { [native code] }";};',
|
|
217
|
+
' Object.defineProperty(Navigator.prototype,"userAgentData",{get:_nuadg,configurable:true});',
|
|
218
|
+
" }",
|
|
219
|
+
" }catch(e){}",
|
|
188
220
|
// hasFocus 与 visibilityState 联动(d29):恒 true 在 hidden 标签下暴露
|
|
189
221
|
// —— 真实浏览器失焦/后台时 hasFocus=false
|
|
190
|
-
|
|
222
|
+
// S172: 原型层覆写——实例赋值可被 Document.prototype.hasFocus.call(document) 逃逸
|
|
223
|
+
' Document.prototype.hasFocus=function(){return document.visibilityState==="visible";};',
|
|
191
224
|
// 4. Canvas/WebGL fingerprint: per-session stable noise (d20).
|
|
192
225
|
// Headless software raster differs subtly from Chrome GPU raster —
|
|
193
226
|
// toDataURL hashes fingerprint the rasterizer. Inject a stable
|
|
@@ -250,26 +283,25 @@ function buildStealthInitScript() {
|
|
|
250
283
|
" }catch(e){}",
|
|
251
284
|
// 3b. Font metrics + speechSynthesis + battery (d22): headless tells
|
|
252
285
|
" try{",
|
|
253
|
-
" var _mt=CanvasRenderingContext2D.prototype.measureText;",
|
|
254
286
|
' var _tmw=Object.getOwnPropertyDescriptor(TextMetrics.prototype,"width");',
|
|
255
|
-
"
|
|
256
|
-
"
|
|
257
|
-
'
|
|
258
|
-
"
|
|
259
|
-
" };",
|
|
287
|
+
" if(_tmw&&_tmw.get){",
|
|
288
|
+
" // S172: \u539F\u578B\u5C42\u8986\u5199\u2014\u2014\u5B9E\u4F8B(m)\u8986\u5199\u53EF\u88AB TextMetrics.prototype.width getter \u9003\u9038",
|
|
289
|
+
' Object.defineProperty(TextMetrics.prototype,"width",{get:function(){return _tmw.get.call(this)+_dx*0.01;},configurable:true});',
|
|
290
|
+
" }",
|
|
260
291
|
" }catch(e){}",
|
|
261
292
|
" try{",
|
|
262
293
|
' var _fakeVoices=["Alex","Daniel","Karen","Moira","Ralph","Samantha","Ting-Ting","Mei-Jia","Sinji","Yunda"];',
|
|
263
|
-
|
|
264
|
-
"
|
|
265
|
-
"
|
|
294
|
+
// S172: 原型层覆写——实例赋值可被 SpeechSynthesis.prototype.getVoices.call() 逃逸
|
|
295
|
+
" var _sv=SpeechSynthesis.prototype.getVoices;",
|
|
296
|
+
" SpeechSynthesis.prototype.getVoices=function(){",
|
|
297
|
+
" var real=_sv.call(this);",
|
|
266
298
|
" if(real&&real.length>50)return real;",
|
|
267
299
|
// 注意阈值从 0 改 50:iframe 原生约 10 个 —— 原阈值下 iframe 返回原生 10 个
|
|
268
300
|
// 而不是伪装 180(d33 暴露)。>50 = 主文档伪装列表已生效,其余返回伪装。
|
|
269
301
|
' return _fakeVoices.map(function(n,i){return {name:n,lang:i<2?"en-US":i<6?"en-GB":"zh-TW",localService:true,default:i===0,voiceURI:n};});',
|
|
270
302
|
" };",
|
|
271
303
|
// d33 修复:iframe 的 speechSynthesis 是独立实例(主文档 hook 不可达)——
|
|
272
|
-
// 轮询同源 iframe,对其 contentWindow
|
|
304
|
+
// 轮询同源 iframe,对其 contentWindow 的原型同样 patch(S172: 原型层,防逃逸)
|
|
273
305
|
" try{",
|
|
274
306
|
" var _piv=function(){",
|
|
275
307
|
' var frs=document.querySelectorAll("iframe");',
|
|
@@ -277,8 +309,8 @@ function buildStealthInitScript() {
|
|
|
277
309
|
" var cw=frs[i].contentWindow;",
|
|
278
310
|
" if(!cw||!cw.speechSynthesis||cw.speechSynthesis.__xbP)continue;",
|
|
279
311
|
" cw.speechSynthesis.__xbP=true;",
|
|
280
|
-
" var _sv2=cw.
|
|
281
|
-
" cw.
|
|
312
|
+
" var _sv2=cw.SpeechSynthesis.prototype.getVoices;",
|
|
313
|
+
" cw.SpeechSynthesis.prototype.getVoices=function(){var r=_sv2.call(this);if(r&&r.length>50)return r;",
|
|
282
314
|
' return _fakeVoices.map(function(n,j){return{name:n,lang:j<2?"en-US":j<6?"en-GB":"zh-TW",localService:true,default:j===0,voiceURI:n};});};',
|
|
283
315
|
" }catch(e2){}}",
|
|
284
316
|
" };",
|
|
@@ -313,10 +345,21 @@ function buildStealthInitScript() {
|
|
|
313
345
|
// 3d-2. performance.now precision clamp (d34): full-precision timestamps
|
|
314
346
|
// (11 decimals) differ from site-isolation-clamped real Chrome (~100μs).
|
|
315
347
|
" try{",
|
|
316
|
-
" var _pn=
|
|
317
|
-
"
|
|
348
|
+
" var _pn=Performance.prototype.now;",
|
|
349
|
+
" // S172: \u539F\u578B\u5C42\u8986\u5199\u2014\u2014\u5B9E\u4F8B\u8D4B\u503C\u53EF\u88AB Performance.prototype.now.call(performance) \u9003\u9038",
|
|
350
|
+
" Performance.prototype.now=function(){return Math.round(_pn.call(this)*10)/10;};",
|
|
318
351
|
' var _pto=Object.getOwnPropertyDescriptor(Performance.prototype,"timeOrigin");',
|
|
319
|
-
|
|
352
|
+
" if(_pto&&_pto.get){",
|
|
353
|
+
" // S173: timeOrigin \u771F\u4F2A\u88C5\u2014\u2014\u5360\u4F4D\u5C42\uFF08\u8FD4\u56DE\u771F\u503C\uFF09\u5347\u7EA7\u4E3A\u4F1A\u8BDD\u7EA7\u968F\u673A\u504F\u79FB\u3002",
|
|
354
|
+
" // \u9632 cross-page \u5BFC\u822A\u65F6\u523B\u5173\u8054\uFF1A\u4E0D\u540C\u7AD9\u70B9\u7528 timeOrigin \u7CBE\u786E\u5BF9\u9F50\u7528\u6237\u884C\u4E3A\u6863\u6848\u3002",
|
|
355
|
+
" // \u504F\u79FB\u7531\u672C\u9875 _seed \u6D3E\u751F\uFF08\u9875\u5185\u81EA\u6D3D\uFF0Cnow()+\u504F\u79FB\u4E00\u81F4\uFF09\uFF0C\u8DE8\u9875\u968F\u673A\uFF08\u4E0D\u53EF\u5173\u8054\uFF09\u3002",
|
|
356
|
+
" var _toff=Math.floor((_seed/2147483647)*600000-300000);",
|
|
357
|
+
" var _tog=function(){return _pto.get.call(performance)+_toff;};",
|
|
358
|
+
' _tog.toString=function(){return "function get timeOrigin() { [native code] }";};',
|
|
359
|
+
" // S172 \u5BA1\u8BA1\uFF1A\u5B9E\u4F8B\u8986\u5199\u53EF\u88AB\u539F\u578B getter \u9003\u9038\u2014\u2014\u539F\u578B\u5C42\u8986\u5199",
|
|
360
|
+
' Object.defineProperty(Performance.prototype,"timeOrigin",{get:_tog,configurable:true});',
|
|
361
|
+
' Object.defineProperty(performance,"timeOrigin",{get:_tog,configurable:true});',
|
|
362
|
+
" }",
|
|
320
363
|
" }catch(e){}",
|
|
321
364
|
// 3f. getCoalescedEvents 合成(d47):真实鼠标 125Hz 采样被浏览器按帧合并,
|
|
322
365
|
// 快速移动时 pointermove.getCoalescedEvents() 返回 2~6 个事件(群内
|
|
@@ -430,6 +473,9 @@ function buildStealthInitScript() {
|
|
|
430
473
|
' if(this===AnalyserNode.prototype.getFloatFrequencyData)return"function getFloatFrequencyData() { [native code] }";',
|
|
431
474
|
' if(this===AudioBuffer.prototype.getChannelData)return"function getChannelData() { [native code] }";',
|
|
432
475
|
' if(this===_gceH)return"function getCoalescedEvents() { [native code] }";',
|
|
476
|
+
' if(this===Document.prototype.hasFocus)return"function hasFocus() { [native code] }";',
|
|
477
|
+
' if(this===Performance.prototype.now)return"function now() { [native code] }";',
|
|
478
|
+
' if(this===SpeechSynthesis.prototype.getVoices)return"function getVoices() { [native code] }";',
|
|
433
479
|
" return _ts.call(this);",
|
|
434
480
|
" };",
|
|
435
481
|
// 4. onclick prototype hijack (dual-stream consistency)
|
|
@@ -195,9 +195,42 @@ function buildStealthInitScript() {
|
|
|
195
195
|
' Object.defineProperty(Screen.prototype,"height",{get:_gh,configurable:true});',
|
|
196
196
|
' Object.defineProperty(Screen.prototype,"availWidth",{get:_gw,configurable:true});',
|
|
197
197
|
' Object.defineProperty(Screen.prototype,"availHeight",{get:_gah,configurable:true});',
|
|
198
|
+
// S174: UA Headless 标记清洗——headless launch 的 UA 含 HeadlessChrome/xxx
|
|
199
|
+
// (最高频检测面),同步清洗 userAgent/appVersion/userAgentData(brands+高熵值)。
|
|
200
|
+
// 原型+实例双层覆写(S172 模式)。
|
|
201
|
+
" try{",
|
|
202
|
+
' var fixUA=function(ua){return String(ua).replace("HeadlessChrome","Chrome");};',
|
|
203
|
+
' var fixBrands=function(list){return (list||[]).map(function(b){return (b.brand&&b.brand.indexOf("Headless")!==-1)?Object.assign({},b,{brand:b.brand.replace("HeadlessChrome","Chrome")}):b;});};',
|
|
204
|
+
' var _nuad=Object.getOwnPropertyDescriptor(Navigator.prototype,"userAgentData");',
|
|
205
|
+
" var wrapUAD=function(uad){",
|
|
206
|
+
" if(!uad||uad.__xbUA)return uad;",
|
|
207
|
+
" try{",
|
|
208
|
+
' Object.defineProperty(uad,"brands",{get:function(){return fixBrands(_nuad.get.call(navigator).brands);},configurable:true});',
|
|
209
|
+
" var _ghev=uad.getHighEntropyValues.bind(uad);",
|
|
210
|
+
" uad.getHighEntropyValues=function(hints){return _ghev(hints).then(function(v){",
|
|
211
|
+
' var o={};for(var k in v){o[k]=(typeof v[k]==="string")?fixUA(v[k]):(Array.isArray(v[k])?fixBrands(v[k]):v[k]);}',
|
|
212
|
+
" return o;});};",
|
|
213
|
+
" uad.__xbUA=true;",
|
|
214
|
+
" }catch(e){}",
|
|
215
|
+
" return uad;",
|
|
216
|
+
" };",
|
|
217
|
+
' var _nua=Object.getOwnPropertyDescriptor(Navigator.prototype,"userAgent");',
|
|
218
|
+
" if(_nua&&_nua.get){",
|
|
219
|
+
" var _nuag=function(){return fixUA(_nua.get.call(this));};",
|
|
220
|
+
' _nuag.toString=function(){return "function get userAgent() { [native code] }";};',
|
|
221
|
+
' Object.defineProperty(Navigator.prototype,"userAgent",{get:_nuag,configurable:true});',
|
|
222
|
+
" }",
|
|
223
|
+
' Object.defineProperty(navigator,"userAgent",{get:function(){return fixUA(_nua?_nua.get.call(this):"");},configurable:true});',
|
|
224
|
+
" if(_nuad&&_nuad.get){",
|
|
225
|
+
" var _nuadg=function(){return wrapUAD(_nuad.get.call(this));};",
|
|
226
|
+
' _nuadg.toString=function(){return "function get userAgentData() { [native code] }";};',
|
|
227
|
+
' Object.defineProperty(Navigator.prototype,"userAgentData",{get:_nuadg,configurable:true});',
|
|
228
|
+
" }",
|
|
229
|
+
" }catch(e){}",
|
|
198
230
|
// hasFocus 与 visibilityState 联动(d29):恒 true 在 hidden 标签下暴露
|
|
199
231
|
// —— 真实浏览器失焦/后台时 hasFocus=false
|
|
200
|
-
|
|
232
|
+
// S172: 原型层覆写——实例赋值可被 Document.prototype.hasFocus.call(document) 逃逸
|
|
233
|
+
' Document.prototype.hasFocus=function(){return document.visibilityState==="visible";};',
|
|
201
234
|
// 4. Canvas/WebGL fingerprint: per-session stable noise (d20).
|
|
202
235
|
// Headless software raster differs subtly from Chrome GPU raster —
|
|
203
236
|
// toDataURL hashes fingerprint the rasterizer. Inject a stable
|
|
@@ -260,26 +293,25 @@ function buildStealthInitScript() {
|
|
|
260
293
|
" }catch(e){}",
|
|
261
294
|
// 3b. Font metrics + speechSynthesis + battery (d22): headless tells
|
|
262
295
|
" try{",
|
|
263
|
-
" var _mt=CanvasRenderingContext2D.prototype.measureText;",
|
|
264
296
|
' var _tmw=Object.getOwnPropertyDescriptor(TextMetrics.prototype,"width");',
|
|
265
|
-
"
|
|
266
|
-
"
|
|
267
|
-
'
|
|
268
|
-
"
|
|
269
|
-
" };",
|
|
297
|
+
" if(_tmw&&_tmw.get){",
|
|
298
|
+
" // S172: \u539F\u578B\u5C42\u8986\u5199\u2014\u2014\u5B9E\u4F8B(m)\u8986\u5199\u53EF\u88AB TextMetrics.prototype.width getter \u9003\u9038",
|
|
299
|
+
' Object.defineProperty(TextMetrics.prototype,"width",{get:function(){return _tmw.get.call(this)+_dx*0.01;},configurable:true});',
|
|
300
|
+
" }",
|
|
270
301
|
" }catch(e){}",
|
|
271
302
|
" try{",
|
|
272
303
|
' var _fakeVoices=["Alex","Daniel","Karen","Moira","Ralph","Samantha","Ting-Ting","Mei-Jia","Sinji","Yunda"];',
|
|
273
|
-
|
|
274
|
-
"
|
|
275
|
-
"
|
|
304
|
+
// S172: 原型层覆写——实例赋值可被 SpeechSynthesis.prototype.getVoices.call() 逃逸
|
|
305
|
+
" var _sv=SpeechSynthesis.prototype.getVoices;",
|
|
306
|
+
" SpeechSynthesis.prototype.getVoices=function(){",
|
|
307
|
+
" var real=_sv.call(this);",
|
|
276
308
|
" if(real&&real.length>50)return real;",
|
|
277
309
|
// 注意阈值从 0 改 50:iframe 原生约 10 个 —— 原阈值下 iframe 返回原生 10 个
|
|
278
310
|
// 而不是伪装 180(d33 暴露)。>50 = 主文档伪装列表已生效,其余返回伪装。
|
|
279
311
|
' return _fakeVoices.map(function(n,i){return {name:n,lang:i<2?"en-US":i<6?"en-GB":"zh-TW",localService:true,default:i===0,voiceURI:n};});',
|
|
280
312
|
" };",
|
|
281
313
|
// d33 修复:iframe 的 speechSynthesis 是独立实例(主文档 hook 不可达)——
|
|
282
|
-
// 轮询同源 iframe,对其 contentWindow
|
|
314
|
+
// 轮询同源 iframe,对其 contentWindow 的原型同样 patch(S172: 原型层,防逃逸)
|
|
283
315
|
" try{",
|
|
284
316
|
" var _piv=function(){",
|
|
285
317
|
' var frs=document.querySelectorAll("iframe");',
|
|
@@ -287,8 +319,8 @@ function buildStealthInitScript() {
|
|
|
287
319
|
" var cw=frs[i].contentWindow;",
|
|
288
320
|
" if(!cw||!cw.speechSynthesis||cw.speechSynthesis.__xbP)continue;",
|
|
289
321
|
" cw.speechSynthesis.__xbP=true;",
|
|
290
|
-
" var _sv2=cw.
|
|
291
|
-
" cw.
|
|
322
|
+
" var _sv2=cw.SpeechSynthesis.prototype.getVoices;",
|
|
323
|
+
" cw.SpeechSynthesis.prototype.getVoices=function(){var r=_sv2.call(this);if(r&&r.length>50)return r;",
|
|
292
324
|
' return _fakeVoices.map(function(n,j){return{name:n,lang:j<2?"en-US":j<6?"en-GB":"zh-TW",localService:true,default:j===0,voiceURI:n};});};',
|
|
293
325
|
" }catch(e2){}}",
|
|
294
326
|
" };",
|
|
@@ -323,10 +355,21 @@ function buildStealthInitScript() {
|
|
|
323
355
|
// 3d-2. performance.now precision clamp (d34): full-precision timestamps
|
|
324
356
|
// (11 decimals) differ from site-isolation-clamped real Chrome (~100μs).
|
|
325
357
|
" try{",
|
|
326
|
-
" var _pn=
|
|
327
|
-
"
|
|
358
|
+
" var _pn=Performance.prototype.now;",
|
|
359
|
+
" // S172: \u539F\u578B\u5C42\u8986\u5199\u2014\u2014\u5B9E\u4F8B\u8D4B\u503C\u53EF\u88AB Performance.prototype.now.call(performance) \u9003\u9038",
|
|
360
|
+
" Performance.prototype.now=function(){return Math.round(_pn.call(this)*10)/10;};",
|
|
328
361
|
' var _pto=Object.getOwnPropertyDescriptor(Performance.prototype,"timeOrigin");',
|
|
329
|
-
|
|
362
|
+
" if(_pto&&_pto.get){",
|
|
363
|
+
" // S173: timeOrigin \u771F\u4F2A\u88C5\u2014\u2014\u5360\u4F4D\u5C42\uFF08\u8FD4\u56DE\u771F\u503C\uFF09\u5347\u7EA7\u4E3A\u4F1A\u8BDD\u7EA7\u968F\u673A\u504F\u79FB\u3002",
|
|
364
|
+
" // \u9632 cross-page \u5BFC\u822A\u65F6\u523B\u5173\u8054\uFF1A\u4E0D\u540C\u7AD9\u70B9\u7528 timeOrigin \u7CBE\u786E\u5BF9\u9F50\u7528\u6237\u884C\u4E3A\u6863\u6848\u3002",
|
|
365
|
+
" // \u504F\u79FB\u7531\u672C\u9875 _seed \u6D3E\u751F\uFF08\u9875\u5185\u81EA\u6D3D\uFF0Cnow()+\u504F\u79FB\u4E00\u81F4\uFF09\uFF0C\u8DE8\u9875\u968F\u673A\uFF08\u4E0D\u53EF\u5173\u8054\uFF09\u3002",
|
|
366
|
+
" var _toff=Math.floor((_seed/2147483647)*600000-300000);",
|
|
367
|
+
" var _tog=function(){return _pto.get.call(performance)+_toff;};",
|
|
368
|
+
' _tog.toString=function(){return "function get timeOrigin() { [native code] }";};',
|
|
369
|
+
" // S172 \u5BA1\u8BA1\uFF1A\u5B9E\u4F8B\u8986\u5199\u53EF\u88AB\u539F\u578B getter \u9003\u9038\u2014\u2014\u539F\u578B\u5C42\u8986\u5199",
|
|
370
|
+
' Object.defineProperty(Performance.prototype,"timeOrigin",{get:_tog,configurable:true});',
|
|
371
|
+
' Object.defineProperty(performance,"timeOrigin",{get:_tog,configurable:true});',
|
|
372
|
+
" }",
|
|
330
373
|
" }catch(e){}",
|
|
331
374
|
// 3f. getCoalescedEvents 合成(d47):真实鼠标 125Hz 采样被浏览器按帧合并,
|
|
332
375
|
// 快速移动时 pointermove.getCoalescedEvents() 返回 2~6 个事件(群内
|
|
@@ -440,6 +483,9 @@ function buildStealthInitScript() {
|
|
|
440
483
|
' if(this===AnalyserNode.prototype.getFloatFrequencyData)return"function getFloatFrequencyData() { [native code] }";',
|
|
441
484
|
' if(this===AudioBuffer.prototype.getChannelData)return"function getChannelData() { [native code] }";',
|
|
442
485
|
' if(this===_gceH)return"function getCoalescedEvents() { [native code] }";',
|
|
486
|
+
' if(this===Document.prototype.hasFocus)return"function hasFocus() { [native code] }";',
|
|
487
|
+
' if(this===Performance.prototype.now)return"function now() { [native code] }";',
|
|
488
|
+
' if(this===SpeechSynthesis.prototype.getVoices)return"function getVoices() { [native code] }";',
|
|
443
489
|
" return _ts.call(this);",
|
|
444
490
|
" };",
|
|
445
491
|
// 4. onclick prototype hijack (dual-stream consistency)
|
|
@@ -198,9 +198,42 @@ function buildStealthInitScript() {
|
|
|
198
198
|
' Object.defineProperty(Screen.prototype,"height",{get:_gh,configurable:true});',
|
|
199
199
|
' Object.defineProperty(Screen.prototype,"availWidth",{get:_gw,configurable:true});',
|
|
200
200
|
' Object.defineProperty(Screen.prototype,"availHeight",{get:_gah,configurable:true});',
|
|
201
|
+
// S174: UA Headless 标记清洗——headless launch 的 UA 含 HeadlessChrome/xxx
|
|
202
|
+
// (最高频检测面),同步清洗 userAgent/appVersion/userAgentData(brands+高熵值)。
|
|
203
|
+
// 原型+实例双层覆写(S172 模式)。
|
|
204
|
+
" try{",
|
|
205
|
+
' var fixUA=function(ua){return String(ua).replace("HeadlessChrome","Chrome");};',
|
|
206
|
+
' var fixBrands=function(list){return (list||[]).map(function(b){return (b.brand&&b.brand.indexOf("Headless")!==-1)?Object.assign({},b,{brand:b.brand.replace("HeadlessChrome","Chrome")}):b;});};',
|
|
207
|
+
' var _nuad=Object.getOwnPropertyDescriptor(Navigator.prototype,"userAgentData");',
|
|
208
|
+
" var wrapUAD=function(uad){",
|
|
209
|
+
" if(!uad||uad.__xbUA)return uad;",
|
|
210
|
+
" try{",
|
|
211
|
+
' Object.defineProperty(uad,"brands",{get:function(){return fixBrands(_nuad.get.call(navigator).brands);},configurable:true});',
|
|
212
|
+
" var _ghev=uad.getHighEntropyValues.bind(uad);",
|
|
213
|
+
" uad.getHighEntropyValues=function(hints){return _ghev(hints).then(function(v){",
|
|
214
|
+
' var o={};for(var k in v){o[k]=(typeof v[k]==="string")?fixUA(v[k]):(Array.isArray(v[k])?fixBrands(v[k]):v[k]);}',
|
|
215
|
+
" return o;});};",
|
|
216
|
+
" uad.__xbUA=true;",
|
|
217
|
+
" }catch(e){}",
|
|
218
|
+
" return uad;",
|
|
219
|
+
" };",
|
|
220
|
+
' var _nua=Object.getOwnPropertyDescriptor(Navigator.prototype,"userAgent");',
|
|
221
|
+
" if(_nua&&_nua.get){",
|
|
222
|
+
" var _nuag=function(){return fixUA(_nua.get.call(this));};",
|
|
223
|
+
' _nuag.toString=function(){return "function get userAgent() { [native code] }";};',
|
|
224
|
+
' Object.defineProperty(Navigator.prototype,"userAgent",{get:_nuag,configurable:true});',
|
|
225
|
+
" }",
|
|
226
|
+
' Object.defineProperty(navigator,"userAgent",{get:function(){return fixUA(_nua?_nua.get.call(this):"");},configurable:true});',
|
|
227
|
+
" if(_nuad&&_nuad.get){",
|
|
228
|
+
" var _nuadg=function(){return wrapUAD(_nuad.get.call(this));};",
|
|
229
|
+
' _nuadg.toString=function(){return "function get userAgentData() { [native code] }";};',
|
|
230
|
+
' Object.defineProperty(Navigator.prototype,"userAgentData",{get:_nuadg,configurable:true});',
|
|
231
|
+
" }",
|
|
232
|
+
" }catch(e){}",
|
|
201
233
|
// hasFocus 与 visibilityState 联动(d29):恒 true 在 hidden 标签下暴露
|
|
202
234
|
// —— 真实浏览器失焦/后台时 hasFocus=false
|
|
203
|
-
|
|
235
|
+
// S172: 原型层覆写——实例赋值可被 Document.prototype.hasFocus.call(document) 逃逸
|
|
236
|
+
' Document.prototype.hasFocus=function(){return document.visibilityState==="visible";};',
|
|
204
237
|
// 4. Canvas/WebGL fingerprint: per-session stable noise (d20).
|
|
205
238
|
// Headless software raster differs subtly from Chrome GPU raster —
|
|
206
239
|
// toDataURL hashes fingerprint the rasterizer. Inject a stable
|
|
@@ -263,26 +296,25 @@ function buildStealthInitScript() {
|
|
|
263
296
|
" }catch(e){}",
|
|
264
297
|
// 3b. Font metrics + speechSynthesis + battery (d22): headless tells
|
|
265
298
|
" try{",
|
|
266
|
-
" var _mt=CanvasRenderingContext2D.prototype.measureText;",
|
|
267
299
|
' var _tmw=Object.getOwnPropertyDescriptor(TextMetrics.prototype,"width");',
|
|
268
|
-
"
|
|
269
|
-
"
|
|
270
|
-
'
|
|
271
|
-
"
|
|
272
|
-
" };",
|
|
300
|
+
" if(_tmw&&_tmw.get){",
|
|
301
|
+
" // S172: \u539F\u578B\u5C42\u8986\u5199\u2014\u2014\u5B9E\u4F8B(m)\u8986\u5199\u53EF\u88AB TextMetrics.prototype.width getter \u9003\u9038",
|
|
302
|
+
' Object.defineProperty(TextMetrics.prototype,"width",{get:function(){return _tmw.get.call(this)+_dx*0.01;},configurable:true});',
|
|
303
|
+
" }",
|
|
273
304
|
" }catch(e){}",
|
|
274
305
|
" try{",
|
|
275
306
|
' var _fakeVoices=["Alex","Daniel","Karen","Moira","Ralph","Samantha","Ting-Ting","Mei-Jia","Sinji","Yunda"];',
|
|
276
|
-
|
|
277
|
-
"
|
|
278
|
-
"
|
|
307
|
+
// S172: 原型层覆写——实例赋值可被 SpeechSynthesis.prototype.getVoices.call() 逃逸
|
|
308
|
+
" var _sv=SpeechSynthesis.prototype.getVoices;",
|
|
309
|
+
" SpeechSynthesis.prototype.getVoices=function(){",
|
|
310
|
+
" var real=_sv.call(this);",
|
|
279
311
|
" if(real&&real.length>50)return real;",
|
|
280
312
|
// 注意阈值从 0 改 50:iframe 原生约 10 个 —— 原阈值下 iframe 返回原生 10 个
|
|
281
313
|
// 而不是伪装 180(d33 暴露)。>50 = 主文档伪装列表已生效,其余返回伪装。
|
|
282
314
|
' return _fakeVoices.map(function(n,i){return {name:n,lang:i<2?"en-US":i<6?"en-GB":"zh-TW",localService:true,default:i===0,voiceURI:n};});',
|
|
283
315
|
" };",
|
|
284
316
|
// d33 修复:iframe 的 speechSynthesis 是独立实例(主文档 hook 不可达)——
|
|
285
|
-
// 轮询同源 iframe,对其 contentWindow
|
|
317
|
+
// 轮询同源 iframe,对其 contentWindow 的原型同样 patch(S172: 原型层,防逃逸)
|
|
286
318
|
" try{",
|
|
287
319
|
" var _piv=function(){",
|
|
288
320
|
' var frs=document.querySelectorAll("iframe");',
|
|
@@ -290,8 +322,8 @@ function buildStealthInitScript() {
|
|
|
290
322
|
" var cw=frs[i].contentWindow;",
|
|
291
323
|
" if(!cw||!cw.speechSynthesis||cw.speechSynthesis.__xbP)continue;",
|
|
292
324
|
" cw.speechSynthesis.__xbP=true;",
|
|
293
|
-
" var _sv2=cw.
|
|
294
|
-
" cw.
|
|
325
|
+
" var _sv2=cw.SpeechSynthesis.prototype.getVoices;",
|
|
326
|
+
" cw.SpeechSynthesis.prototype.getVoices=function(){var r=_sv2.call(this);if(r&&r.length>50)return r;",
|
|
295
327
|
' return _fakeVoices.map(function(n,j){return{name:n,lang:j<2?"en-US":j<6?"en-GB":"zh-TW",localService:true,default:j===0,voiceURI:n};});};',
|
|
296
328
|
" }catch(e2){}}",
|
|
297
329
|
" };",
|
|
@@ -326,10 +358,21 @@ function buildStealthInitScript() {
|
|
|
326
358
|
// 3d-2. performance.now precision clamp (d34): full-precision timestamps
|
|
327
359
|
// (11 decimals) differ from site-isolation-clamped real Chrome (~100μs).
|
|
328
360
|
" try{",
|
|
329
|
-
" var _pn=
|
|
330
|
-
"
|
|
361
|
+
" var _pn=Performance.prototype.now;",
|
|
362
|
+
" // S172: \u539F\u578B\u5C42\u8986\u5199\u2014\u2014\u5B9E\u4F8B\u8D4B\u503C\u53EF\u88AB Performance.prototype.now.call(performance) \u9003\u9038",
|
|
363
|
+
" Performance.prototype.now=function(){return Math.round(_pn.call(this)*10)/10;};",
|
|
331
364
|
' var _pto=Object.getOwnPropertyDescriptor(Performance.prototype,"timeOrigin");',
|
|
332
|
-
|
|
365
|
+
" if(_pto&&_pto.get){",
|
|
366
|
+
" // S173: timeOrigin \u771F\u4F2A\u88C5\u2014\u2014\u5360\u4F4D\u5C42\uFF08\u8FD4\u56DE\u771F\u503C\uFF09\u5347\u7EA7\u4E3A\u4F1A\u8BDD\u7EA7\u968F\u673A\u504F\u79FB\u3002",
|
|
367
|
+
" // \u9632 cross-page \u5BFC\u822A\u65F6\u523B\u5173\u8054\uFF1A\u4E0D\u540C\u7AD9\u70B9\u7528 timeOrigin \u7CBE\u786E\u5BF9\u9F50\u7528\u6237\u884C\u4E3A\u6863\u6848\u3002",
|
|
368
|
+
" // \u504F\u79FB\u7531\u672C\u9875 _seed \u6D3E\u751F\uFF08\u9875\u5185\u81EA\u6D3D\uFF0Cnow()+\u504F\u79FB\u4E00\u81F4\uFF09\uFF0C\u8DE8\u9875\u968F\u673A\uFF08\u4E0D\u53EF\u5173\u8054\uFF09\u3002",
|
|
369
|
+
" var _toff=Math.floor((_seed/2147483647)*600000-300000);",
|
|
370
|
+
" var _tog=function(){return _pto.get.call(performance)+_toff;};",
|
|
371
|
+
' _tog.toString=function(){return "function get timeOrigin() { [native code] }";};',
|
|
372
|
+
" // S172 \u5BA1\u8BA1\uFF1A\u5B9E\u4F8B\u8986\u5199\u53EF\u88AB\u539F\u578B getter \u9003\u9038\u2014\u2014\u539F\u578B\u5C42\u8986\u5199",
|
|
373
|
+
' Object.defineProperty(Performance.prototype,"timeOrigin",{get:_tog,configurable:true});',
|
|
374
|
+
' Object.defineProperty(performance,"timeOrigin",{get:_tog,configurable:true});',
|
|
375
|
+
" }",
|
|
333
376
|
" }catch(e){}",
|
|
334
377
|
// 3f. getCoalescedEvents 合成(d47):真实鼠标 125Hz 采样被浏览器按帧合并,
|
|
335
378
|
// 快速移动时 pointermove.getCoalescedEvents() 返回 2~6 个事件(群内
|
|
@@ -443,6 +486,9 @@ function buildStealthInitScript() {
|
|
|
443
486
|
' if(this===AnalyserNode.prototype.getFloatFrequencyData)return"function getFloatFrequencyData() { [native code] }";',
|
|
444
487
|
' if(this===AudioBuffer.prototype.getChannelData)return"function getChannelData() { [native code] }";',
|
|
445
488
|
' if(this===_gceH)return"function getCoalescedEvents() { [native code] }";',
|
|
489
|
+
' if(this===Document.prototype.hasFocus)return"function hasFocus() { [native code] }";',
|
|
490
|
+
' if(this===Performance.prototype.now)return"function now() { [native code] }";',
|
|
491
|
+
' if(this===SpeechSynthesis.prototype.getVoices)return"function getVoices() { [native code] }";',
|
|
446
492
|
" return _ts.call(this);",
|
|
447
493
|
" };",
|
|
448
494
|
// 4. onclick prototype hijack (dual-stream consistency)
|
|
@@ -196,9 +196,42 @@ function buildStealthInitScript() {
|
|
|
196
196
|
' Object.defineProperty(Screen.prototype,"height",{get:_gh,configurable:true});',
|
|
197
197
|
' Object.defineProperty(Screen.prototype,"availWidth",{get:_gw,configurable:true});',
|
|
198
198
|
' Object.defineProperty(Screen.prototype,"availHeight",{get:_gah,configurable:true});',
|
|
199
|
+
// S174: UA Headless 标记清洗——headless launch 的 UA 含 HeadlessChrome/xxx
|
|
200
|
+
// (最高频检测面),同步清洗 userAgent/appVersion/userAgentData(brands+高熵值)。
|
|
201
|
+
// 原型+实例双层覆写(S172 模式)。
|
|
202
|
+
" try{",
|
|
203
|
+
' var fixUA=function(ua){return String(ua).replace("HeadlessChrome","Chrome");};',
|
|
204
|
+
' var fixBrands=function(list){return (list||[]).map(function(b){return (b.brand&&b.brand.indexOf("Headless")!==-1)?Object.assign({},b,{brand:b.brand.replace("HeadlessChrome","Chrome")}):b;});};',
|
|
205
|
+
' var _nuad=Object.getOwnPropertyDescriptor(Navigator.prototype,"userAgentData");',
|
|
206
|
+
" var wrapUAD=function(uad){",
|
|
207
|
+
" if(!uad||uad.__xbUA)return uad;",
|
|
208
|
+
" try{",
|
|
209
|
+
' Object.defineProperty(uad,"brands",{get:function(){return fixBrands(_nuad.get.call(navigator).brands);},configurable:true});',
|
|
210
|
+
" var _ghev=uad.getHighEntropyValues.bind(uad);",
|
|
211
|
+
" uad.getHighEntropyValues=function(hints){return _ghev(hints).then(function(v){",
|
|
212
|
+
' var o={};for(var k in v){o[k]=(typeof v[k]==="string")?fixUA(v[k]):(Array.isArray(v[k])?fixBrands(v[k]):v[k]);}',
|
|
213
|
+
" return o;});};",
|
|
214
|
+
" uad.__xbUA=true;",
|
|
215
|
+
" }catch(e){}",
|
|
216
|
+
" return uad;",
|
|
217
|
+
" };",
|
|
218
|
+
' var _nua=Object.getOwnPropertyDescriptor(Navigator.prototype,"userAgent");',
|
|
219
|
+
" if(_nua&&_nua.get){",
|
|
220
|
+
" var _nuag=function(){return fixUA(_nua.get.call(this));};",
|
|
221
|
+
' _nuag.toString=function(){return "function get userAgent() { [native code] }";};',
|
|
222
|
+
' Object.defineProperty(Navigator.prototype,"userAgent",{get:_nuag,configurable:true});',
|
|
223
|
+
" }",
|
|
224
|
+
' Object.defineProperty(navigator,"userAgent",{get:function(){return fixUA(_nua?_nua.get.call(this):"");},configurable:true});',
|
|
225
|
+
" if(_nuad&&_nuad.get){",
|
|
226
|
+
" var _nuadg=function(){return wrapUAD(_nuad.get.call(this));};",
|
|
227
|
+
' _nuadg.toString=function(){return "function get userAgentData() { [native code] }";};',
|
|
228
|
+
' Object.defineProperty(Navigator.prototype,"userAgentData",{get:_nuadg,configurable:true});',
|
|
229
|
+
" }",
|
|
230
|
+
" }catch(e){}",
|
|
199
231
|
// hasFocus 与 visibilityState 联动(d29):恒 true 在 hidden 标签下暴露
|
|
200
232
|
// —— 真实浏览器失焦/后台时 hasFocus=false
|
|
201
|
-
|
|
233
|
+
// S172: 原型层覆写——实例赋值可被 Document.prototype.hasFocus.call(document) 逃逸
|
|
234
|
+
' Document.prototype.hasFocus=function(){return document.visibilityState==="visible";};',
|
|
202
235
|
// 4. Canvas/WebGL fingerprint: per-session stable noise (d20).
|
|
203
236
|
// Headless software raster differs subtly from Chrome GPU raster —
|
|
204
237
|
// toDataURL hashes fingerprint the rasterizer. Inject a stable
|
|
@@ -261,26 +294,25 @@ function buildStealthInitScript() {
|
|
|
261
294
|
" }catch(e){}",
|
|
262
295
|
// 3b. Font metrics + speechSynthesis + battery (d22): headless tells
|
|
263
296
|
" try{",
|
|
264
|
-
" var _mt=CanvasRenderingContext2D.prototype.measureText;",
|
|
265
297
|
' var _tmw=Object.getOwnPropertyDescriptor(TextMetrics.prototype,"width");',
|
|
266
|
-
"
|
|
267
|
-
"
|
|
268
|
-
'
|
|
269
|
-
"
|
|
270
|
-
" };",
|
|
298
|
+
" if(_tmw&&_tmw.get){",
|
|
299
|
+
" // S172: \u539F\u578B\u5C42\u8986\u5199\u2014\u2014\u5B9E\u4F8B(m)\u8986\u5199\u53EF\u88AB TextMetrics.prototype.width getter \u9003\u9038",
|
|
300
|
+
' Object.defineProperty(TextMetrics.prototype,"width",{get:function(){return _tmw.get.call(this)+_dx*0.01;},configurable:true});',
|
|
301
|
+
" }",
|
|
271
302
|
" }catch(e){}",
|
|
272
303
|
" try{",
|
|
273
304
|
' var _fakeVoices=["Alex","Daniel","Karen","Moira","Ralph","Samantha","Ting-Ting","Mei-Jia","Sinji","Yunda"];',
|
|
274
|
-
|
|
275
|
-
"
|
|
276
|
-
"
|
|
305
|
+
// S172: 原型层覆写——实例赋值可被 SpeechSynthesis.prototype.getVoices.call() 逃逸
|
|
306
|
+
" var _sv=SpeechSynthesis.prototype.getVoices;",
|
|
307
|
+
" SpeechSynthesis.prototype.getVoices=function(){",
|
|
308
|
+
" var real=_sv.call(this);",
|
|
277
309
|
" if(real&&real.length>50)return real;",
|
|
278
310
|
// 注意阈值从 0 改 50:iframe 原生约 10 个 —— 原阈值下 iframe 返回原生 10 个
|
|
279
311
|
// 而不是伪装 180(d33 暴露)。>50 = 主文档伪装列表已生效,其余返回伪装。
|
|
280
312
|
' return _fakeVoices.map(function(n,i){return {name:n,lang:i<2?"en-US":i<6?"en-GB":"zh-TW",localService:true,default:i===0,voiceURI:n};});',
|
|
281
313
|
" };",
|
|
282
314
|
// d33 修复:iframe 的 speechSynthesis 是独立实例(主文档 hook 不可达)——
|
|
283
|
-
// 轮询同源 iframe,对其 contentWindow
|
|
315
|
+
// 轮询同源 iframe,对其 contentWindow 的原型同样 patch(S172: 原型层,防逃逸)
|
|
284
316
|
" try{",
|
|
285
317
|
" var _piv=function(){",
|
|
286
318
|
' var frs=document.querySelectorAll("iframe");',
|
|
@@ -288,8 +320,8 @@ function buildStealthInitScript() {
|
|
|
288
320
|
" var cw=frs[i].contentWindow;",
|
|
289
321
|
" if(!cw||!cw.speechSynthesis||cw.speechSynthesis.__xbP)continue;",
|
|
290
322
|
" cw.speechSynthesis.__xbP=true;",
|
|
291
|
-
" var _sv2=cw.
|
|
292
|
-
" cw.
|
|
323
|
+
" var _sv2=cw.SpeechSynthesis.prototype.getVoices;",
|
|
324
|
+
" cw.SpeechSynthesis.prototype.getVoices=function(){var r=_sv2.call(this);if(r&&r.length>50)return r;",
|
|
293
325
|
' return _fakeVoices.map(function(n,j){return{name:n,lang:j<2?"en-US":j<6?"en-GB":"zh-TW",localService:true,default:j===0,voiceURI:n};});};',
|
|
294
326
|
" }catch(e2){}}",
|
|
295
327
|
" };",
|
|
@@ -324,10 +356,21 @@ function buildStealthInitScript() {
|
|
|
324
356
|
// 3d-2. performance.now precision clamp (d34): full-precision timestamps
|
|
325
357
|
// (11 decimals) differ from site-isolation-clamped real Chrome (~100μs).
|
|
326
358
|
" try{",
|
|
327
|
-
" var _pn=
|
|
328
|
-
"
|
|
359
|
+
" var _pn=Performance.prototype.now;",
|
|
360
|
+
" // S172: \u539F\u578B\u5C42\u8986\u5199\u2014\u2014\u5B9E\u4F8B\u8D4B\u503C\u53EF\u88AB Performance.prototype.now.call(performance) \u9003\u9038",
|
|
361
|
+
" Performance.prototype.now=function(){return Math.round(_pn.call(this)*10)/10;};",
|
|
329
362
|
' var _pto=Object.getOwnPropertyDescriptor(Performance.prototype,"timeOrigin");',
|
|
330
|
-
|
|
363
|
+
" if(_pto&&_pto.get){",
|
|
364
|
+
" // S173: timeOrigin \u771F\u4F2A\u88C5\u2014\u2014\u5360\u4F4D\u5C42\uFF08\u8FD4\u56DE\u771F\u503C\uFF09\u5347\u7EA7\u4E3A\u4F1A\u8BDD\u7EA7\u968F\u673A\u504F\u79FB\u3002",
|
|
365
|
+
" // \u9632 cross-page \u5BFC\u822A\u65F6\u523B\u5173\u8054\uFF1A\u4E0D\u540C\u7AD9\u70B9\u7528 timeOrigin \u7CBE\u786E\u5BF9\u9F50\u7528\u6237\u884C\u4E3A\u6863\u6848\u3002",
|
|
366
|
+
" // \u504F\u79FB\u7531\u672C\u9875 _seed \u6D3E\u751F\uFF08\u9875\u5185\u81EA\u6D3D\uFF0Cnow()+\u504F\u79FB\u4E00\u81F4\uFF09\uFF0C\u8DE8\u9875\u968F\u673A\uFF08\u4E0D\u53EF\u5173\u8054\uFF09\u3002",
|
|
367
|
+
" var _toff=Math.floor((_seed/2147483647)*600000-300000);",
|
|
368
|
+
" var _tog=function(){return _pto.get.call(performance)+_toff;};",
|
|
369
|
+
' _tog.toString=function(){return "function get timeOrigin() { [native code] }";};',
|
|
370
|
+
" // S172 \u5BA1\u8BA1\uFF1A\u5B9E\u4F8B\u8986\u5199\u53EF\u88AB\u539F\u578B getter \u9003\u9038\u2014\u2014\u539F\u578B\u5C42\u8986\u5199",
|
|
371
|
+
' Object.defineProperty(Performance.prototype,"timeOrigin",{get:_tog,configurable:true});',
|
|
372
|
+
' Object.defineProperty(performance,"timeOrigin",{get:_tog,configurable:true});',
|
|
373
|
+
" }",
|
|
331
374
|
" }catch(e){}",
|
|
332
375
|
// 3f. getCoalescedEvents 合成(d47):真实鼠标 125Hz 采样被浏览器按帧合并,
|
|
333
376
|
// 快速移动时 pointermove.getCoalescedEvents() 返回 2~6 个事件(群内
|
|
@@ -441,6 +484,9 @@ function buildStealthInitScript() {
|
|
|
441
484
|
' if(this===AnalyserNode.prototype.getFloatFrequencyData)return"function getFloatFrequencyData() { [native code] }";',
|
|
442
485
|
' if(this===AudioBuffer.prototype.getChannelData)return"function getChannelData() { [native code] }";',
|
|
443
486
|
' if(this===_gceH)return"function getCoalescedEvents() { [native code] }";',
|
|
487
|
+
' if(this===Document.prototype.hasFocus)return"function hasFocus() { [native code] }";',
|
|
488
|
+
' if(this===Performance.prototype.now)return"function now() { [native code] }";',
|
|
489
|
+
' if(this===SpeechSynthesis.prototype.getVoices)return"function getVoices() { [native code] }";',
|
|
444
490
|
" return _ts.call(this);",
|
|
445
491
|
" };",
|
|
446
492
|
// 4. onclick prototype hijack (dual-stream consistency)
|
package/dist/cli.js
CHANGED
|
@@ -72,7 +72,7 @@ import {
|
|
|
72
72
|
setActivePage,
|
|
73
73
|
sleep,
|
|
74
74
|
wheelDelta
|
|
75
|
-
} from "./chunk-
|
|
75
|
+
} from "./chunk-T2KUVO4H.js";
|
|
76
76
|
import "./chunk-3KZ34AUC.js";
|
|
77
77
|
import {
|
|
78
78
|
errMsg
|
|
@@ -8248,7 +8248,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
|
|
|
8248
8248
|
}
|
|
8249
8249
|
let targetPageOverride = null;
|
|
8250
8250
|
if (_target && extraOpts?.cdpEndpoint) {
|
|
8251
|
-
const { findTargetPage } = await import("./browser-
|
|
8251
|
+
const { findTargetPage } = await import("./browser-Y6B3NS4Q.js");
|
|
8252
8252
|
targetPageOverride = await findTargetPage(extraOpts.cdpEndpoint, _target);
|
|
8253
8253
|
if (!targetPageOverride) {
|
|
8254
8254
|
return errorResult(`Target "${_target}" not found. Use 'xbrowser targets --cdp ${extraOpts.cdpEndpoint}' to list available pages.`);
|
|
@@ -14433,7 +14433,7 @@ Run "xbrowser ${command} ${subCommand} --help" to see available parameters.`
|
|
|
14433
14433
|
const targetPage = pages[cmdTabIndex];
|
|
14434
14434
|
await targetPage.bringToFront().catch(() => {
|
|
14435
14435
|
});
|
|
14436
|
-
const { setActivePage: setActivePage2 } = await import("./browser-
|
|
14436
|
+
const { setActivePage: setActivePage2 } = await import("./browser-Y6B3NS4Q.js");
|
|
14437
14437
|
setActivePage2(session, targetPage);
|
|
14438
14438
|
}
|
|
14439
14439
|
}
|
|
@@ -14709,7 +14709,7 @@ async function main() {
|
|
|
14709
14709
|
const command = process.argv[2];
|
|
14710
14710
|
const isLongRunning = command === "preview" || command === "serve";
|
|
14711
14711
|
if (!isLongRunning) {
|
|
14712
|
-
const { ensureProcessCanExit } = await import("./browser-
|
|
14712
|
+
const { ensureProcessCanExit } = await import("./browser-Y6B3NS4Q.js");
|
|
14713
14713
|
await ensureProcessCanExit().catch(() => {
|
|
14714
14714
|
});
|
|
14715
14715
|
process.exit(process.exitCode || exitCode);
|
package/dist/daemon-main.js
CHANGED
|
@@ -34,13 +34,13 @@ import {
|
|
|
34
34
|
resolveLaunchOpts,
|
|
35
35
|
saveSessionDiskMeta,
|
|
36
36
|
setActivePage
|
|
37
|
-
} from "./chunk-
|
|
37
|
+
} from "./chunk-75TLPVVZ.js";
|
|
38
38
|
import {
|
|
39
39
|
createRuleEngine,
|
|
40
40
|
rand,
|
|
41
41
|
sleep,
|
|
42
42
|
wheelDelta
|
|
43
|
-
} from "./chunk-
|
|
43
|
+
} from "./chunk-UYEJ66VX.js";
|
|
44
44
|
import {
|
|
45
45
|
queryJS
|
|
46
46
|
} from "./chunk-3FWLW7FS.js";
|
|
@@ -7766,7 +7766,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
|
|
|
7766
7766
|
}
|
|
7767
7767
|
let targetPageOverride = null;
|
|
7768
7768
|
if (_target && extraOpts?.cdpEndpoint) {
|
|
7769
|
-
const { findTargetPage } = await import("./browser-
|
|
7769
|
+
const { findTargetPage } = await import("./browser-PBBC7RAV.js");
|
|
7770
7770
|
targetPageOverride = await findTargetPage(extraOpts.cdpEndpoint, _target);
|
|
7771
7771
|
if (!targetPageOverride) {
|
|
7772
7772
|
return errorResult(`Target "${_target}" not found. Use 'xbrowser targets --cdp ${extraOpts.cdpEndpoint}' to list available pages.`);
|
|
@@ -9588,7 +9588,7 @@ function createRPCHandler() {
|
|
|
9588
9588
|
if (isNewFormat) {
|
|
9589
9589
|
try {
|
|
9590
9590
|
const replayErrors = [];
|
|
9591
|
-
const { SessionReplayer } = await import("./session-replayer-
|
|
9591
|
+
const { SessionReplayer } = await import("./session-replayer-SBYJXQZZ.js");
|
|
9592
9592
|
const replayer = new SessionReplayer({
|
|
9593
9593
|
page: session.page,
|
|
9594
9594
|
stepDelay: slowMo * 500,
|
package/dist/index.js
CHANGED
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
resolveLaunchOpts,
|
|
19
19
|
saveSessionDiskMeta,
|
|
20
20
|
setActivePage
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-76EKW7YJ.js";
|
|
22
22
|
import {
|
|
23
23
|
detectAntiBot,
|
|
24
24
|
formatDetectionMessage
|
|
@@ -86,7 +86,7 @@ import {
|
|
|
86
86
|
rand,
|
|
87
87
|
sleep,
|
|
88
88
|
wheelDelta
|
|
89
|
-
} from "./chunk-
|
|
89
|
+
} from "./chunk-FDU5BCPV.js";
|
|
90
90
|
import "./chunk-3KZ34AUC.js";
|
|
91
91
|
import {
|
|
92
92
|
errMsg
|
|
@@ -8599,7 +8599,7 @@ async function executeCommand(commandName, params, sessionName = "default", extr
|
|
|
8599
8599
|
}
|
|
8600
8600
|
let targetPageOverride = null;
|
|
8601
8601
|
if (_target && extraOpts?.cdpEndpoint) {
|
|
8602
|
-
const { findTargetPage } = await import("./browser-
|
|
8602
|
+
const { findTargetPage } = await import("./browser-NVC7MTML.js");
|
|
8603
8603
|
targetPageOverride = await findTargetPage(extraOpts.cdpEndpoint, _target);
|
|
8604
8604
|
if (!targetPageOverride) {
|
|
8605
8605
|
return errorResult(`Target "${_target}" not found. Use 'xbrowser targets --cdp ${extraOpts.cdpEndpoint}' to list available pages.`);
|
|
@@ -14822,7 +14822,7 @@ Run "xbrowser ${command} ${subCommand} --help" to see available parameters.`
|
|
|
14822
14822
|
const targetPage = pages[cmdTabIndex];
|
|
14823
14823
|
await targetPage.bringToFront().catch(() => {
|
|
14824
14824
|
});
|
|
14825
|
-
const { setActivePage: setActivePage2 } = await import("./browser-
|
|
14825
|
+
const { setActivePage: setActivePage2 } = await import("./browser-NVC7MTML.js");
|
|
14826
14826
|
setActivePage2(session, targetPage);
|
|
14827
14827
|
}
|
|
14828
14828
|
}
|
|
@@ -17995,7 +17995,7 @@ var DataCollector = class {
|
|
|
17995
17995
|
return results;
|
|
17996
17996
|
}
|
|
17997
17997
|
async createBrowserContext() {
|
|
17998
|
-
const { launch } = await import("./cdp-driver-
|
|
17998
|
+
const { launch } = await import("./cdp-driver-QYFA4QTP.js");
|
|
17999
17999
|
const { browser } = await launch({
|
|
18000
18000
|
headless: true,
|
|
18001
18001
|
args: ["--no-sandbox", "--disable-setuid-sandbox"]
|
|
@@ -34,7 +34,7 @@ var SessionReplayer = class {
|
|
|
34
34
|
if (this.opts.page) {
|
|
35
35
|
this.page = this.opts.page;
|
|
36
36
|
} else if (this.opts.cdpUrl) {
|
|
37
|
-
const { launch } = await import("./cdp-driver-
|
|
37
|
+
const { launch } = await import("./cdp-driver-73F5CVH2.js");
|
|
38
38
|
const { browser } = await launch({ cdpEndpoint: this.opts.cdpUrl });
|
|
39
39
|
let contexts = browser.contexts();
|
|
40
40
|
for (let i = 0; i < 10 && contexts.length === 0; i++) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xbrowser/cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.20.0",
|
|
4
4
|
"description": "Browser automation CLI for web scraping, headless browsing, SEO analysis, and AI agent workflows. A command-line alternative to Playwright, Puppeteer, and Selenium.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|