将javascript注入javascript函数

时间:2010-01-21 11:58:52

标签: javascript function code-injection

我有一个奇怪的问题,我需要将一些javascript注入另一个javascript函数。我正在使用一个被锁定的框架,所以我无法改变现有的功能。

我得到的是这样的

function doSomething(){ ... }

... ***

我可以操作***(上面)但是我无法更改doSomething函数...相反,我需要以某种方式在doSomething代码的末尾注入几行代码。

我需要这样做的原因是自定义框架调用doSomething(),这导致从我需要提取的服务器返回一个ID。这个ID只在doSomething函数中引用,所以我无法捕获它,除非我向该函数注入代码(除非我遗漏了一些东西)。

有办法做到这一点吗?

7 个答案:

答案 0 :(得分:5)

别名。

var oldDoSomething = doSomething;
doSomething = function() {
  // Do what you need to do.
  return oldDoSomething.apply(oldDoSomething, arguments);
}

答案 1 :(得分:3)

感谢您的所有反馈。每个答案都给了我一个线索,因此我提出了以下解决方案。

<body>
<script type="text/javascript">
    var val;
    function doSomething(item1, item2) {
        var id = 3;
    }
    function merge() {
        var oScript = document.createElement("script");
        var oldDoSomething = doSomething.toString();
        oScript.language = "javascript";
        oScript.type = "text/javascript";
        var args = oldDoSomething.substring(oldDoSomething.indexOf("(") + 1, oldDoSomething.indexOf(")"));
        var scr = oldDoSomething.substring(oldDoSomething.indexOf("{") + 1, oldDoSomething.lastIndexOf("}") - 1);
        var newScript = "function doSomething(" + args + "){" + scr + " val = id; }";
        oScript.text = newScript;
        document.getElementsByTagName('BODY').item(0).appendChild(oScript);
    }

    merge();

</script>
<input type="button" onclick="doSomething();alert(val);" value="xx" />

答案 2 :(得分:2)

我不确定“锁定”是什么意思 - 您的浏览器会解释JavaScript。即使它已被缩小或编码,您仍然可以从脚本页面的源复制该函数的源。此时,您将原始函数重新分配给您自己的一个设计,其中包含复制的代码和您自己的代码。

var id;
var myFunction = function() {
  // code copied from their source, which contains the variable needed

  // insert  your own code, such as for copying the needed value
  id = theirIDvalue;

  // return the value as originally designed by the function
  return theirValue;
};

theirObject.theirFunction = myFunction;

答案 3 :(得分:2)

通过使用源代码字符串来改变函数可以非常简单。要针对特定​​实例执行此操作,请尝试:

eval(doSomething.toString().replace(/}\s*$/, ' return id; $&');

现在doSomething会返回ID。我通常不是eval的粉丝,但由于需要访问本地变量,因此普通aspect oriented programming技术不适用于此。

如果doSomething已经返回值,请尝试:

eval(doSomething.toString().replace(/}\s*$/, ' window.someID = id; $&');

要将其转换为函数,我们需要在全局范围内对代码进行求值:

function insertCode(func, replacer, pattern) {
    var newFunc = func.toString().replace(pattern, replacer);
    with (window) {
        eval(newFunc);
    }
}
function after(func, code) {
    return insertCode(func, function (old) { code + old }, /}\s*$/ );
}
...
after(doSomething, 'return id;');

如果要重写绑定到变量的方法和匿名函数,请将insertCodeBefore更改为:

function insertCode(funcName, replacer, pattern) {
    var newFunc = eval('window.' + funcName).toString().replace(pattern, replacer);
    eval('window.' + funcName + '=' + newFunc);
}
...
function Foo() {}
Foo.prototype.bar = function () { var secret=0x09F91102; }
...
after('doSomething', 'return id;');
after('Foo.prototype.bar', 'return secret;');

注意函数的第一个参数现在是字符串。我们可以定义其他功能:

function before(func, code) {
    return insertCode(func, function (old) {old + code}, /^function\s+\w+\([^)]*\)\s+{/);
}
function around(func, beforeCode, afterCode) {
    before(func, beforeCode);
    after(func, afterCode);
}

答案 4 :(得分:1)

function doSomething() { ... }
var oldVersionOfFunc = doSomething;
doSomething = function() {
    var retVal = oldVersionOfFunc.apply(oldVersionOfFunc, args);
    // your added code here
    return retVal;
}

这似乎引发了一个错误(太多的递归)

function doSomething(){ document.write('Test'); return 45; } 
var code = 'myDoSomething = ' + doSomething + '; function doSomething() { var id = myDoSomething(); document.write("Test 2"); return id; }';
eval(code)
doSomething();

这对我有用,即使它很难看。

答案 5 :(得分:0)

函数是Javascript中的第一类值,这意味着您可以将它们存储在变量中(事实上,声明命名函数实际上是将一个匿名函数赋值给变量)。

你应该可以这样做:

function doSomething() { ... }

var oldVersionOfFunc = doSomething;
doSomething = function() {

    var retVal = oldVersionOfFunc.apply(oldVersionOfFunc, args);

    // your added code here

    return retVal;
}

(但是,我可能是错的。我的javascript有点生疏。;))

答案 6 :(得分:0)

  

我无法更改doSomething函数...相反,我需要以某种方式在doSomething代码的末尾注入几行代码

doSomething代码的末尾注入几行听起来像更改doSomething函数给我。不幸的是,我认为你被搞砸了。

(我对这一切有些模糊,但我认为功能是那些担心这些事情的人如何在JavaScript中实现信息隐藏,正是因为你无法从他们外部访问他们的范围。)