Bên cạnh việc xác định lại console._commandLineAPI
, có một số cách khác để xâm nhập vào In tiêmScripthost trên trình duyệt WebKit, để ngăn chặn hoặc thay đổi việc đánh giá các biểu thức được nhập vào bảng điều khiển của nhà phát triển.
Biên tập:
Chrome đã sửa lỗi này trong một bản phát hành trước đây. - phải có trước tháng 2 năm 2015, khi tôi tạo ra ý chính tại thời điểm đó
Vì vậy, đây là một khả năng khác. Lần này chúng tôi kết nối, một cấp độ ở trên, trực tiếp vào InjectedScript
chứ không phải InjectedScriptHost
trái ngược với phiên bản trước.
Điều này thật tuyệt, vì bạn có thể trực tiếp vá khỉ InjectedScript._evaluateAndWrap
thay vì phải dựa vào InjectedScriptHost.evaluate
vì điều đó cho phép bạn kiểm soát tốt hơn những gì sẽ xảy ra.
Một điều khá thú vị là, chúng ta có thể chặn kết quả bên trong khi một biểu thức được ước tính và trả lại cho người dùng thay vì hành vi thông thường.
Đây là mã, thực hiện chính xác điều đó, trả về kết quả bên trong khi người dùng đánh giá một cái gì đó trong bảng điều khiển.
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);
Đó là một chút dài dòng, nhưng tôi nghĩ rằng tôi đã đặt một số ý kiến vào nó
Vì vậy, thông thường, nếu người dùng, ví dụ, đánh giá [1,2,3,4]
bạn mong đợi đầu ra sau:
Sau khi kết hợp InjectedScript._evaluateAndWrap
đánh giá biểu thức rất giống nhau, đưa ra kết quả sau:
Như bạn thấy mũi tên nhỏ bên trái, biểu thị đầu ra, vẫn ở đó, nhưng lần này chúng ta có một đối tượng. Trong đó kết quả của biểu thức, mảng [1,2,3,4]
được biểu diễn dưới dạng một đối tượng với tất cả các thuộc tính được mô tả.
Tôi khuyên bạn nên cố gắng đánh giá biểu thức này và biểu thức đó, bao gồm cả những biểu hiện tạo ra lỗi. Nó khá thú vị.
Thêm vào đó, có một cái nhìn tại is
- InjectedScriptHost
- đối tượng. Nó cung cấp một số phương pháp để chơi và có được một chút cái nhìn sâu sắc về nội bộ của thanh tra.
Tất nhiên, bạn có thể chặn tất cả thông tin đó và vẫn trả lại kết quả ban đầu cho người dùng.
Chỉ cần thay thế câu lệnh return trong đường dẫn khác bằng cách console.log (res)
sau a return res
. Sau đó, bạn sẽ kết thúc với những điều sau đây.
Kết thúc chỉnh sửa
Đây là phiên bản trước đó đã được Google sửa. Do đó không phải là một cách có thể nữa.
Một trong số đó là móc vào Function.prototype.call
Chrome đánh giá biểu thức nhập vào bởi call
ing chức năng eval với InjectedScriptHost
nhưthisArg
var result = evalFunction.call(object, expression);
Vì điều này, bạn có thể nghe cho thisArg
của call
con người evaluate
và có được một tham chiếu đến đối số đầu tiên ( 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);
}
};
}
Ví dụ, bạn có thể đưa ra một lỗi, rằng đánh giá đã bị từ chối.
Dưới đây là một ví dụ trong đó biểu thức đã nhập được chuyển đến trình biên dịch CoffeeScript trước khi chuyển nó vào evaluate
hàm.