zl程序教程

您现在的位置是:首页 >  前端

当前栏目

JavaScript高级编程:函数Hook与反Hook

JavaScript编程 函数 高级 hook
2023-06-13 09:18:47 时间

JavaScript高级编程:函数Hook与反Hook

作者:专注于JS混淆加密的JShaman

API HOOK技术,在PC时代曾盛行,是高端的技术。在JavaScript编程中,也可以应用API Hook技术实现不寻常的效果。

例,eval hook:

<html>
<script>
//备份原window.eval函数
var _eval = window.eval;
//eval的hook函数
window.eval = function(src){
console.log("eval要执行的代码:",src);
return _eval(src);
}
eval("console.log('eval hook')");
</script>
</html>

运行效果

还有一种写法:Object.defineProperty(object, prop, descript);

此方法会在一个对象上定义一个新属性,或者修改一个对象的现有属性。

参数说明:

object:要添加或者修改属性的目标对象;

prop:要定义或修改属性的名称;

descript:属性描述符,常用get、set、value以获取、设置属性值或赋值。

上面的eval hook改成这种写法:

<html>
<script>
var _eval = window.eval;
Object.defineProperty(window, "eval", {
value:function(src){
console.log("eval要执行的代码:",src);
return _eval(src);
}
});
eval("console.log('eval hook')");
</script>
</html>

Hook有什么用途呢?

比如,可以用于实现cookie加密,代码如下:

<html>
<script>
(function() {
var document_cookie = document.cookie;
Object.defineProperty(document, "cookie", {
get: function() {
console.log("读取到cookie:", document_cookie);
var encode_value = document_cookie.split("").reverse().join("");
console.log("cookie值已解密", document_cookie, "变成", encode_value);
return encode_value;
},
set: function(value) {
console.log("写cookie,原始值:",value );
var encode_value = value.split("").reverse().join("");
console.log("cookie值已加密",value,"变成",encode_value);
document_cookie = value.split("").reverse().join("");
console.log("cookie已写入")
},
});
})();
document.cookie = "jshaman.com";
console.log("cookie加解密测试", document.cookie);
</script>
</html>

运行效果

那么,如何反Hook呢?

代码如下:

<html>
<script>
(function(){
console.log(eval.toString());
//备份原window.eval函数
var _eval = window.eval;
//eval的hook函数
window.eval = function(src){
console.log("eval要执行的代码:",src);
return _eval(src);
}
console.log(eval.toString());
if(eval.toString().indexOf("[native code]") != -1){
eval("console.log('eval hook');");
}else{
console.log("eval 被hook了,不执行正常代码")
}
})();
</script>
</html>

即:正常的eval函数,toString()后,会输出:

function eval() { [native code] }

但如果被Hook,Hook函数必然不是这样的,如本文示例,它会是:

function(src){ console.log("eval要执行的代码:",src); return _eval(src); }

那么当未检测到“[native code]”时,即表示被Hook了。

运行效果:

还有一种方法,代码如下:

<html>
<script>
(function(){
console.log(eval.toString());
//备份原window.eval函数
var _eval = window.eval;
//直接调用原始函数
_eval("console.log('eval hook');");
//eval的hook函数
window.eval = function(src){
console.log("eval要执行的代码:",src);
return _eval(src);
}
console.log(eval.toString());
})();
</script>
</html>

即:直接调用eval函数的备份函数,使hook函数无用武之地。

运行效果: