hook大致上分为三种方式。
第一种,在 JS 逆向中,我们通常把替换原函数的过程都称为 Hook(一般是hook一些基本内置函数)。
直接上案例。
Hook eval函数
var _eval = eval
eval = function (src) {
console.log("eval截断开始...")
debugger;
_eval.apply(this, src)
console.log("eval截断结束...")
}
Hook JSON.stringify
(function() {
var stringify = JSON.stringify;
JSON.stringify = function(params) {
console.log("Hook JSON.stringif:::", params);
debugger;
return stringify(params);
}
})()
Hook JSON.parse
(function() {
var parse = JSON.parse;
JSON.parse = function(params) {
console.log("Hook JSON.parse::: ", params);
debugger;
return parse(params);
}
})()
第二种,使用Object.defineProperty()来进行属性操作的hook。
Object.defineProperty(obj, prop, descriptor)
// 参数
obj:对象;
prop:对象的属性名;
descriptor:属性描述符;
通过这样的方法,我们就可以在设置某个值的时候,添加一些代码,比如 debugger;,让其断下,然后利用调用栈进行调试,找到参数加密、或者参数生成的地方,需要注意的是,网站加载时首先要运行我们的 Hook 代码,再运行网站自己的代码,才能够成功断下,这个过程我们可以称之为 Hook 代码的注入
一般hook使用的是get和set方法,下边简单演示一下
(function(){
'use strict'
var _cookie = "";
Object.defineProperty(document, 'cookie', {
set: function(val) {
console.log(val);
debugger
_cookie = val;
return val;
},
get: function() {
return _cookie;
},
});
})()
第三种,利用proxy代理对象做一个对象的拦截。
new Proxy(target, handler)
是 JavaScript 中的一个内置对象和特性,用于创建一个代理对象,可以拦截并自定义对目标对象的操作。
当你使用 new Proxy
创建一个代理对象时,你需要传入两个参数:
-
target
:要代理的目标对象,可以是任何 JavaScript 对象(包括函数、数组等)。 -
handler
:一个处理程序对象,其中定义了拦截目标对象操作的方法(也称为“陷阱”)。
代理对象会封装目标对象,并可以拦截和处理对目标对象的操作,例如属性访问、函数调用、赋值等。你可以在 handler
中定义各种陷阱方法,用于自定义处理这些操作。
通过在这些陷阱方法中编写自定义的逻辑,你可以对目标对象的操作进行修改、拦截、记录或验证等。这使得 Proxy
对象非常适合用于实现代理模式、数据验证、日志记录等应用场景。
function get_proxy(obj, obj_name) {
obj = new Proxy(obj, {
get: function (target, property1) {
console.log('获取对象-->', obj_name, '属性-->', property1, '值-->', target[property1])
//debugger
return Reflect.get(target, property1)
},
set: function (target, property1, value) {
console.log('设置对象-->', obj_name, '属性-->', property1, '值-->', target[property1])
//debugger
Reflect.set(target, property1, value)
}
})
return obj;
}
window = get_proxy(window, 'window')