Inject javascript code into anonymous function scope

天涯浪子 提交于 2020-05-09 17:12:32

问题


I've got this kind of script I need to inject into

! function(e) {
    function doSomething()
    {
    }
}

Basically I get a reference to doSomething, when my code is called via Function object, but I need to hook to doSomething, so I need an original reference to id. Since doSomething is declared inside anonymous function I can't get to it. Question is, can I somehow inject code into the scope of anonymous function, Greesemonkey or any other tool.


回答1:


Javascript doesn't make it easy to get values from inside a scope.

You can declare doSomething in a broader scope:

function doSomething() {
    // ...
}
function func(e) {
    doSomething(); // This works! `func` has a reference to `doSomething`
}

doSomething(); // This also works! `doSomething` is declared in this scope.

You can also return values from an inner scope! For example:

function func(e) {
    function doSomething() {
        // ...
    }

    // Note that we are not invoking `doSomething`, we are only returning a reference to it.
    return doSomething; 
}

var doSomething = func(/* some value */);

// Now you got the reference!
doSomething();

Sometimes your outer function is already needed for returning another value:

function func(e) {
    function doSomething() { /* ... */ }
    return 'important value!!';
}

In this case we can STILL return doSomething, along with the original value:

function func(e) {
    function doSomething() { /* ... */ }
    return {
        value: 'important value',
        doSomething: doSomething
    };
}

var funcResult = func(/* some value */);
var originalValue = funcResult.value;
var doSomething = funcResult.doSomething;

// Now we have the original value, AND we have access to `doSomething`:
doSomething(); // This works



回答2:


Hey man I saw you're question after doing a google search, because I was interested in this same topic, and I was a bit frustrated how other people didn't seem to understand what you were asking... but after some thought, I actually proposed a solution!

First I'll show you how to do it if you were to write a chrome extension, which would be the simplest way to guarantee we are intercepting the script source, but there is also a way to do it without making an extension, see below further.

Basically, say you have some site that you want to write an addon for, with some HTML content like:

<script src="http://www.someURL.com/someFile.js"></script>

and the file someFile.js has content like the following:

(function() {
    function cantGetMeMethod() {

    }
})();

So the user, at the main page where the HTML is being executed, is unable to get the function "cantGetMeMethod".

The thing is, if we were able to simply change the source code of that JavaScript file, we could either easily remove the anonymous function wrap, or insert some kind of global variable reference to it at the bottom.

But how can we possibly change JavaScript source code from the client side?

That's where chrome extensions come in. With extensions, its possible to redirect an HTTP request that is made anywhere on the site, before the page even loads, to another website. So, for example, if a page had an image like:

<img src="http://example.com/somePic.png"></img>

the extension can redirect all requests made from example.com to another website, so the real image that is displayed (to the client with the extension) could be actually sourced at some other website, and be an entirely different image!

How is this relevant to JavaScript?

Because the same principle could work by JavaScript sources also. All we have to do is find the JavaScript references to other files, and, with the extension, redirect the src URL to our own server, with the original src URL as a get paramter. So say we have some nodeJS site or something hosted at http://www.myAwesomeNodeJSserverOrSomething.com, so we redirect all calls (or at least the relevant script calls) made to http://www.someURL.com/someFile.js to http://www.myAwesomeNodeJSserverOrSomething.com/http://www.someURL.com/someFile.js

and then on the nodeJS side do something like:

require("http")
.createServer((q,r) => {
    http.get(q.url.slice(1), req => {
        let str = "";
        req.on("data", d => str += d.toString())
        req.on("end", () => {
            let newCode = someFunctionThatModifiesCode(str);
            r.end(newCode);
        });
    }); //pseudocode obviously, check for errors etc. for real
}).listen(8080);

and now the page has modified JavaScript code in it! So how do we make a quick extension that redirects the headers? First, make a new directory, and make in it a file called manifest.json, like this:

{
    "name":"JavaScript cracking the codes",
    "version":"1.0",
    "description":"hi",
    "manifest_version":2,
    "permissions": [
        "webRequest",
        "webRequestBlocking",
        "<all_urls>"
    ],
    "background": {
        "scripts":["lol.js"],
        "persistent": true
    }
}

now make a new file "lol.js" in the same directory, and put in it something like this:

let otherServer = "http://www.myAwesomeNodeJSserverOrSomething.com",
    urlsToRedirect = [ //list of javascript files that need fine tuning
        "http://www.someURL.com/someFile.js",
        "http://www.someURL.com/someFile2.js",
        "http://www.someURL.com/someFile3.js",
    ];
chrome.webRequest.onBeforeRequest.addListener(
    details => {
        if(
            urlsToRedirect.includes(
                details
                .url
            )
        ) {
            {
                redirectUrl: (
                    otherServer 
                    + "/"
                    + details.url
                )
            }
        }
    },
    {urls: ["<all_urls>"]},
    ["blocking"]
);

(warning: untested code)

And go to chrome settings, put in in developer mode, and load in a new extension, and select that folder.

Also, the way to do it without an extension, if you yourself were just doing it, would be to inject a mutationobserver script before the page loads, with somethinng like tamper monkey. For more on this see https://github.com/CertainPerformance/Stack-Exchange-Userscripts/blob/master/obsolete/Experiment-Off/StackExperimentOff.user.js https://stackoverflow.com/a/59424277/2016831 Let me know if that solves it for you.



来源:https://stackoverflow.com/questions/46677566/inject-javascript-code-into-anonymous-function-scope

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!