一、hook的作用区域
1、客户端的过程
链接服务器
拿回资源
渲染(解析资源)资源
初始化(自执行)
页面逻辑
等待用户输入
加密数据
提交数据
2、hook的本质
在这些流程任意环节中插入自己的代码,让浏览器限制性自己的代码,然后再执行原本的网站代码。
①:链接服务器 hook能拿到服务器的IP地址,wss的话能后拿到向服务器发送前的参数
②:.拿回资源 hook能修改拿回的资源.
③:渲染 hook能够判定想渲染的东西
④:js初始化 hook能够修改windows的常见变量 浏览器的环境变量 loction.href window.atob, window.btoa
⑤:页面逻辑 在js 的某些内部函数写的 所以会有自己的作用域 作用域->变量生效的位置
⑥:等待用户输入 hook 拿到用户输入 ~ = 事件断点.
⑦:加密数据 hook 拿到明文参数和加密后的参数
二、hook基础
1、上下文
①:同一个一个环境(js 中的v8虚拟机)
②:浏览器中 不同的新页面就是一个新的环境
③:但是js中使用eval执行虽然开了一个新的v8虚拟机,但是还是同一个上下文。
④:新的线程 webwork v8虚拟机是开了多个的v8虚拟机,但是在浏览器看来是一个上下文
2、变量的作用域(生命周期)
①:在同一个上下文环境中。
②:因为javascript是一个弱类型语言,所以在重复定义一个变量的时候不会报错,并且可以在定义变量的时候修改变量的被赋的值
var zhiyuan = 1; var zhiyaun = function(){ var zhiyuan = 2; return zhiyaun } //不会报错,控制台输入zhiyua 对输出对应函数体,输入zhiyuan()返回2
③:解释器执行流程(其实和其他的语言差不多),声明一个全局作用域变量和数组
var zhiyuan = 1; var zhiyaun = function(){ var zhiyuan = 2; return zhiyaun ; } zhiyuan = 3 //解释器 var glArr = {} glArr.zhiyuan = 1; glArr.zz = “CODE” //执行方法(glArr.zz); //进入方法作用域 //声明一个“glArr.zz”方法作用域变量数组 glArr.zz.Arr = {} glArr.zz.Arr.zhiyuan = 2; //输出的时候取当前作用域的值,如果当前没有,那么去上一个作用域找。 //如是果一直没找到,那么就报错not defind //退出方法 //设置当前作用域"Arr" //然后再取当前的作用域
④:在不是全局作用域下 如果赋值语句没有使用var定义而直接赋值.
var zhiyuan = 1; var zhiyaun = function(){ var zhiyuan = 2; zhiyuan1 = 2; return zhiyaun ; } zhiyuan = 3
3、this指向问题
①:全局作用域 this = window
②:在方法作用域(局部作用域) this = 调用者
③:在类(对象)的方法里面 this = 类自己
④:在所有方法下,只要this没有调用者,那么就是执行window
function xxx(){ console.log(this); } xxx();
三、hook实例
1、网页中的js代码
var = 1 loction.xxx = function(){ console.log(this); } zzz = function(){ console.log(this); } zzz(); loction.xxx();
2、hook方法
如果在console中重新定义
loction.xxx(){}
这样并没有效果,因为当页面中的js代码再次被执行的时候就会再次定义xxx();
所以在xxx()函数运行后,被调用前来进行hook可以hook到
即在zzz处打断点,然后控制台重新定义xxx()
3、自执行
!(function(){ var bbb = 2; var zzz = function(){ console.log(bbb) } var rrr = 1; })() var aaa = 111
在var aaa 处打断点不能hook
所以应该在自执行中,函数执行完,没被调用的时候hook
所以断点打在 var rrr = 1
四、hook本质
改变原方法或源代码执行流程
1、覆盖原方法
2、ES6的语法
Object.defineProperty
给对象重新定义属性
能够监听属性的设置值和获取值
js Proxy
给对象整体监听
属性初始化
属性的设置值和获取值
构造函数相关的
3、实例
hook 发包 实现xhr断点的功能
首先找到发包所在的函数
XMLHttpRequests.prototype.send
然后我们保存其原来的值
XMLHttpRequests.prototype.send_ = XMLHttpRequests.prototype.send;
然后我们对XMLHttpRequests.prototype.send改值
XMLHttpRequests.prototype.send = function(){debugger;}
然后进行翻页,就hook到了
此例子是在刷新之后hook到的
(function(){ "use strict"; var cooikeTemp = ""; Object.defineProperty(document,"cookie",{ set: function(val){ if (val.indexOf("v=")) console.log("hook捕获到cookie设置",val); cookieTemp = val; return val; }, get: function() { return cookieTemp; } }); })();
4、hook时机
①:一般只影响hook完成后的操作
②:整个浏览器初始化想进行hook,那么需要插件(油猴)
③:插件(油猴(浏览器插件监听接收数据的方法)、FD插件(代理的方式)修改原数据)
④:如果不想使用插件:首先找到最先运行的js文件,格式化,然后在第一行下断点,然后再在控制台进行手动hook(这样会导致插入的位置不确定)
5、应用
对于不好调试的函数,就可以使用hook进行。或者用来hook变量,扣js代码的时候作为函数的返回值