我想计算用于动态解释的函数调用的数量 JavaScript代码(例如, eval 和 setTimeout )。我的主要目的是找到作为参数传递给eval和setTimeout 的字符串。这是因为恶意脚本通常使用eval函数动态评估复杂代码。找到这个的一种方法是挂钩函数,以便可以触发每个eval函数调用。但我不知道该怎么做。请用一个例子解释一下。
我通常尝试使用setTimeout,但是我没有得到正确的结果。
我的代码如下
var sto = setTimeout;
setTimeout = function setTimeout(str){
console.log(str);
}
我的实际用户名是:
// ==UserScript==
// @encoding UTF-8
// @name Count_setTimeout
// @run-at document-start
// ==/UserScript==
addJS_Node("var count=0;");
function Log_StimeoutCreations ()
{
var sto = setTimeout;
setTimeout = function(arg, time)
{
if(typeof arg == "string")
console.log("Insecure setTimeout: ", arg);
else
console.log("setTimeout:",arg);
count++;
sto(arg, time);
}
}
var waitForDomInterval = setInterval (
function () {
var domPresentNode;
if (typeof document.head == "undefined")
domPresentNode = document.querySelector ("head, body");
else
domPresentNode = document.head;
if (domPresentNode) {
clearInterval (waitForDomInterval);
addJS_Node (null, null, Log_StimeoutCreations);
}
},
1
);
function addJS_Node (text, s_URL, funcToRun) {
var D = document;
var scriptNode = D.createElement ('script');
scriptNode.type = "text/javascript";
if (text) scriptNode.textContent = text;
if (s_URL) scriptNode.src = s_URL;
if (funcToRun) scriptNode.textContent = '(' + funcToRun.toString() + ')()';
var targ = D.getElementsByTagName ('head')[0] || D.body || D.documentElement;
targ.appendChild (scriptNode);
}
addJS_Node("document.onreadystatechange = function (){if (document.readyState == 'complete'){if(typeof(unsafeWindow)=='undefined') { unsafeWindow=window; } unsafeWindow.console.log('count--'+count);}}");
但我甚至没有在源代码中查看setTimeout函数。我如何实现这一点通过这个我将得到内部eval函数,即eval(eval());
答案 0 :(得分:1)
你基本上做对了。这是我的代码:
var sto = setTimeout;
setTimeout = function(arg, time) {
if(typeof arg == "string")
console.warn("Insecure setTimeout: ", arg);
// call real setTimeout
sto(arg, time);
}
// ...now all future setTimeout calls will warn about string use...
setTimeout("alert(1);", 1000);
如果你想对它超级正确,不要将sto
留在允许访问原始setTimeout
的全局命名空间中,请使用闭包:
(function() {
var sto = setTimeout;
setTimeout = function(arg, time) {
if(typeof arg == "string")
console.warn("Insecure setTimeout!", arg);
sto(arg, time);
}
})();
这样,真正的setTimeout
完全无法访问,因为一旦匿名函数结束,sto
无法访问,新的setTimeout
封装器除外。