爬虫逆向学习(三):Hook让你快速定位网站逆向疑难杂症

Hook定义

Hook 技术又叫做钩子函数,在系统没有调用该函数之前,钩子程序就先捕获该消息,钩子函数先得到控制权,这时钩子函数既可以加工处理(改变)该函数的执行行为,还可以强制结束消息的传递。简单来说,就是把系统的程序拉出来变成我们自己执行代码片段。

hook的目的

现在很多网站js都使用了混淆,我们没法直接通过查找的方式定位参数生成位置,js hook能帮助我们找到函数入口以及一些参数变化,便于分析js逻辑,对于爬虫只借助其寻找函数入口。

Hook使用步骤

  1. 明确要定位的参数类型
  2. 编写hook逻辑
  3. 调试代码确定hook成功

Hook函数公式

old_func = funcfunc =function(argument){
  mytask;
  returnold_func.apply(argument)
}
func.prototype.....= .......

// func :要hook的函数

常用Hook方式

对象中属性

old_attr = obj.attrObject.defineProperty(obj, 'attr', {
       get: function() {
            console.log(cookie_cache);
            return old_attr 
  },
       set: function(val) {
   return ......
}

eval/Function

# eval/Function
window.__cr_eval = window.eval
​
// 捕捉到debugger位置
var myeval = function (src) {
    console.log("============ eval begin: length=" + src.length + ",caller=" + (myeval.caller && myeval.caller.name) + " ===============")
    console.log(">>>>>>>>>>>> eval injected: " + document.location + " <<<<<<<<<<<<<<<<")
    console.log(src);
    console.log("============ eval end =============")
    return window.__cr_eval(src)
}// 会有一些反爬会识别是不是本机代码,这个地方是小花招本招,防止被识别
var _myeval = myeval.bind(null)
_myeval.toString = window.__cr_eval.toString
Object.defineProperty(window, 'eval', { value: myeval })

Cookie

// 捕捉window参数写入位置
(function() {
    //document 为要hook的对象   这里是hook的cookie
     var cookieTemp = "";
    Object.defineProperty(document, 'cookie', {
        //hook set方法也就是赋值的方法 
        set: function(val) {
            //这样就可以快速给下面这个代码行下断点
            //从而快速定位设置cookie的代码
            console.log('Hook捕获到cookie设置->', val);
            cookieTemp = val;
            debugger;
            return val;
        },
        //hook get方法也就是取值的方法 
        get: function()
        {
            return cookieTemp;
        }
    });
})();

header 参数

//方式一:
var code = function(){
    var org = window.XMLHttpRequest.prototype.setRequestHeader;
    window.XMLHttpRequest.prototype.setRequestHeader = function(key,value){
        if(key=='Authorization'){
            debugger;
        }
        return org.apply(this,arguments);
    }
}
var script = document.createElement('script');
script.textContent = '(' + code + ')()';
(document.head||document.documentElement).appendChild(script);
script.parentNode.removeChild(script);

// 方式二
(function () {
    var org = window.XMLHttpRequest.prototype.setRequestHeader;
    window.XMLHttpRequest.prototype.setRequestHeader = function (key, value) {
        if (key == 'Authorization') {
            debugger;
        }
        return org.apply(this, arguments);
    };
})();

关闭alert

var _alert=window.alert

window.alert = function() {
  return true;
}

url

(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);
    };
})();

JSON.stringify

(function() {
    var stringify = JSON.stringify;
    JSON.stringify = function(params) {
        console.log("Hook JSON.stringify ——> ", params);
        debugger;
        return stringify(params);
    }
})();

JSON.parse

(function() {
    var parse = JSON.parse;
    JSON.parse = function(params) {
        console.log("Hook JSON.parse ——> ", params);
        debugger;
        return parse(params);
    }
})();

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
    });
})();

对象操作

如果想动态操作某个对象,可以参考下面这种方式
用途:将值与a对象的href进行网址动态拼接

a = {
    'href': ""
}

var join_url;
Object.defineProperty(a, 'href', {
    set: function(val) {
        if (val.startsWith('http')) {
            join_url = val;
        } else {
            let baseURL = new URL('');
            baseURL.pathname = val;
            join_url = baseURL.toString();
        }
        return join_url;
    },
    get: function()
    {
        return join_url;
    }
});
posted @ 2023-04-05 15:06  七夜魔手  阅读(24)  评论(0编辑  收藏  举报  来源