Oprócz redefiniowania console._commandLineAPI, istnieją inne sposoby włamania się do InjectedScriptHost w przeglądarkach WebKit, aby zapobiec lub zmienić ocenę wyrażeń wprowadzonych do konsoli programisty.
Edytować:
Chrome naprawił to w poprzedniej wersji. - które musiały być przed lutym 2015 r., ponieważ wtedy stworzyłem sedno
Oto kolejna możliwość. Tym razem w hak, poziom wyżej, bezpośrednio InjectedScriptzamiast InjectedScriptHostw przeciwieństwie do wcześniejszej wersji.
Co jest całkiem miłe, ponieważ możesz bezpośrednio małpować łatkę InjectedScript._evaluateAndWrapzamiast polegać na niej, InjectedScriptHost.evaluateponieważ daje to bardziej szczegółową kontrolę nad tym, co powinno się stać.
Inną dość interesującą rzeczą jest to, że możemy przechwycić wynik wewnętrzny podczas oceny wyrażenia i zwrócić go użytkownikowi zamiast normalnego zachowania.
Oto kod, który właśnie to robi, zwraca wynik wewnętrzny, gdy użytkownik ocenia coś w konsoli.
var is;
Object.defineProperty(Object.prototype,"_lastResult",{
get:function(){
return this._lR;
},
set:function(v){
if (typeof this._commandLineAPIImpl=="object") is=this;
this._lR=v;
}
});
setTimeout(function(){
var ev=is._evaluateAndWrap;
is._evaluateAndWrap=function(){
var res=ev.apply(is,arguments);
console.log();
if (arguments[2]==="completion") {
//This is the path you end up when a user types in the console and autocompletion get's evaluated
//Chrome expects a wrapped result to be returned from evaluateAndWrap.
//You can use `ev` to generate an object yourself.
//In case of the autocompletion chrome exptects an wrapped object with the properties that can be autocompleted. e.g.;
//{iGetAutoCompleted: true}
//You would then go and return that object wrapped, like
//return ev.call (is, '', '({test:true})', 'completion', true, false, true);
//Would make `test` pop up for every autocompletion.
//Note that syntax as well as every Object.prototype property get's added to that list later,
//so you won't be able to exclude things like `while` from the autocompletion list,
//unless you wou'd find a way to rewrite the getCompletions function.
//
return res; //Return the autocompletion result. If you want to break that, return nothing or an empty object
} else {
//This is the path where you end up when a user actually presses enter to evaluate an expression.
//In order to return anything as normal evaluation output, you have to return a wrapped object.
//In this case, we want to return the generated remote object.
//Since this is already a wrapped object it would be converted if we directly return it. Hence,
//`return result` would actually replicate the very normal behaviour as the result is converted.
//to output what's actually in the remote object, we have to stringify it and `evaluateAndWrap` that object again.`
//This is quite interesting;
return ev.call (is, null, '(' + JSON.stringify (res) + ')', "console", true, false, true)
}
};
},0);
To trochę gadatliwe, ale pomyślałem, że dodałem do niego kilka komentarzy
Więc normalnie, jeśli użytkownik, na przykład, ocenia, [1,2,3,4]można oczekiwać następujących danych wyjściowych:
Po monkeypatchingu InjectedScript._evaluateAndWrapoceniającym to samo wyrażenie, daje następujące dane wyjściowe:

Jak widzisz mała strzałka w lewo wskazująca wyjście, nadal tam jest, ale tym razem otrzymujemy obiekt. W przypadku wyniku wyrażenia tablica [1,2,3,4]jest reprezentowana jako obiekt ze wszystkimi opisanymi właściwościami.
Polecam spróbować ocenić to i to wyrażenie, w tym te, które generują błędy. To dość interesujące.
Dodatkowo spójrz na obiekt is - InjectedScriptHost- . Zapewnia kilka metod zabawy i pozwala uzyskać wgląd w wewnętrzne elementy kontrolera.
Oczywiście możesz przechwycić wszystkie te informacje i nadal zwrócić oryginalny wynik użytkownikowi.
Wystarczy zastąpić instrukcję return w ścieżce else console.log (res)następującą literą a return res. Wtedy skończysz z następującymi.
Koniec edycji
To jest poprzednia wersja, która została naprawiona przez Google. Dlatego nie jest już możliwy sposób.
Jeden z nich się zaczepia Function.prototype.call
Chrome ocenia wprowadzone wyrażenie, wprowadzając callfunkcję eval przy pomocy InjectedScriptHostasthisArg
var result = evalFunction.call(object, expression);
Biorąc to pod uwagę, można nasłuchiwać thisArgod callistoty evaluatei uzyskać odniesienie do pierwszego argumentu ( InjectedScriptHost)
if (window.URL) {
var ish, _call = Function.prototype.call;
Function.prototype.call = function () { //Could be wrapped in a setter for _commandLineAPI, to redefine only when the user started typing.
if (arguments.length > 0 && this.name === "evaluate" && arguments [0].constructor.name === "InjectedScriptHost") { //If thisArg is the evaluate function and the arg0 is the ISH
ish = arguments[0];
ish.evaluate = function (e) { //Redefine the evaluation behaviour
throw new Error ('Rejected evaluation of: \n\'' + e.split ('\n').slice(1,-1).join ("\n") + '\'');
};
Function.prototype.call = _call; //Reset the Function.prototype.call
return _call.apply(this, arguments);
}
};
}
Możesz np. Zgłosić błąd, że ocena została odrzucona.

Oto przykład, w którym wprowadzone wyrażenie jest przekazywane do kompilatora CoffeeScript przed przekazaniem go do evaluatefunkcji.