[Greasemonkey] accessing js functions outside of GM scope
Johan Sundström
oyasumi at gmail.com
Wed Apr 12 09:45:56 EDT 2006
> Original code (obtained from GM_log(unsafeWindow.GEvent.addListener) ):
>
> window.GEvent.addListener =
> function Tb(a, b, c) {
> var d = new Fa(a, b, c, 0);
> mb.push(d);
> return d;
> }
>
> if I:
>
> window.location.href = "javascript:(function(){"
> + " window.GEvent.addListener = function(a, b, c){"
> + " function Tb(a, b, c) {"
> + " var d = new Fa(a, b, c, 0);"
> + " mb.push(d);"
> + "return d;"
> + " }; " // ends overwrite function
> + " }) ()";
>
> I get an error the Fa is not defined. The function looks identical
> in GM_log(unsafeWindow.GEvent.addListener)
>
>
> However, if I:
>
> window.location.href = "javascript:(function(){"
> + " window.GEvent.VaddListener = window.GEvent.addListener; "
> + " window.GEvent.addListener = function(a, b, c){"
> + " window.GEvent.VaddListener(a, b, c); alert(b); "
> + " }; " // ends overwrite function
> + " }) ()";
>
> addListener calls Vaddlistener and appends the alert to the end.
>
> Granted, I want to do more with the overwriting, such as add an entire
> line of code to the Td function. But this is just an example.
>
> Does this have something to do with the scope? or is this something
> to do with the obfuscated compression? More importantly, any ideas?
Yes; your overrided version is not defined in the same namespace, and
does not see the same scope environment that the original definitions
did. Your later example solves the issue by wrapping the existing
exposed function, but you can't do that for the (presumably
non-exposed -- your example code only mentions a Tb function) Td
function. If you meant the tb function, doesn't your alert() already
solve the issue?
I'd suggest also making sure your wrapper returns the returned value,
so it gets the same overall behaviour as the original.
If you really need to inject code inside anything within the namespace
wrapper that is not exposed to the public world, the only way I know
that works in a present-day GM+Firefox environment is to take the raw
code, as a string, parse out the injection spot, inject some more
source code there and evaluate the whole of it with changes and all.
It's very messy and unefficient, though, and I expect you might end up
with weird problems if any code has already been invoked with the
unchanged version of the code.
When dealing with exposed code and only needing code run prior to or
post invocation, I'd go with your present solution. Which might also
not affect any already resolved references to the original addListener
function.
--
/ Johan Sundström, http://ecmanaut.blogspot.com/
More information about the Greasemonkey
mailing list