JS常用HOOK调试技术

news/2025/1/15 18:16:17/
hook技术

Hook 是一种钩子技术,在系统没有调用函数之前,钩子程序就先得到控制权,这时钩子函数既可以加工处理(改变)该函数的执行行为,也可以强制结束消息的传递。简单来说,修改原有的 JS 代码就是 Hook

Hook 技术之所以能够实现有两个条件:

  • 客户端拥有 JS 的最高解释权,可以决定在任何时候注入 JS,而服务器无法阻止或干预。服务端只能通过检测和混淆的手段,另 Hook 难度加大,但是无法直接阻止。
  • 除了上面的必要条件之外,还有一个条件。就是 JS 是一种弱类型语言,同一个变量可以多次定义、根据需要进行不同的赋值,而这种情况如果在其他强类型语言中则可能会报错,导致代码无法执行。js 的这种特性,为我们 Hook 代码提供了便利。

**注意:**JS 变量是有作用域的,只有当被 hook 函数和 debugger 断点在同一个作用域的时候,才能 hook 成功。

Hook步骤:*
  • 1、寻找hook入口

  • 2、编写hook逻辑

  • 3、调试

:最常用的是hook cookie

hook 方法

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);}
})();
hook XHR请求

定义了一个变量 open 保留原始 XMLHttpRequest.open 方法,然后重写 XMLHttpRequest.open 方法

(function () {var open = window.XMLHttpRequest.prototype.open;window.XMLHttpRequest.prototype.open = function (method, url, async) {if (url.indexOf("analysis") != -1) {debugger;}return open.apply(this, arguments);};
})();

Interceptors-拦截器

  • 请求拦截器:在发送请求之前,可以借助一些函数来对请求的内容和参数做一些检测。若有问题可以直接取消请求。
  • 响应拦截器:当服务器返回响应数据时,响应拦截器会在我们拿到结果前预先处理响应数据。例如对响应数据做一些格式化处理,或者当响应失败时,可以做一些失败提醒和纪录。
// npm install axios
axios = require('axios')
//设置请求拦截器
axios.interceptors.request.use(function (config) {console.log('请求拦截器 成功')config.timeout = 2000; //修改请求configconfig.headers['sign'] = 'lili'return config;
}, function (error) {console.log('请求拦截器 失败')return Promise.reject(error);
});//设置响应拦截器
axios.interceptors.response.use(function (response) {console.log('响应拦截器 成功')console.log('调解密函数进行解密数据')//return response;return response.data; //修改响应数据
}, function (error) {console.log('响应拦截器 失败')return Promise.reject(error);
});//发送请求
axios.get('http://httpbin.org/get').then(res=>console.log(res))

XMLHttpRequest

XMLHttpRequest(XHR)对象用于与服务器交互。通过 XMLHttpRequest 可以在不刷新页面的情况下请求特定 URL,获取数据。这允许网页在不影响用户操作的情况下,更新页面的局部内容。XMLHttpRequest 在 AJAX 编程中被大量使用。

XMLHttpRequest.open()

方法初始化一个新创建的请求,或重新初始化一个请求。

xhrReq.open(method, url, async);

XMLHttpRequest.send()

发送请求。如果请求是异步的(默认),那么该方法将在请求发送后立即返回。

方法接受一个可选的参数,其作为请求主体;如果请求方法是 GET 或者 HEAD,则应将请求主体设置为 null。

xhrReq.send(body)

XMLHttpRequest.setRequestHeader()

设置 HTTP 请求头的值。必须在 open() 之后、send() 之前调用 setRequestHeader() 方法。

myReq.setRequestHeader(header, value);    // headers['key'] = value

XMLHttpRequest.onreadystatechange

readyState 属性发生变化时,调用的事件处理器。

var xhr= new XMLHttpRequest(),method = "GET",url = "https://developer.mozilla.org/";xhr.open(method, url, true);
xhr.onreadystatechange = function () {if(xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {console.log(xhr.responseText)}
}
xhr.send();
HOOK cookie操作

WEBAPI地址:https://developer.mozilla.org/zh-CN/docs/Web/API

Object.defineProperty 为对象的属性赋值,替换对象属性

基本语法:Object.defineProperty(obj, prop, descriptor),它的作用就是直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,接收的三个参数含义如下:

  • obj:需要定义属性的当前对象;

  • prop:当前需要定义的属性名;

Object.defineProperty(user,"age",{get:function(){console.log("这个人来获取值了!!");return count;},set:function(newVal){console.log("这个人来设置值了!!");count=newVal+1;}
})

cookie 示范

示范例子:http://q.10jqka.com.cn/

cookie 钩子用于定位 cookie 中关键参数生成位置,以下代码演示了当 cookie 中匹配到了 v, 则插入断点:

(function () {var cookieTemp = '';Object.defineProperty(document, 'cookie', {set: function (val) {if (val.indexOf('v') != -1) {debugger;}console.log('Hook捕获到cookie设置->', val);cookieTemp = val;return val;},get: function () {return cookieTemp;},});
})();

注:正常hook cookie操作的时候需要清除下cookie

通用反调试
(function() {var _constructor = unsafeWindow.Function.prototype.constructor;// Hook Function.prototype.constructorunsafeWindow.Function.prototype.constructor = function() {var fnContent = arguments[0];if (fnContent) {if (fnContent.includes('debugger')) { // An anti-debugger is attempting to stop debuggingvar caller = Function.prototype.constructor.caller; // Non-standard hack to get the function callervar callerContent = caller.toString();if (callerContent.includes(/\bdebugger\b/gi)) { // Eliminate all debugger statements from the caller, if anycallerContent = callerContent.replace(/\bdebugger\b/gi, ''); // Remove all debugger expressionseval('caller = ' + callerContent); // Replace the function}return (function () {});}}// Execute the normal function constructor if nothing unusual is going onreturn _constructor.apply(this, arguments);};
})();

http://www.ppmy.cn/news/1281619.html

相关文章

设计模式 建造者模式 与 Spring Bean建造者 BeanDefinitionBuilder 源码与应用

建造者模式 定义: 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示主要作用: 在用户不知道对象的建造过程和细节的情况下就可以直接创建复杂的对象如何使用: 用户只需要给出指定复杂对象的类型和内容, 建造者模式负责按顺序创建复杂对象…

http和https、http状态码分类

http协议是hyper text transfer protocol的缩写。 https是加了ssl外壳的http。https是一种通过计算机网络进行安全通信的传输协议,经由http进行通信,利用SSL/TLS建立全信道,加密数据包。https使用的主要目的是提供对网站服务器的身份认证&am…

C++中的存储类及其实例

文章目录 0. 语法1. 自动存储类自动存储类对象的属性自动存储类的例子 2. 外部存储类extern存储类对象的属性extern存储类的例子 3. 静态存储类静态存储类的属性静态存储类的例子 4. 寄存器存储类寄存器存储类对象的属性寄存器存储类例子 5. 可变(mutable&#xff0…

Android 手机对于Arduino蓝牙控制解决方案

1、Android系统概述 ​ Android 系统是 Google 公司基于 Linux 内核开发的移动端操作系统,适用于智能手机智能手表平板电脑等设备,最新的版本为 7.1。Android系统具有免费开源的优势,任何企业与个人都可以查阅公开的 API 文档,并在自己开发的应用中通过调…

iOS使用CXCallObserver监听电话接听与拨打

初始化 import CallKitclass HomeViewController: UIViewController, CXCallObserverDelegate {public var cacheManager: TripCacheManager TripCacheManager.init()override func viewDidLoad() {super.viewDidLoad()self.callObserver.setDelegate(self, queue: DispatchQ…

如何处理uni-app中的跨平台差异

在uni-app中,可以通过条件编译和平台判断来处理跨平台差异代码。具体步骤如下: 在uni-app项目的根目录下,找到名为manifest.json的文件,这是uni-app的配置文件。 在manifest.json文件中,可以使用条件编译指令来处理不…

SperingBoot+vue文件上传下载预览

上传文件: 前端: 整个过程,就是在使用FormData 添加 上File(这个Blob),并且key要和后台的名字对应上在点击上传按钮开始上传之前,使用了URL.createObjectURL(File)创建blobUrl,给了…

树莓派Pi4B简介

树莓派是什么?Raspberry Pi(中文名为“树莓派”,简写为RPi,或者RasPi/RPi)是为学生计算机编程教育而设计,只有信用卡大小的卡片式电脑,其系统基于Linux。 树莓派4B与树莓派3B/3B参数对比: 具体的实物图如下&#xff1a…