1

There's a page eg. http://somesite.com that runs some javascript code located in path eg.http://somesite.com/code.js

In that file -among other code- there's a function (badFunction(x,y)).

I'd like to change the value of one of it's local variables, in order to make it equal with some another (local) variable (which is used inside in another function, also located in that remote javascript file).

So, based on these two answers 1 and 2 (i.e this userscript), I've tried the following simple userscript, in order to replace the entire badFunction with my own implementation, but it doesn't work (i.e my badFunction is not injected in the loaded code.js - I've checked it via Firefox's Debugger).

What I'm trying to accomplish with the userscript, is, while the code.js is loaded, at the time the badFunction definition is reached, to inject my function implementation, and then, let the rest code.js continue it's loading normally.

What is wrong in my userscript? Or is my approach wrong altogether?

I'd prefer not give the actual URL of the forementioned remote javascript file as it's NSFW.

// ==UserScript==
// @name           @document-start Example
// @version        1
// @namespace      
// @include        http://somesite.com/*
// @run-at         document-start
// ==/UserScript==

var changed = 1; // script need to be edited with

window.addEventListener('beforescriptexecute', function(e) {

  ///for external script:   
    src = e.target.src;
    if (src.search(/code\.js/) == "badFunction") {
        changed--;
        e.preventDefault();
        e.stopPropagation();
        append(badFunction);
    };

    ///when done, remove the listener:
    if(changed == 0) window.removeEventListener(e.type, arguments.callee, true);

}, true);


////// append with new block function:
function append(s) {     
    document.head.appendChild(document.createElement('script'))
                          .innerHTML = s.toString().replace(/^function.*{|}$/g, '');
}

function badFunction(x, y)
{
 // my code
};
Community
  • 1
  • 1
darkred
  • 591
  • 5
  • 28

2 Answers2

1

I do not have the source code of your site so I do not know how the badFunction is declared and called. However keep in mind that if the function is called inside a closure you need to inject the code somewhere inside that closure:

(function someClosure() {
  function hello() {
    // code
  }
  // hello is available
})();
// hello is not available

In the link they show how to modify the existing source code

window.addEventListener('beforescriptexecute', function(e) {

    ///for external script:
    src = e.target.src;
    if (src.search(/bad\.js/) != -1) {
                changed++;
        e.preventDefault();
        e.stopPropagation();
        append(NewScript1);
    };
});

So basically you need to search for your function code and replace it. Remember you can search for newlines in regex using [\s\S]* link

Community
  • 1
  • 1
Posva
  • 1,104
  • 9
  • 15
  • Thank you for trying to help. I've misjudged the necessity of the addEventListener. So, I edited my userscript code -I hope I got it right- (btw `badFunction` is not inside a closure). But still it doesn't work. (there's no error in Error Console, but the edited function doesn't seem to be injected) – darkred Mar 16 '15 at 00:01
  • I've renamed and edited again my question, to better describe what I'm trying do. – darkred Mar 16 '15 at 10:41
  • 1
    If overriding `badfunction` doesn't work it means some variable is holding it and that this variable is used for the call because `badfunction` should be overrided. Did you try to call `badFunction` within console after your script loaded ? BTW with the example above I was talking about changing the source code before it is actually loaded which is what the page seems to suggest although I am not sure about this technique – Posva Mar 16 '15 at 15:08
1

After reading these two answers (which I upvoted of course):
How to overwrite a function using a userscript? and
Stop execution of Javascript function (client side) or tweak it
(and because badfunction is not global, and code.js fires immediately and is a file, not inline)
the solution I concluded to is:

  • First, grab a copy of the script and make the desired change to it. Save this locally.
  • Then use Adblock Plus to block loading of that remote script file.
  • Then use the script offered in the 2nd link to add my modified local file to the page.

    var scriptNode = document.createElement ("script");
    scriptNode.setAttribute ("src", "Point to your modified JS file here.");
    document.head.appendChild (scriptNode);
    
Community
  • 1
  • 1
darkred
  • 591
  • 5
  • 28