JavaScript中11種常用的hook鉤子技術(shù)及示例代碼
我們前端的JavaScript中,經(jīng)常提到鉤子,Hook技術(shù)又叫鉤子技術(shù),指在程序運(yùn)行過(guò)程中,對(duì)其中某個(gè)方法進(jìn)行重寫,在原先某個(gè)方法前后加入我們自定義的代碼。我們的鉤子,鉤子機(jī)制,鉤子函數(shù),hook,都是同一個(gè)概念。
對(duì)于Windows系統(tǒng),它是建立在事件驅(qū)動(dòng)機(jī)制上的,說(shuō)白了就是整個(gè)系統(tǒng)都是通過(guò)消息傳遞實(shí)現(xiàn)的。hook(鉤子)是一種特殊的消息處理機(jī)制,它可以監(jiān)視系統(tǒng)或者進(jìn)程中的各種事件消息,截獲發(fā)往目標(biāo)窗口的消息并進(jìn)行處理。用來(lái)監(jiān)視系統(tǒng)中特定事件的發(fā)生,完成特定功能,如屏幕取詞,監(jiān)視日志,截獲鍵盤、鼠標(biāo)輸入等等。
開(kāi)發(fā)者經(jīng)常使用一些用于hook(鉤子)的技術(shù)來(lái)監(jiān)視或修改程序的行為。下面是常用的hook技術(shù)及示例代碼
1、dom操作
在JS逆向油猴腳本中,DOM操作是最常用的一種Hook方式。通過(guò)修改DOM元素的屬性和樣式,我們可以實(shí)現(xiàn)對(duì)網(wǎng)頁(yè)的控制和修改。
// 修改DOM元素的屬性
document.getElementById('elementId').setAttribute('attrName', 'attrValue');
// 修改DOM元素的樣式
document.getElementById('elementId').style.property = 'value';2、Cookie操作
Cookie Hook 用于定位 Cookie 中關(guān)鍵參數(shù)生成位置,以下代碼演示了當(dāng) Cookie 中匹配到了 __dfp 關(guān)鍵字, 則插入斷點(diǎn):
(function () {
'use strict';
var cookieTemp = '';
Object.defineProperty(document, 'cookie', {
set: function (val) {
if (val.indexOf('__dfp') != -1) {
debugger;
}
console.log('Hook捕獲到cookie設(shè)置->', val);
cookieTemp = val;
return val;
},
get: function () {
return cookieTemp;
},
});
})();
(function () {
'use strict';
var org = document.cookie.__lookupSetter__('cookie');
document.__defineSetter__('cookie', function (cookie) {
if (cookie.indexOf('__dfp') != -1) {
debugger;
}
org = cookie;
});
document.__defineGetter__('cookie', function () {
return org;
});
})();3、事件監(jiān)聽(tīng)操作
事件監(jiān)聽(tīng)也是JS逆向油猴腳本中常用的一種Hook方式。通過(guò)監(jiān)聽(tīng)網(wǎng)頁(yè)上的事件,我們可以觸發(fā)自定義的操作和行為。
// 監(jiān)聽(tīng)按鈕點(diǎn)擊事件
document.getElementById('buttonId').addEventListener('click', function() {
// 自定義操作和行為
});4、AJAX攔截操作
AJAX攔截也是JS逆向油猴腳本中常用的一種Hook方式。通過(guò)攔截網(wǎng)頁(yè)上的AJAX請(qǐng)求,我們可以實(shí)現(xiàn)對(duì)數(shù)據(jù)的控制和修改。
// 攔截AJAX請(qǐng)求
XMLHttpRequest.prototype._send = XMLHttpRequest.prototype.send;
XMLHttpRequest.prototype.send = function() {
// 自定義操作和行為
this._send.apply(this, arguments);
};5、函數(shù)替換操作
函數(shù)替換也是JS逆向油猴腳本中常用的一種Hook方式。通過(guò)替換網(wǎng)頁(yè)上的函數(shù),我們可以實(shí)現(xiàn)對(duì)函數(shù)的控制和修改。
// 替換原有函數(shù)
var originalFunction = window.functionName;
window.functionName = function() {
// 自定義操作和行為
originalFunction.apply(this, arguments);
};6、Header操作
Header Hook 用于定位 Header 中關(guān)鍵參數(shù)生成位置,以下代碼演示了當(dāng) Header 中包含 Authorization 關(guān)鍵字時(shí),則插入斷點(diǎn):
(function () {
var org = window.XMLHttpRequest.prototype.setRequestHeader;
window.XMLHttpRequest.prototype.setRequestHeader = function (key, value) {
if (key == 'Authorization') {
debugger;
}
return org.apply(this, arguments);
};
})()7、URL操作
URL Hook 用于定位請(qǐng)求 URL 中關(guān)鍵參數(shù)生成位置,以下代碼演示了當(dāng)請(qǐng)求的 URL 里包含 login 關(guān)鍵字時(shí),則插入斷點(diǎn):
(function () {
var open = window.XMLHttpRequest.prototype.open;
window.XMLHttpRequest.prototype.open = function (method, url, async) {
if (url.indexOf("login") != 1) {
debugger;
}
return open.apply(this, arguments);
};
})();8、JSON.stringify操作
JSON.stringify() 方法用于將 JavaScript 值轉(zhuǎn)換為 JSON 字符串,在某些站點(diǎn)的加密過(guò)程中可能會(huì)遇到,以下代碼演示了遇到 JSON.stringify() 時(shí),則插入斷點(diǎn):
(function() {
var stringify = JSON.stringify;
JSON.stringify = function(params) {
console.log("Hook JSON.stringify ——> ", params);
debugger;
return stringify(params);
}
})();9、JSON.parse操作
JSON.parse() 方法用于將一個(gè) JSON 字符串轉(zhuǎn)換為對(duì)象,在某些站點(diǎn)的加密過(guò)程中可能會(huì)遇到,以下代碼演示了遇到 JSON.parse() 時(shí),則插入斷點(diǎn):
(function() {
var parse = JSON.parse;
JSON.parse = function(params) {
console.log("Hook JSON.parse ——> ", params);
debugger;
return parse(params);
}
})();10、eval操作
JavaScript eval() 函數(shù)的作用是計(jì)算 JavaScript 字符串,并把它作為 腳本代碼來(lái)執(zhí)行。如果參數(shù)是一個(gè)表達(dá)式,eval() 函數(shù)將執(zhí)行表達(dá)式。如果參數(shù)是 Javascript 語(yǔ)句,eval() 將執(zhí)行 Javascript 語(yǔ)句,經(jīng)常被用來(lái)動(dòng)態(tài)執(zhí)行 JS。以下代碼執(zhí)行后,之后所有的 eval() 操作都會(huì)在控制臺(tái)打印輸出將要執(zhí)行的 JS 源碼:
(function() {
// 保存原始方法
window.__cr_eval = window.eval;
// 重寫 eval
var myeval = function(src) {
console.log(src);
console.log("=============== eval end ===============");
debugger;
return window.__cr_eval(src);
}
// 屏蔽 JS 中對(duì)原生函數(shù) native 屬性的檢測(cè)
var _myeval = myeval.bind(null);
_myeval.toString = window.__cr_eval.toString;
Object.defineProperty(window, 'eval', {
value: _myeval
});
})();11、Function操作
以下代碼執(zhí)行后,所有的函數(shù)操作都會(huì)在控制臺(tái)打印輸出將要執(zhí)行的 JS 源碼:
(function() {
// 保存原始方法
window.__cr_fun = window.Function;
// 重寫 function
var myfun = function() {
var args = Array.prototype.slice.call(arguments, 0, -1).join(","),
src = arguments[arguments.length - 1];
console.log(src);
console.log("=============== Function end ===============");
debugger;
return window.__cr_fun.apply(this, arguments);
}
// 屏蔽js中對(duì)原生函數(shù)native屬性的檢測(cè)
myfun.toString = function() {
return window.__cr_fun + ""
}
Object.defineProperty(window, 'Function', {
value: myfun
});
})();12、總結(jié)
到此這篇關(guān)于JavaScript中11種常用的hook鉤子技術(shù)及示例代碼的文章就介紹到這了,更多相關(guān)js常用的hook技術(shù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
通過(guò)循環(huán)優(yōu)化 JavaScript 程序
這篇文章主要介紹了通過(guò)循環(huán)優(yōu)化 JavaScript 程序,對(duì)于提高 JavaScript 程序的性能這個(gè)問(wèn)題,最簡(jiǎn)單同時(shí)也是很容易被忽視的方法就是學(xué)習(xí)如何正確編寫高性能循環(huán)語(yǔ)句。下面我們來(lái)學(xué)習(xí)一下吧2019-06-06
JavaScript在IE和Firefox上的差異及相互替代的實(shí)現(xiàn)方法
我們經(jīng)常在處理ie和firefox下的js總會(huì)碰到一些兼容問(wèn)題,下面是些總結(jié),希望大家仔細(xì)看看研究2008-06-06
HTML+JS實(shí)現(xiàn)監(jiān)控切屏功能
這篇文章主要介紹了如何利用HTML和JavaScript實(shí)現(xiàn)監(jiān)控切屏功能,監(jiān)控是否離開(kāi)當(dāng)前頁(yè)面,文中的示例代碼講解詳細(xì),需要的可以參考一下2022-03-03
解決js數(shù)據(jù)包含加號(hào)+通過(guò)ajax傳到后臺(tái)時(shí)出現(xiàn)連接錯(cuò)誤
測(cè)試過(guò)程中發(fā)現(xiàn)js數(shù)據(jù)包含加號(hào)+通過(guò)ajax傳到后臺(tái)時(shí)出現(xiàn)連接錯(cuò)誤,刪除+,鏈接暢通了,果然是這塊問(wèn)題,對(duì)加號(hào)進(jìn)行轉(zhuǎn)義2013-08-08
HTA版JSMin(省略修飾語(yǔ)若干)基于javascript語(yǔ)言編寫

