mirror of
https://git.mirrors.martin98.com/https://github.com/cilame/v_jstools
synced 2025-08-15 17:55:55 +08:00
add
This commit is contained in:
parent
713fd7fefc
commit
0e56986fb5
@ -1,3 +1,20 @@
|
|||||||
|
// 暂时还在考虑的一种 window hook 方式。需要配合全局 ast 代码修改的方式
|
||||||
|
function fetch_hook(code){
|
||||||
|
var newn = t.ConditionalExpression(
|
||||||
|
t.BinaryExpression('===', t.ThisExpression(), t.Identifier('v_window')),
|
||||||
|
t.Identifier('v_win'),
|
||||||
|
t.ThisExpression()
|
||||||
|
)
|
||||||
|
function protect_this(path){
|
||||||
|
var node = path.node
|
||||||
|
path.replaceWith(newn)
|
||||||
|
path.stop()
|
||||||
|
}
|
||||||
|
var ast = parser.parse(code, {allowReturnOutsideFunction: true});
|
||||||
|
traverse(ast, {ThisExpression: protect_this});
|
||||||
|
var { code } = generator(ast, { jsescOption: { minimal: true, } });
|
||||||
|
return `
|
||||||
|
|
||||||
// 暂时还在考虑的一种 window hook 方式。需要配合全局 ast 代码修改的方式
|
// 暂时还在考虑的一种 window hook 方式。需要配合全局 ast 代码修改的方式
|
||||||
;(function(){
|
;(function(){
|
||||||
var cache = {}
|
var cache = {}
|
||||||
@ -14,8 +31,8 @@
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
var filter_log = console.log
|
var filter_log = console.log
|
||||||
function make_fake_window(){
|
!function make_fake_window(){
|
||||||
if (window.globalThisWindow){ return window.globalThisWindow }
|
if (window.v_win){ return }
|
||||||
var _win = {}
|
var _win = {}
|
||||||
function mainobj(b, r){
|
function mainobj(b, r){
|
||||||
switch(b){
|
switch(b){
|
||||||
@ -52,13 +69,9 @@
|
|||||||
}
|
}
|
||||||
var unlogs = [
|
var unlogs = [
|
||||||
'undefined',
|
'undefined',
|
||||||
|
'v_window',
|
||||||
]
|
]
|
||||||
// var unlimits = [
|
var localeval = eval
|
||||||
// 'module',
|
|
||||||
// 'define',
|
|
||||||
// 'global',
|
|
||||||
// 'process',
|
|
||||||
// ]
|
|
||||||
var win = new Proxy(_win, {
|
var win = new Proxy(_win, {
|
||||||
has: function(a,b){ return true },
|
has: function(a,b){ return true },
|
||||||
set: function(a,b,c){ return filter_log('window set', b, c), window[b]=c },
|
set: function(a,b,c){ return filter_log('window set', b, c), window[b]=c },
|
||||||
@ -70,36 +83,27 @@
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
var interceptor = new Proxy(_win, {
|
var interceptor = new Proxy(_win, {
|
||||||
has: function(a,b){ return true },
|
has: function(a,b){ return b in window }, // win 和 interceptor 的区别在这里
|
||||||
set: function(a,b,c){ return filter_log('window set', b, c), window[b]=c },
|
set: function(a,b,c){ return filter_log('window set', b, c), window[b]=c },
|
||||||
get: function(a,b){
|
get: function(a,b){
|
||||||
// if (!(b in window) && typeof b != 'symbol' && unlimits.indexOf(b) == -1){ throw ReferenceError(b + ' is not defined') } // win 和 interceptor 的区别在这里
|
if (!(b in window) && typeof b != 'symbol'){ throw ReferenceError(b + ' is not defined') } // win 和 interceptor 的区别在这里
|
||||||
var r = mainobj(b)
|
var r = mainobj(b)
|
||||||
if (!(b == Symbol.unscopables || b == Symbol.toStringTag || b == Symbol.toPrimitive || unlogs.indexOf(b) != -1)){ filter_log('window', 'get', b, r) }
|
if (!(b == Symbol.unscopables || b == Symbol.toStringTag || b == Symbol.toPrimitive || unlogs.indexOf(b) != -1)){ filter_log('window', 'get', b, r) }
|
||||||
if (typeof r == 'function' && !r.prototype){ return r.bind(window) }
|
if (typeof r == 'function' && !r.prototype){ return r.bind(window) }
|
||||||
return r
|
return r
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
window.globalThisWindow = _win
|
window.v_win = win
|
||||||
window.globalThisInterceptor = interceptor
|
window.v_interceptor = interceptor
|
||||||
return Object.defineProperty(_win, 'v_run', {set:function(v){ v.call(win, interceptor) }})
|
window.v_window = window
|
||||||
}
|
// window.v_eval = eval
|
||||||
return make_fake_window()
|
}()
|
||||||
})()
|
})()
|
||||||
|
|
||||||
|
|
||||||
// 第一种挂钩方式,能 hook 住最外层的 this ,不过有缺陷,this 也只能挂在最外一层,内层就基本挂钩不了。
|
with (window.v_interceptor){
|
||||||
// 另外,因为代码都放在函数内部,导致函数定义只能在内部调用。跨脚本调用基本是别想了。
|
${code}
|
||||||
window.globalThisWindow.v_run = function(inter){
|
}
|
||||||
with (inter){
|
|
||||||
console.log(this == window)
|
`
|
||||||
console.log(window.a)
|
|
||||||
}},1
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 第二种挂钩方式,直接放弃挂钩 this 的可能,这样函数定义可以跨脚本调用,某种程度上具有鲁棒性,不过 this 这块的很难绕过。
|
|
||||||
with (window.globalThisInterceptor){
|
|
||||||
console.log(this == window)
|
|
||||||
console.log(window.a)
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user