第9章 day09 hook插件

news/2025/9/29 17:07:37/文章来源:https://www.cnblogs.com/fuminer/p/19119130

二. hook插件

1.概念

在JavaScript中,hook是一种能够拦截和修改函数或方法行为的技术。通过使用hook,开发者可以在现有的函数执行前、执行后或者替换函数的实现逻辑。hook目的是找到函数入口以及一些参数变化,便于分析js逻辑。

2.hook的作用:

  1. 增强代码的可扩展性:Hook技术允许开发者在不修改原始代码的情况下,增加或修改功能,使得代码更加灵活和可扩展。
  2. 减少代码的侵入性:使用hook可以在不改变原始代码的前提下增加新功能,这减少了对原始代码的侵入,使得添加的功能更容易被管理和维护。
  3. 便于调试和问题定位:利用hook技术可以在函数执行前后插入调试信息,帮助开发者更好地理解程序执行流程和定位问题源头。

3. hook基本使用

3.1 函数的hook
  • 定义函数
// 定义函数
function add(a,b){console.log("add方法正在执行");return a+b;
}
  • 保存原函数,目的是为了不修改原函数内部的实现
_add = add;
  • 对add函数进行hook(进行相关的日志输出)
    • hook的位置必须是加载完需要hook的函数(原函数)后
add = function(a,b){console.log("原函数调用前, 参数:", a, b);let result = _add(a,b)console.log("原函数调用后, 结果:", result);return result;
}
  • 调用函数
add(1,2)
3.2 对象属性的hook
//1、创建一个对象
let user = {"name": "波波",
};//2、保存原属性
_name = user.name;//3、对象属性的hook
//defineProperty函数用来重新定义对象的属性。
//参数1:对象。参数2:属性。参数3:属性描述符
Object.defineProperty(user, "name",{get(){ // 获取属性值的时候执行console.log("正在获取属性值");return _name;},set(value){ // 设置属性值的时候执行console.log("正在设置属性值:", value);_name = value;}
});//4、获取属性和设置属性操作
console.log(user.name)
user.name = 'Jay'
console.log(user.name)

如果对象没有/不存在的属性可以被hook吗?

//1、创建一个对象
let user = {"name": "波波",
};//2、保存原属性
_age = 18;//3、对象属性age的hook
Object.defineProperty(user, "age",{get(){ console.log("正在获取属性值");return _age;},set(value){ console.log("正在设置属性值:", value);_age = value;}
});//4、获取属性和设置属性操作
console.log(user.age)
user.age = 20
console.log(user.age)
3.3 浏览器环境下atob函数的hook

atob函数是浏览器环境自带的用来对base64数据进行解编码。接下来,使用对atob函数进行hook。

  • hook时机:在浏览器页面加载出来之前进行hook

    • 1.在一个空白页面打开浏览器开发者工具

    • 2.开启js的事件监听器

      Snipaste_2024-07-06_09-52-59
    • 3.访问百度页面,会有断点停留

    • 4.在Sources中的Snippets代码段中新增hook代码片段,打上断点,然后运行

      • 编写hook操作:

         _atob = atob;//保存原函数atob = function (str){console.log("正在执行atob方法, 参数:", str);let result = _atob(str);console.log("正在执行atob方法, 返回值:", result);return result;
        }
        

      ![Snipaste_2024-07-28_09-13-38](笔记2 - 副本.assets/Snipaste_2024-07-28_09-13-38.png)

  • 5.查看hook运行,监控atob函数的执行

    • 取消事件监听器中的Script,因为此时已经成功对atob函数进行了hook(不可刷新页面)

      Snipaste_2024-07-06_10-17-16

3.4 浏览器环境下cookie的hook

  • 操作步骤如步骤:3.3
_cookie = document.cookie;
Object.defineProperty(document,'cookie',{get(){console.log("正在获取cookie:", _cookie);return _cookie;},set(value){console.log("正在设置cookie:", value);_cookie = value;}
});
3.4 hook检测与破解检测

一些网站会严格检测该网站中的先关函数或者属性是否被一些别有用心的人进行hook。那么检测方式是什么呢?我们又该如何破解该种检测呢?

  • toString() 检测法

    • atob原函数的toString() 结果为:

      Snipaste_2024-07-06_10-48-42
    • atob被hook后的toString() 结果为:

      Snipaste_2024-07-06_10-51-28
    • 结果:两个atob的toString返回的结果是不一样的。

    什么是native?- 在js中,一些内置函数如toString或者atob等函数的函数实现会被显示为[native code],而不是显示实现的具体代码。这样的操作对于提高代码的安全性和封装性有一定的作用。
    
  • toString() 检测法的破解

    • 在hook中重写atob函数的toStirng方法:
    _atob = atob;//保存原函数atob = function (str){console.log("正在执行atob方法, 参数:", str);let result = _atob(str);console.log("正在执行atob方法, 返回值:", result);return result;
    }
    //重写atob函数的toString方法
    atob.toString = function(){return 'function atob() { [native code] }'
    }
    
  • 原型链上的toString()检测法

    Function.prototype.toString.call(atob)
    //调用函数原型对象中的toString进行的检测,而不是atob实例对象的toString了。
    
  • 原型链上的toString()检测法的破解

    • 在hook中重写原型链上的toString()方法:
    _atob = atob;//保存原函数atob = function (str){console.log("正在执行atob方法, 参数:", str);let result = _atob(str);console.log("正在执行atob方法, 返回值:", result);return result;
    }
    //重写原型链上的toString方法
    Function.prototype.toString = function(){return `function ${this.name}() { [native code] }`
    }//this.name就是toString的调用者的名字,比如Location.toString,则this.name就是Location,如果将this.name直接换成atob的话,则以后任何调用者调用toString的话,则返回的function后面的名字就都是atob了。也就是如果Location.toString()返回的也是:function atob() { [native code] }
    

三. proxy代理机制

1. 概念

JavaScript中的Proxy是一种内置对象,它允许你在访问或操作对象之前拦截和自定义底层操作的行为。通过使用Proxy,你可以修改对象的默认行为,添加额外的逻辑或进行验证,以实现更高级的操作和控制。

Proxy对象包装了另一个对象(目标对象),并允许你定义一个处理程序(handler)来拦截对目标对象的操作。处理程序是一个带有特定方法的对象,这些方法被称为"捕获器"(traps),它们会在执行相应的操作时被调用。

2. 代理操作

  • 给User对象设置代理,监控该对象 “已有/存在” 属性值的相关操作
//创建user对象
var User = {username: "bobo",age: 20
}
//创建代理对象,Proxy的参数1:被代理对象。参数2:处理器
User = new Proxy(User, {//target:被代理对象。p:属性。receiver:代理后的对象就是Userget(target, p, receiver) {console.log(`获取属性${p}操作`)//返回代理对象的p属性值return Reflect.get(target, p);},set(target, p, value, receiver) {console.log(`设置属性${p}操作`)Reflect.set(target, p, value);}
});console.log(User.username);
console.log(User.age);
User.username = "Jay"
User.age = 18
console.log(User.username);
console.log(User.age);
  • 给User对象设置代理,监控该对象 “不存在” 属性值的相关操作
//创建user对象
var User = {username: "bobo",age: 20
}User = new Proxy(User, {get(target, p, receiver) {console.log(`获取属性${p}操作`)return Reflect.get(target, p);},set(target, p, value, receiver) {console.log(`设置属性${p}操作`)Reflect.set(target, p, value);}
});console.log(User.username);
console.log(User.age);
console.log(User.address);

​ 输出结果为:Snipaste_2024-07-06_12-43-54说明该对象中不存在address这个属性值,则需要给该对象进行address属性的补充。同理可以作用在逆向的补环境中,例如:对window对象进行代理时,发现window的xxx属性返回的是空,则需要在逆向js代码中的window对象中补上xxx属性即可。

3. 属性描述符

  • getOwnPropertyDescriptor对象属性的获取

有些时候,一些网站的js中是通过属性描述符的方式获取一个对象的属性值。如下所示:

var Stu = {"name":"小明"
};
//通过属性描述符获取Stu对象中的name属性值
console.log(Object.getOwnPropertyDescriptor(Stu, "name"));

那么,这个时候我们该如何通过代理去监控通过属性描述符对属性进行的操作行为呢?(拦截获取属性描述符)

//创建user对象
var User = {username: "bobo",age: 20,address:"Bj"
}User = new Proxy(User, {get(target, p, receiver) {console.log(`获取属性${p}操作`)return Reflect.get(target, p);},set(target, p, value, receiver) {console.log(`设置属性${p}操作`)Reflect.set(target, p, value);},getOwnPropertyDescriptor(target, p){let result;result = Reflect.getOwnPropertyDescriptor(target, p);console.log(`通过属性描述符获取属性${p}操作`)return result;}
});//测试
console.log(User.username);
User.age = 30;
console.log(Object.getOwnPropertyDescriptor(User, "address").value);
  • defineProperty对象属性的定义

有些时候,一些网站的js中是通过属性描述符的方式对属性值的定义。如下所示:

var Person = {};// 通过属性描述符给Person对象定义一个name属性
Object.defineProperty(Person, 'name', {value: 'Bobo',writable: true, // 允许修改属性值enumerable: true, // 允许枚举属性configurable: true // 允许删除或修改属性描述符}
);
console.log(Person)

那么,这个时候我们该如何通过代理去监控通过属性描述符对属性进行的定义行为呢?(拦截属性定义)

var Person = {};Person = new Proxy(Person, {get(target, p, receiver) {console.log(`获取属性${p}操作`)return Reflect.get(target, p);},set(target, p, value, receiver) {console.log(`设置属性${p}操作`)Reflect.set(target, p, value);},getOwnPropertyDescriptor(target, p){let result;result = Reflect.getOwnPropertyDescriptor(target, p);console.log(`通过属性描述符获取属性${p}操作`)return result;},defineProperty: function (target, p, descriptor){console.log(`通过属性描述符设置属性${p}操作`)let result;result = Reflect.defineProperty(target, p, descriptor); return result;}});// 通过属性描述符给Person对象定义一个name属性
Object.defineProperty(Person, 'name', {value: 'Bobo',writable: true, // 允许修改属性值enumerable: true, // 允许枚举属性configurable: true // 允许删除或修改属性描述符}
);
console.log(Person)

4. 函数调用拦截监控

拦截监控指定函数的调用

add = function(a,b){console.log("add函数正在被调用");return a+b;
}
add = new Proxy(add, {apply:function (target, thisArg, argList){// target: 函数对象。thisArg: 调用函数的this指针。argList:函数参数数组let result;result = Reflect.apply(target, thisArg, argList);console.log(`${target.name}函数被调用,参数为:${argList}`);return result;}
});
add(1,2);

5. 对象构造方法拦截监控

拦截new关键字。基于new创建的对象就是在调用该对象的构造方法。

function Animal(){}
Animal = new Proxy(Animal, {construct:function (target, argArray, newTarget) {//target: 函数对象。argArray: 参数列表。newTarget: 代理后的对象let result = Reflect.construct(target, argArray, newTarget);console.log(`${target.name}对象被创建`);return result;}
});
animal = new Animal();

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/922029.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

nginx 一致性hash和流量检查模块

nginx-module-vts:这是一个Nginx的监控模块,能够收集Nginx自身详细的虚拟主机流量状态信息,如请求次数、响应字节、响应时间等,并以JSON、HTML或Prometheus格式输出。nginx-vts-exporter依赖于这个模块。nginx-vts…

网站开发的试用期条款疏肝益阳胶囊有哪些功效与作用

阿里妹导读:日常工作中,我们多少都会遇到应用的性能问题。在阿里面试中,性能优化也是常被问到的题目,用来考察是否有实际的线上问题处理经验。面对这类问题,阿里工程师齐光给出了详细流程。来阿里面试前,先…

深入解析:10月底实习准备-Mysql(按面试频率准备)

深入解析:10月底实习准备-Mysql(按面试频率准备)pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas"…

CEXE的%你赛5-题解

T1 简单 dfs,记录数组 \(vis\) 表示一个点有没有被搜索过,从小到大遍历 \(vis\),如果 \(vis_i=0\) 则从 \(i\) 开始遍历图,遍历时记录答案即可。 #include<bits/stdc++.h> using namespace std; int n,m; lo…

C++语言(1)

.数制的前缀 二进制:0b或0B。 八进制:0。注意代码中012的十进制数值是10。 十六进制:0x(字母小写)或0X(字母小写)。 .输入和输出 .1.scanf和printf 格式符 常见类型的格式符:类型 格式符int %dlong long %llds…

Windows多人共享文件夹全流程,附2025新共享文件快90%

针对传统Windows共享文件夹设置繁琐、不安全、仅限局域网的痛点,本文提出用坚果云创建多人共享文件夹。其操作简便,支持跨地域协作、精细权限管理与文件版本回溯,无缝替代传统方式,是实现团队安全、高效协同办公的…

第11章 day11-day12关于json请求体/逆向爬虫实战

第1知识点:关于json请求体 第2知识点:关于精准请求(如何排除干扰请求) 第3知识点:入口定位 一、关键字方法 (1) 方法关键字 encrypt decrypt (2) key关键字 第4知识点:断点与断点调试 普通断点 XHR断点 条件断点…

容斥与二项式反演

先挖坑,后填坑。容斥 容斥,实际上就是用总的方案数减去不合法的方案数。 我们考虑以下组合恒等式: \[\sum_{i = 0}^{n} (-1) ^ {i} C_{n}^{i} = [n = 0] \]为什么这个式子跟容斥有关呢? 我们考虑不合法的数量为 \(…

网上怎样做电缆网站建设网站公司怎么建站

centos7 mysql 基本测试&#xff08;7&#xff09;主从并行简单测试 重启MySQL服务使配置生效。 注意&#xff1a;并行复制需要slave的硬件资源充足&#xff0c;并且确保网络通信和IO性能不是瓶颈。不是所有的应用场景都适合并行复制&#xff0c;比如写密集型应用或者slave负…

react useCallback Hook详解

什么是 useCallback Hook? useCallback 是一个 React Hook,用于缓存函数,防止函数在每次组件渲染时被重新创建。它的主要目的是优化性能,特别是在将函数作为 props 传递给子组件或在依赖数组中使用时。 简单来说,…

从Docker构建失败到CRA被淘汰:一个React项目的ES模块探索记录

开头 最近给一个React项目配Docker构建,碰到了一个看起来简单实际很麻烦的错误: Failed to compile. The target environment doesnt support dynamic import() syntax so its not possible to use external type mo…

充气泵PCBA方案中数字传感器和模拟传感器的差异

充气泵的核心需求是实时、准确检测气罐/充气对象(如轮胎、泳圈)的压力,并根据压力值控制电机启停(如达到目标压力后停机),二者的应用差异直接影响产品体验:1.模拟传感器的应用场景低成本入门级充气泵(如家用小…

实用指南:小米17手机的上市公司供应商

实用指南:小米17手机的上市公司供应商pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Mon…

小程序支付遇到:system:access_denied

小程序支付遇到:system:access_denied 原因: 小程序支付,只能用手机微信测试,不能用电脑。 -

cloudfared 内网穿透经过docker方式遇到的问题

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

CDN + WAF + CLB + Higress 架构下的 TLS 加解密详细解析(适用阿里云)

在云环境中,Web 应用常见架构是:用户 → CDN → WAF → CLB → ECS/Higress本文详细解析 WAF 在网络拓扑中的位置、TLS 加解密流程、回源逻辑,以及自定义接入模式下的注意事项,结合阿里云官方推荐实践。1.WAF 在网…

react useMemo Hook详解

什么是 useMemo Hook? useMemo 是一个 React Hook,用于缓存计算结果,避免在每次组件渲染时重复执行昂贵的计算。它通过记忆计算的值,只有在依赖项变化时才会重新计算,从而优化性能。 简单来说,useMemo 让你的计算…

门户网站改版建议wordpress 调用热门 文章

文章目录 1.liunx简介2.liunx的jdk安装2.liunx的tomcat安装3.liunx的mysql安装4.单机项目部署 1.liunx简介 Linux&#xff0c;一般指GNU/Linux&#xff08;单独的Linux内核并不可直接使用&#xff0c;一般搭配GNU套件&#xff0c;故得此称呼&#xff09;&#xff0c;是一种免费…

vs2012网站开发济南做网站的网络公司

简介&#xff1a; 淘宝的开放技术目前主要有两种形态&#xff0c;第一种是小程序&#xff0c;第二种是今天的主角小部件。它是基于小程序技术体系&#xff0c;面向标准化、轻量化、高性能的开放卡片场景。本文我们将通过技术设计策略、核心技术设施、业务场景接入、技术演进路线…

网站后台系统有哪些佛山优化企业网站排名平台

实验要求 1、R5为ISP&#xff0c;只能进行IP地址配置&#xff0c;其所有地址均配为公有IP地址。 2、&#xff08;1&#xff09;R1和R5间使用PPP的PAP认证&#xff0c;R5为主认证方。 &#xff08;2&#xff09;R2与R5之间使用ppp的CHAP认证&#xff0c;R5为主认证方。 &#…