开发者

"Decompile" Javascript function?

[1] Ok, I don't even know how to call this, to be honest. So let me get some semi-pseudo code, to show what I'm trying to do. I'm using jQuery to get an already existing script declared inside the page, inside a createDocument() element, from an AJAX call.

GM_xmlhttprequest({
  ...
  load:function(r){
    var doc = document_from_string(r.responseText);
    script_content = $('body script:regex(html, local_xw_sig)', doc).html();
    var scriptEl = document.createElement('script'开发者_开发知识库);
    scriptEl.type = 'text/javascript';
    scriptEl.innerHTML = script_content; // good till here
    (function(sc){
      eval(sc.innerHTML); // not exactly like this, but you get the idea, errors
      alert('wont get here ' + local_xw_sig); // local_xw_sig is a global "var" inside the source
    })(scriptEl);
  }
});

So far so good, the script indeed contains the source from the entire script block. Now, inside this "script_content", there are auto executing functions, like $(document).ready(function(){...}) that, everything I "eval" the innerHTML, it executes this code, halting my encapsulated script. Like variables that doesn't exist, etc.

Removing certain parts of the script using regex isn't really an option... what I really wanted is to "walk" inside the function. like do a (completely fictional):

script = eval("function(){" + script_content + "};");
alert(script['local_xw_sig']); // a03ucc34095cw3495

Is there any way to 'disassemble' the function, and be able to reach the "var"s inside of it? like this function:

function hello(){
  var message = "hello";
}
alert(hello.message); // message = var inside the function

Is it possible at all? Or I will have to hack my way using regex? ;P

[2] also, is there any way I can access javascript inside a document created with "createDocument"?


Simply trying to access a local variable inside a function from outside of it is impossible due to scope. However, using closures you can absolutely accomplish this:

function hello(msg){
  return function message(){
    return msg;
  }
}
alert(hello("yourMessage")()); // will alert "yourMessage"

Note exactly what's happening here. You are calling a function which returns a function, in which "yourMessage" is now defined inside its scope. Calling that inner closure the second time will yield that variable you set earlier.

If you are not familiar with closures in JS, I suggest you read this wonderful FAQ.


It's not possible that way. You can introspect object's properties (any function is an object), but not before you have created an instance with new operator.

Looking at your code sample, it seems that your approach is a bit messy – eval()'ing script blocks is something one should not do unless absolutely necessary (a situation I can't imagine).


In your example at

function hello(){
  var message = "hello";
}
alert(hello.message); // message = var inside the function

you can in fact use hello.toString() to get the function source, like this:

alert(hello.toString().match(/var message = \"(.*)\";/));


You want to eval the script in global scope. Briefly it is,

// Evalulates a script in a global context
globalEval: function( data ) {
        data = jQuery.trim( data );
        if ( data ) {
                if ( window.execScript )
                        window.execScript( data );
                else if ( jQuery.browser.safari )
                        // safari doesn't provide a synchronous global eval
                        window.setTimeout( data, 0 );
                else
                        eval.call( window, data );
        }
    }

Also check out Google's caja for secure external script evaluation.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜