を再定義する以外にもconsole._commandLineAPI
、開発者のコンソールに入力された式の評価を防止または変更するために、WebKitブラウザーでInjectedScriptHostに侵入する方法がいくつかあります。
編集:
Chromeはこれを過去のリリースで修正しました。-その時点で要旨を作成したため、2015年2月より前である必要があります。
これが別の可能性です。今回は、直接に、上のレベルにフックInjectedScript
ではなく、InjectedScriptHost
以前のバージョンとは対照的です。
何が起こるかをよりきめ細かく制御できるので、InjectedScript._evaluateAndWrap
依存する代わりに直接パッチをモンキーすることができるので、これは一種のいいですInjectedScriptHost.evaluate
。
別のかなり興味深いことは、式が評価されるときに内部結果をインターセプトして、通常の動作の代わりにユーザーにそれを返すことができることです。
これは、ユーザーがコンソールで何かを評価したときに内部結果を返すコードです。
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);
少し冗長ですが、コメントを入れてみました
したがって、通常、たとえばユーザーが評価した[1,2,3,4]
場合、次の出力が予想されます。
InjectedScript._evaluateAndWrap
まったく同じ式をモンキーパッチで評価すると、次の出力が得られます。
出力を示す小さな左矢印が表示されているように、まだそこにありますが、今度はオブジェクトを取得します。式の結果の場合、配列[1,2,3,4]
はすべてのプロパティが記述されたオブジェクトとして表されます。
エラーを生成するものを含め、これとその式を評価することをお勧めします。なかなか面白いです。
また、見とるis
- InjectedScriptHost
-オブジェクトを。これは、インスペクターを操作し、インスペクターの内部を少し洞察するいくつかのメソッドを提供します。
もちろん、すべての情報を傍受しても、元の結果をユーザーに返すことができます。
elseパスのreturnステートメントをconsole.log (res)
次のa で置き換えるだけですreturn res
。その後、次のようになります。
編集の終わり
これは、Googleによって修正された以前のバージョンです。したがって、もはや可能な方法ではありません。
そのうちの1つは Function.prototype.call
Chromeは、次のようにcall
eval関数を使用InjectedScriptHost
して入力された式を評価しますthisArg
var result = evalFunction.call(object, expression);
これを考えると、あなたがのために聞くことができるthisArg
のcall
であることevaluate
と、最初の引数(への参照を取得します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);
}
};
}
たとえば、評価が拒否されたというエラーをスローできます。
ここで例として入力された式はに渡す前のCoffeeScriptのコンパイラに渡されるevaluate
関数が。