簡體   English   中英

將javascript代碼注入匿名函數作用域

[英]Inject javascript code into anonymous function scope

我有我需要注入的這種腳本

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

基本上,當我的代碼通過Function 對象調用時,我得到了對doSomething 的引用,但我需要掛鈎到doSomething,因此我需要對id 的原始引用。 由於 doSomething 是在匿名函數中聲明的,因此我無法訪問它。 問題是,我能否以某種方式將代碼注入匿名函數、Greesemonkey 或任何其他工具的范圍內。

嘿,我在谷歌搜索后看到你的問題,因為我對同一主題感興趣,而且我有點沮喪其他人似乎不明白你在問什么......但經過一些思考,我實際上提出了一個解決方案!

首先我會告訴你如果你要寫一個chrome擴展怎么做,這是保證我們攔截腳本源的最簡單的方法,但也有一種不做擴展的方法,見下文進一步。

基本上,假設您有一些要為其編寫插件的站點,其中包含一些 HTML 內容,例如:

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

並且文件 someFile.js 具有如下內容:

(function() {
    function cantGetMeMethod() {

    }
})();

因此,在執行 HTML 的主頁面上,用戶無法獲得函數“cantGetMeMethod”。

問題是,如果我們能夠簡單地更改該 JavaScript 文件的源代碼,我們可以輕松刪除匿名函數包裝,或者在底部插入某種全局變量引用。

但是我們怎么可能從客戶端更改 JavaScript 源代碼呢?

這就是 chrome 擴展的用武之地。使用擴展,可以將站點上任何地方發出的 HTTP 請求,甚至在頁面加載之前,重定向到另一個網站。 因此,例如,如果頁面有如下圖像:

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

該擴展程序可以將來自 example.com 的所有請求重定向到另一個網站,因此顯示的真實圖像(到具有擴展程序的客戶端)實際上可能來自其他某個網站,並且是完全不同的圖像!

這與 JavaScript 有什么關系?

因為同樣的原理也適用於 JavaScript 源。 我們所要做的就是找到對其他文件的 JavaScript 引用,並使用擴展名將 src URL 重定向到我們自己的服務器,並將原始 src URL 作為獲取參數。 所以說我們有一些 nodeJS 站點或托管在http://www.myAwesomeNodeJSserverOrSomething.com東西,所以我們將所有調用(或至少相關腳本調用)重定向到http://www.someURL.com/someFile.jshttp://www.myAwesomeNodeJSserverOrSomething.com/http://www.someURL.com/someFile.js

然后在 nodeJS 端做一些類似的事情:

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);

現在頁面已經修改了其中的 JavaScript 代碼! 那么我們如何制作一個快速的擴展來重定向標頭呢? 首先,創建一個新目錄,並在其中創建一個名為 manifest.json 的文件,如下所示:

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

現在在同一目錄中創建一個新文件“lol.js”,並放入如下內容:

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"]
);

(警告:未經測試的代碼)

並轉到 chrome 設置,進入開發者模式,並加載一個新的擴展程序,然后選擇該文件夾。

此外,如果您自己只是這樣做,那么在沒有擴展的情況下執行此操作的方法是在頁面加載之前注入一個mutationobserver 腳本,其中包含諸如篡改猴子之類的東西。 有關更多信息,請參見https://github.com/CertainPerformance/Stack-Exchange-Userscripts/blob/master/obsolete/Experiment-Off/StackExperimentOff.user.js https://stackoverflow.com/a/59424277/2016831讓我知道這是否可以為您解決。

Javascript 並不能輕松地從范圍內獲取值。

您可以在更廣泛的范圍內聲明doSomething

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

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

您還可以從內部范圍返回值! 例如:

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();

有時您的外部函數已經需要返回另一個值:

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

在這種情況下,我們仍然可以返回doSomething以及原始值:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM