参照:
一、常用Hook
1. eval
(function() {
let _eval = eval;
eval = function(val) {
if (val.indexof('debugger') === -1) {
_eval_cache(obj);
}
}
})();
2. JSON.parse()
(function () {
var parse_ = JSON.parse;
JSON.parse = function (arg) {
console.log(arg);
debugger;
return parse_(arg);
};
})();
3.JSON.stringify
JSON.stringify()
方法用于将 JavaScript 值转换为 JSON 字符串,在某些站点的加密过程中可能会遇到,以下代码演示了遇到 JSON.stringify()
时,则插入断点:
(function() {
var stringify = JSON.stringify;
JSON.stringify = function(params) {
console.log("Hook JSON.stringify ——> ", params);
debugger;
return stringify(params);
}
})();
3.XMLHttpRequest(URL)
一般获取请求中的参数
(function () {
var _open = window.XMLHttpRequest.prototype.open;
window.XMLHttpRequest.prototype.open = function (method, url, async) {
if (url.indexOf("参数名称") != -1) {
debugger;
}
return _open.apply(this, arguments);
};
})();
4.XMLHttpRequest(Header)
一般获取header中的参数
(function () {
var _setRequestHeader = window.XMLHttpRequest.prototype.setRequestHeader;
window.XMLHttpRequest.prototype.setRequestHeader = function (key, value) {
if (key == "header 的参数 key") {
debugger;
}
return open.apply(this, arguments);
};
})();
5.cookie
(function() {
var cookieTemp = '';
Object.defineProperty(document, 'cookie', {
set: function (val) {
if (val.indexOf('cookie 关键字') != -1) {
debugger;
}
console.log(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;
});
})();
6. Function
(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中对原生函数native属性的检测
myfun.toString = function() {
return window.__cr_fun + ""
}
Object.defineProperty(window, 'Function', {
value: myfun
});
})();
二、无限 debugger
debugger 使用 Function.constructor / setInterval / eval
1. setInterval
比如setInterval(function () { debugger; }, 500);
1. 方法置空
setInterval = function() {};
2.eval
//通常以下代码是加密构造出来的, eval 执行的是一个字符串变量。
eval("debugger;")
eval("(function() {var a = new Date(); debugger; return new Date() - a > 100;}())")
1.使用字符串 replace("debugger;"," ") 方法,进行替换 debugger ,为防止对字符串进行长度检测,常常使用等长的空格替换
2.Hook
(function() {
var _eval = eval;
eval = function(val) {
if (val.indexof('debugger') === -1) {
_eval_cache(obj);
}
}
})();
3.置空
eval = function() {};
3.Function
// 常见形式
Function('debugger')()
(function(){return false;})['constructor']('debugger')['call']();
xxx.constructor("debugger").call("action")
1. Hook
Function.prototype.__constructor_back = Function.prototype.constructor;
Function.prototype.constructor = function() {
if(arguments && typeof arguments[0]==='string'){
//alert("new function: "+ arguments[0]);
if("debugger" === arguments[0]){
//arguments[0]="console.log(\"anti debugger\");";
//arguments[0]=";";
return;
}
}
return Function.prototype.__constructor_back.apply(this,arguments);
}
三、Object.defineProperty()
基本语法:Object.defineProperty(obj, prop, descriptor)
,它的作用就是直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,接收的三个参数含义如下:
obj
:需要定义属性的当前对象;
prop
:当前需要定义的属性名;
descriptor
:属性描述符,可以取以下值:
属性名 | 默认值 | 含义 |
---|---|---|
get | undefined | 存取描述符,目标属性获取值的方法 |
set | undefined | 存取描述符,目标属性设置值的方法 |
value | undefined | 数据描述符,设置属性的值 |
writable | false | 数据描述符,目标属性的值是否可以被重写 |
enumerable | false | 目标属性是否可以被枚举 |
configurable | false | 目标属性是否可以被删除或是否可以再次修改特性 |
通常情况下,对象的定义与赋值是这样的:
var people = {}
people.name = "Bob"
people["age"] = "18"
console.log(people)
输出{ name: 'Bob', age: '18' }
使用 Object.defineProperty() 方法:
var people = {}
Object.defineProperty(people, 'name', {
value: 'Bob',
writable: true // 是否可以被重写
})
//这个是重写了people的name方法
console.log(people.name) // 'Bob'
people.name = "Tom"
console.log(people.name) // 'Tom'
在 Hook 中,使用最多的是存取描述符,即 get 和 set。
get:属性的 getter 函数,如果没有 getter,则为 undefined,当访问该属性时,会调用此函数,执行时不传入任何参数,但是会传入 this 对象(由于继承关系,这里的 this 并不一定是定义该属性的对象),该函数的返回值会被用作属性的值。
set:属性的 setter 函数,如果没有 setter,则为 undefined,当属性值被修改时,会调用此函数,该方法接受一个参数,也就是被赋予的新值,会传入赋值时的 this 对象。
用一个例子来演示:
var people = {
name: 'Bob',
};
var count = 18;
// 定义一个 age 获取值时返回定义好的变量 count
Object.defineProperty(people, 'age', {
get: function () {
console.log('获取值!');
return count;
},
set: function (val) {
console.log('设置值!');
count = val + 1;
},
});
console.log(people.age);
people.age = 20;
console.log(people.age);