首页
实用工具
我的旅程
在线壁纸
更多
✒️ 问题反馈
📦 文章统计
🌍 国内镜像
🎬 次元视界
📒 流水账本
🎨 在线 PS
推荐
🕵️ 开源情报
🌆 图片压缩
🍭 资产清洗
💡 我的作品
👤 关于站长
⚔️ 次 元 剑
搜索
1
【工具分享】逆向工具箱 - 次元剑
89,537 阅读
2
【技术分享】PE文件结构分析 ( RVA转FOA )
7,350 阅读
3
【技术分享】NASM x86 Assembly Language
5,982 阅读
4
【技术分享】CK竞技之王游戏辅助制作
3,725 阅读
5
【每日随记】天涯明月刀无限飞修改思路
2,816 阅读
技术分享
CTF解题
英语笔记
数学笔记
网络通信
每日随记
攻防技术
工具分享
Search
标签搜索
Windows
Web安全
Python3
Linux
逆向工程
CTF
红队技术
人工智能
C/C++
黑客工具
Go
密码学
二进制安全
数学
漏洞挖掘
Android
eNSP
渗透测试
蓝队技术
黑客大会
发光的神
累计撰写
160
篇文章
累计收到
103
条评论
首页
栏目
技术分享
CTF解题
英语笔记
数学笔记
网络通信
每日随记
攻防技术
工具分享
页面
实用工具
我的旅程
在线壁纸
✒️ 问题反馈
📦 文章统计
🌍 国内镜像
🎬 次元视界
📒 流水账本
🎨 在线 PS
推荐
🕵️ 开源情报
🌆 图片压缩
🍭 资产清洗
💡 我的作品
👤 关于站长
⚔️ 次 元 剑
搜索到
4
篇与
的结果
2026-07-05
【工具分享】V免签支付 + vPay 自动发卡系统
简介V免签 是一款私有支付网关,配合 Android 手机监听微信/支付宝到账通知,无需企业资质即可接入支付。vPay 发卡 是本人从零开发的 PHP 原生虚拟商品自动售卡系统。两者独立开源,支持微信支付宝收款、可组合使用,部署后即可搭建一套完整的自动发卡平台。工作流程: 买家下单 → vPay 展示二维码 → 买家扫码支付 → V免签 Android 端监听到账 → 回调 vPay → vPay 自动匹配订单、扣减库存、发送卡密邮件。V免签 (vmq)基于 ThinkPHP 5.1 的免签支付回调服务端。配合 Android 监控端,通过辅助功能监听微信和支付宝通知栏,检测到账后推送至服务端完成订单匹配与回调,一台旧安卓手机即可作为私有支付网关。网站后台本项目基于 szvone/vmqphp 重写,主要改进:安全修复(9 项)SQL 注入:字符串拼接改为 PDO 参数化查询SSRF:CURL 出站增加内网 IP 黑名单校验,禁用重定向跟随XSS:param 参数增加 htmlspecialchars() 过滤订单号注入:正则限制 [a-zA-Z0-9_-],最长 100 字符存储型 XSS:回调 URL 写入前 FILTER_SANITIZE_URL调试模式:app_debug = false硬编码密钥:示例代码改为从数据库动态读取远程代码风险:移除 checkUpdate() 外部拉取逻辑CDN 供应链:jQuery、Vue 等前端资源全部本地化功能改进支持子目录部署,APK 扫码自动识别路径支付页重写,骨架屏加载 + 中英文切换系统运行时间改为数据库记录,跨平台通用APK 安装包内置在后台,可直接下载{abtn icon="fa-github" color="#000000" href="https://github.com/soevai/vmq" radius="" content="Github - vmq | 点击进入" /} {abtn icon="fa-book" color="#e10000" href="https://www.52tt.pro/repo/vmq/" radius="" content="在线 Demo 体验 | 点击进入"/}vPay 发卡 (vPayFaka)网站首页收款弹窗从零构建的 PHP 原生虚拟商品发卡系统,对接 V免签支付。零外部依赖——没有 composer、没有 npm、没有 CDN,文件上传到服务器即可运行,全栈自研,不基于任何现有框架或项目。主要特性商品管理:支持分类、多规格 SKU、库存自动统计自动发卡:SELECT ... FOR UPDATE 行级锁 + 事务,杜绝并发超卖一键安装:首次访问自动跳转安装向导,建库建表写配置邮件通知:支持 SMTP 直发和自定义 API(HMAC-SHA256 签名)超时取消:超时未支付自动取消并返还库存安全措施密码:bcrypt 哈希存储CSRF:random_bytes(32) 令牌 + hash_equals 常量时间比对SQL 注入:全 PDO 预处理 + 参数绑定回调校验:MD5 签名 + 300 秒时间戳窗口 + Nonce 文件去重频率限制:登录失败 5 次锁 3 分钟,购买每 IP 每小时 5 次HTTP 安全头:CSP、X-Frame-Options、X-Content-Type-Options{abtn icon="fa-github" color="#000000" href="https://github.com/soevai/vPayFaka" radius="" content="Github - vPayFaka | 点击进入" /} {abtn icon="fa-book" color="#e10000" href="https://www.52tt.pro/repo/vpay/" radius="" content="在线 Demo 体验 | 点击进入"/}协同方式两个项目独立开源,可单独或组合使用,对接只需在 vPay 后台填入 V免签的服务端地址和通讯密钥。V免签(监听收款)→ notify.php 回调 → vPay 发卡(匹配订单、提取卡密、发送邮件)详细的 API 文档、数据库结构、部署步骤和定时任务配置见各项目 GitHub README。免责声明两个项目均为开源学习用途,请勿用于任何违法违规场景,使用者自行承担相应责任。
2026年07月05日
255 阅读
0 评论
8 点赞
2026-02-24
【技术分享】IDA+Jadx+Trae MCP 配置教程
简介做逆向分析的时候,大家肯定都有这种体验:在 IDA Pro、Jadx 之间来回切,手动复制内存地址、对着代码逐行比对,不仅慢得让人着急,还特别容易出错。而 MCP(Model Context Protocol,模型上下文协议)就是来解决这个问题的!它能把 IDA Pro、Jadx 和 Trae AI 完美连起来,实现工具间的数据互通、操作联动。今天这篇教程就手把手教你配置这套环境,让你告别工具割裂的麻烦,用 AI 一站式搞定逆向分析。一、环境准备为了避免版本不兼容踩坑,建议大家直接照着下面的环境来搭,亲测稳定不翻车:操作系统:Windows 11版本控制:Git运行环境:Python 3.11.8(重点!别用其他版本)逆向工具:IDA Pro 8.3AI 客户端:Trae AI二、Git 安装Git 是安装 ida-pro-mcp 的必需品,主要用来从 GitHub 拉取插件源码,步骤超简单:1.打开浏览器,访问 Git 官网下载 Windows 版本:https://git-scm.com/install/windows2.双击安装包,一路点“下一步”,默认配置完全够用,不用折腾3.安装完成后,按 Win+R 输入 cmd 打开命令行,敲入 git --version,如果能显示版本号,就说明装好了{abtn icon="fa-git-square" color="#000" href="https://git-scm.com/install/windows" radius="" content="Git 官网"/}三、Trae 联动 IDA Proida-pro-mcp 是连接 IDA Pro 和 MCP 协议的核心,有了它,Trae AI 才能直接调用 IDA 的分析能力,我们一步步来:步骤 1:安装 ida-pro-mcp首先右键点击“命令提示符”,选择“以管理员身份运行”(权限不够会装失败),然后复制下面的命令敲进去:pip install --upgrade git+https://github.com/mrexodia/ida-pro-mcp这里提个醒:如果碰到网络超时、连接重置的情况,就是访问 GitHub 受限了。直接去仓库地址(https://github.com/mrexodia/ida-pro-mcp)下载 ZIP 包,解压后进入解压目录,执行 pip install . 就能本地安装了。步骤 2:安装 IDA 插件插件装完后,不用手动拷贝文件,在刚才的管理员命令行里继续敲:ida-pro-mcp.exe --install执行成功后,插件会自动放到 IDA Pro 的插件目录里,以后打开 IDA,MCP 服务就会自动加载,特别省心。步骤 3:Trae AI MCP 配置打开 Trae AI,找到 MCP 服务器的配置页面,把下面的 JSON 代码完整复制进去就行:四、联动使用流程1.如果是使用工具包,第一次运行 IDA 需要以管理员身份运行一次 IDA_Pro_8.3_绿化工具.exe 初始化下 IDA。2.然后去 IDA 安装目录里找 idapyswitch.exe 并运行,把 Python 版本切换到 3.11.8,这样 IDA 才能正常加载 MCP 插件。3.先打开 IDA Pro,加载你要分析的程序(比如 CrackMe),等底部状态栏显示“Ready”,就说明反汇编完成了。然后点击顶部的「Edit」→「Plugins」→「MCP」,开启 MCP 服务,这时 IDA 就会在 13337 端口等着 Trae 连接了。4.切回 Trae AI,在 MCP 配置页面确认一下之前的配置没错,完成连接设置。5.把执行 ida-pro-mcp --config 命令得到的配置信息,手动填到 Trae AI 的 MCP 配置里,确保参数都对得上。MCP 配置{ "mcpServers": { "ida-pro-mcp": { "command": "C:\\Program Files\\Python311\\python.exe", "args": [ "C:\\Program Files\\Python311\\Lib\\site-packages\\ida_pro_mcp\\server.py", "--ida-rpc", "http://127.0.0.1:13337" ] } } }简单说下配置里的关键点,别配错了:command:填你安装 Python 3.11.8 的路径,必须和装插件时的 Python 一致args:固定写法,不用改,作用是启动 MCP 服务端,连接 IDA 的 13337 端口保存之后,Trae AI 就会自动尝试连接 IDA 的 MCP 服务了6.在 Trae AI 里,把智能体切换成「Builder with MCP」模式,这个模式才支持调用 IDA 的服务。7.最后一步,在 Trae AI 的聊天框里输入下面这句话,让 AI 开始工作:我已经用ida打开了一个程序,请用mcp的方式分析并输出flag8.稍等一会儿,Trae AI 就会自动读取 IDA 里的代码信息,分析加密逻辑,最后直接把正确的 Flag 给你输出来,全程不用手动操作!五、Trae 联动 Jadx1.Jadx 插件可在线下载;若访问受限,前往仓库手动获取:https://github.com/zinja-coder/jadx-ai-mcp。手动安装(推荐)1.将 jadx-ai-mcp-6.1.0.jar、jadx-mcp-server-v6.1.0.zip 放入 Jadx 根目录,并手动选择安装 jadx-ai-mcp-6.1.0.jar。2.解压 jadx-mcp-server-v6.1.0.zip,命令行进入解压目录,执行:pip install -r requirements.txtMCP 配置{ "mcpServers": { "jadx-mcp-server": { "command": "C:\\PROGRA~1\\Python311\\python.exe", "args": [ "D:\\VoxShadow\\Jdax\\jadx-mcp-server-v6.1.0\\jadx_mcp_server.py" ] } } }2.按实际路径修改 command 与 args,复制到 Trae AI MCP 配置页(同 IDA 配置方式)。Trae AI 切换到「Builder with MCP」模式,发送指令:我已经用jadx打开了一个程序,请用mcp的方式分析并输出flag3.AI 自动读取 Jadx 代码、分析逻辑并输出 Flag,也可以进行黑盒代码审计了。六、整合包下载用到的软件我都已经打包好了,下载就能按照文章进行配置使用。{cloud title="IDA+Jadx+Trae工具包" type="bd" url="https://pan.baidu.com/s/1PP2sbVkREX8gvgKb8h4eHQ?pwd=2085" password="2085"/}
2026年02月24日
940 阅读
0 评论
339 点赞
2023-04-25
【技术分享】Frida Hook篇
简介Frida是一款基于Python + JavaScript 的hook框架,本质是一种动态插桩技术。可以用于Android、Windows、iOS等各大平台,其执行脚本基于Python或者Node.js写成,而注入代码用JavaScript写成,所以有必要了解一些这些语言的语法。本文简单讲述Frida框架的使用。Windows修改函数返回#include <stdio.h> int license() { return 0; } int main() { if(license() == 1) { printf("%s", "你做到了~"); }else{ printf("%s", "你失败了!"); } return 0; }这里我用C语言编写一个简单的例子,尝试hook函数的返回值修改为 1。objdump -M intel -d Demo | grep call这里我用 objdump 进行过滤反汇编代码,我的习惯用全局过滤 call 看看都调用了哪些函数,因为有的编译是不显示函数名称的,也就无法判断其函数的用途。这里通过调用 license() 函数判断返回值,那么只要 hook 0x1139 这个地址的返回值,就能改变判断执行的流程。var moduleName = "demo"; var baseAddress = Module.findBaseAddress(moduleName); var absoluteAddress = baseAddress.add(0x1139); Interceptor.attach(absoluteAddress, { onLeave: function(retval) { retval.replace(1); console.log("\n"); } });frida -l code.js -f demo因为程序是一运行就执行,这里用这种办法来带动程序执行并进行hook。frida-tracefrida-trace -f demo -i "printf"可以利用 frida-trace 监听函数调用和获取参数等等一系列操作。WSASend Hook// 自适应旧数据大小 Interceptor.attach(Module.getExportByName('Ws2_32.dll', 'WSASend'), { onEnter: function (args) { var hexDataWithSpaces = "00 00 00 BD 00 14 00 02 "; function hexStringWithSpacesToBytes(hexStr) { var hexValues = hexStr.replace(/\s+/g, '').match(/.{1,2}/g); var bytes = []; for (var i = 0; i < hexValues.length; i++) { bytes.push("0x" + hexValues[i]); } return bytes; } var socket = args[0].toInt32(); var sockaddr_in = Memory.alloc(16); var sockaddr_in_size = Memory.alloc(4); Memory.writeU32(sockaddr_in_size, 16); var getpeername = Module.getExportByName('Ws2_32.dll', 'getpeername'); var result = new NativeFunction(getpeername, 'int', ['int', 'pointer', 'pointer'])(socket, sockaddr_in, sockaddr_in_size); if (result === 0) { var ip = Memory.readU32(sockaddr_in.add(4)); var ipStr = ((ip & 0xFF)) + '.' + ((ip >> 8) & 0xFF) + '.' + ((ip >> 16) & 0xFF) + '.' + ((ip >> 24) & 0xFF); console.log("[+] IP Address: " + ipStr); } else { console.log("[-] Failed to retrieve IP address"); } var lpBuffers = args[1]; var dwBufferCount = args[2].toInt32(); for (var i = 0; i < dwBufferCount; i++) { var lpBuffer = lpBuffers.add(i * Process.pointerSize * 2); var bufLen = Memory.readU32(lpBuffer); if (bufLen === 173) { console.log("[+] Length=" + bufLen); var newData = hexStringWithSpacesToBytes(hexDataWithSpaces); var newDataLength = newData.length; var newBufPtr = Memory.alloc(1024); Memory.writeByteArray(newBufPtr.add(24), newData); Memory.writePointer(lpBuffer.add(Process.pointerSize), newBufPtr.add(24)); Memory.writeU32(lpBuffer, newDataLength); var modifiedData = Memory.readByteArray(newBufPtr.add(24), newDataLength); console.log(modifiedData); } } } });WSARcev Hook// 自适应旧数据大小 var buff = Memory.alloc(0x6) Memory.writeByteArray(buff, [0x32,0x32,0x32,0x32,0x32,0x32]); Interceptor.attach(Module.getExportByName('Ws2_32.dll', 'WSARecv'), { onEnter: function (args) { this.lpBuffersPtr = args[1]; this.lpNumberOfBytesRecvd = args[3]; }, onLeave: function (retval) { var lenPtr = Memory.readPointer(this.lpNumberOfBytesRecvd); var buflen = parseInt(lenPtr, 16); if (buflen == 2) { Memory.writePointer(this.lpBuffersPtr.add(Process.pointerSize), buff); ptr(this.lpNumberOfBytesRecvd).writeUInt(0x6); } } });frida -p 2085 -l WSARcev.jsJmp Hookvar baseAddress = ptr('0x4010F5'); var jmpAddress = ptr('0x4010FB'); var offset = jmpAddress.sub(baseAddress.add(5).toInt32()); var jmpOpcode = [ 0xE9, offset & 0xFF, (offset >> 8) & 0xFF, (offset >> 16) & 0xFF, (offset >> 24) & 0xFF ]; Memory.protect(baseAddress, 8, 'rw-'); Memory.writeByteArray(baseAddress, jmpOpcode);系统提权var path = 'C:/Users/28729/Desktop/main.exe'; // 替换你要执行的程序路径(不能包含中文字符) var module = Process.getModuleByName('kernel32.dll'); var WinExec = module.findExportByName('WinExec'); var WinExec = new NativeFunction(WinExec,'int', ['pointer', 'uint32']); WinExec(Memory.allocUtf8String(path), 5); console.log(WinExec.toString());端口修改Interceptor.attach(Module.getExportByName('ws2_32.dll', 'connect'), { onEnter: function(args) { var sockaddr = args[1]; var ip = Memory.readU32(sockaddr.add(4)); var ipStr = ((ip & 0xFF)) + '.' + ((ip >> 8) & 0xFF) + '.' + ((ip >> 16) & 0xFF) + '.' + ((ip >> 24) & 0xFF); // 修改端口为 80 (0x0050) Memory.writeU16(sockaddr.add(2), 0x0050); var modifiedPort = Memory.readU16(sockaddr.add(2)); console.log("[+] Modified to connect to: " + ipStr + ":" + modifiedPort); } });变速齿轮变速原理变速齿轮的原理 变速齿轮(变速精灵)通过修改游戏运行时的时间流逝速度,实现加速或减速效果。其核心思路是拦截并修改游戏调用的时间相关函数的返回值。关键时间函数 大部分游戏依赖Windows提供的计时器API来获取时间流逝数据,常用的函数包括:GetTickCount: 获取系统启动后经过的毫秒数。timeGetTime: 获取自系统启动以来的时间,单位为毫秒。这些函数在游戏中用于时间逻辑和动画刷新等。Hook技术的应用 为实现变速功能,需要使用Hook技术拦截上述API函数:在返回值的基础上加上变速比例。例如,将时间流逝的速度乘以一个比例系数(如2倍速或0.5倍速)。修改后的返回值会被游戏程序使用,从而达到加速或减速效果。实现效果 修改计时器函数返回值后:游戏中的时间会按照设定的速度流逝。动画、技能冷却、任务时间等都会受到影响。注意事项对API函数的Hook需要精确,避免引起其他程序崩溃。修改速度可能会影响游戏网络同步或反作弊机制,因此需要谨慎使用。通过Hook系统的计时器API(如GetTickCount、timeGetTime),改变游戏对时间的感知速度,从而实现游戏变速功能。这种方式通用于大多数基于Windows计时器的游戏程序。推荐下 Cheat Engine,这个工具也可以实现。Cheat Engine 此源码仅支持 64位 Python。{cloud title="变速精灵" type="bd" url="https://pan.baidu.com/s/1byEIfi3HHoZaMKy5jibVyw?pwd=2085" password=""/}AndroidHook okhttp3Java.perform(function () { var RequestBuilder = Java.use("okhttp3.Request$Builder"); var Buffer = Java.use("okio.Buffer"); RequestBuilder.build.implementation = function () { var request = this.build(); var body = request.body(); if (body != null) { var buffer = Buffer.$new(); body.writeTo(buffer); var raw_body = buffer.readUtf8(); console.log("=== HTTP Request ==="); console.log("URL: " + request.url().toString()); console.log("Body: " + raw_body); } return request; }; });so 加载检测function hook_dlopen() { Interceptor.attach(Module.findExportByName(null, "android_dlopen_ext"), { onEnter: function(args) { var pathptr = args[0]; if (pathptr !== undefined && pathptr != null) { var path = ptr(pathptr).readCString(); console.log("Loaded: " + path); } } }); }var dlopen = Module.findExportByName(null, "dlopen"); // 6.0 var android_dlopen_ext = Module.findExportByName(null, "android_dlopen_ext"); // 8.1+ Interceptor.attach(dlopen, { onEnter: function (args) { var path_ptr = args[0]; this.path = ptr(path_ptr).readCString(); console.log("[+] dlopen onEnter => " + this.path + " > 开始加载"); }, onLeave: function (retval) { console.log("[-] dlopen onLeave => " + this.path + " > 加载完成"); } }); Interceptor.attach(android_dlopen_ext, { onEnter: function (args) { var path_ptr = args[0]; this.path = ptr(path_ptr).readCString(); console.log("[+] dlopen_ext onEnter => " + this.path + " > 开始加载"); }, onLeave: function (retval) { console.log("[-] dlopen_ext onLeave => " + this.path + " > 加载完成"); } });其它-JS逆向Hook 解析参数// === JSON.parse (解密后) === var _json_parse = JSON.parse; JSON.parse = function (text, reviver) { console.log("JSON.parse:", text); debugger; return _json_parse.call(this, text, reviver); }; // === JSON.stringify (加密前) === var _json_stringify = JSON.stringify; JSON.stringify = function (value, replacer, space) { console.log("JSON.stringify:", value); debugger; return _json_stringify.call(this, value, replacer, space); }; // === XMLHttpRequest (发送 & 接收) === (function() { var _open = XMLHttpRequest.prototype.open; var _send = XMLHttpRequest.prototype.send; XMLHttpRequest.prototype.open = function(method, url) { this._url = url; this._method = method; return _open.apply(this, arguments); }; XMLHttpRequest.prototype.send = function(body) { console.log(`XHR Request [${this._method}] ${this._url}`, body); this.addEventListener("load", function() { console.log(`XHR Response [${this._method}] ${this._url}`, this.responseText); }); return _send.apply(this, arguments); }; })(); // === fetch (发送 & 接收) === var _fetch = fetch; fetch = function(input, init) { console.log("fetch Request:", input, init && init.body); return _fetch.apply(this, arguments).then(async res => { let clone = res.clone(); let text = await clone.text(); console.log("fetch Response:", text); return res; }); }; // === WebSocket (发送 & 接收) === var _ws_send = WebSocket.prototype.send; WebSocket.prototype.send = function(data) { console.log("WS Send:", data); return _ws_send.apply(this, arguments); }; var _WebSocket = window.WebSocket; window.WebSocket = function(...args) { var ws = new _WebSocket(...args); ws.addEventListener("message", function(event) { console.log("WS Message:", event.data); }); return ws; };Hook 原生加密解密// === CryptoJS AES 加密 / 解密 === if (window.CryptoJS && CryptoJS.AES) { var _aes_encrypt = CryptoJS.AES.encrypt; CryptoJS.AES.encrypt = function (msg, key, cfg) { console.log("AES encrypt input:", msg); debugger; return _aes_encrypt.apply(this, arguments); }; var _aes_decrypt = CryptoJS.AES.decrypt; CryptoJS.AES.decrypt = function (ciphertext, key, cfg) { console.log("AES decrypt input:", ciphertext); var result = _aes_decrypt.apply(this, arguments); console.log("AES decrypt output:", result.toString(CryptoJS.enc.Utf8)); debugger; return result; }; } // === CryptoJS RC4 加密 / 解密 === if (window.CryptoJS && CryptoJS.RC4) { var _rc4_encrypt = CryptoJS.RC4.encrypt; CryptoJS.RC4.encrypt = function (msg, key) { console.log("RC4 encrypt input:", msg); debugger; return _rc4_encrypt.apply(this, arguments); }; var _rc4_decrypt = CryptoJS.RC4.decrypt; CryptoJS.RC4.decrypt = function (ciphertext, key) { console.log("RC4 decrypt input:", ciphertext); var result = _rc4_decrypt.apply(this, arguments); console.log("RC4 decrypt output:", result.toString(CryptoJS.enc.Utf8)); debugger; return result; }; } // === Base64 === var _atob = atob; window.atob = function (str) { console.log("Base64 decode input:", str); var result = _atob(str); console.log("Base64 decode output:", result); debugger; return result; }; var _btoa = btoa; window.btoa = function (str) { console.log("Base64 encode input:", str); debugger; return _btoa(str); };Hook 网络通信函数// ===== Hook fetch API ===== // 拦截并打印 fetch 请求和响应 function hookFetch() { var _fetch = fetch; fetch = function (input, init) { console.log("fetch request:", input, init?.body); return _fetch.apply(this, arguments).then(async res => { let clone = res.clone(); console.log("fetch response:", await clone.text()); return res; }); }; } // ===== Hook XMLHttpRequest API ===== // 拦截并打印 XHR 请求和响应 function hookXHR() { var _open = XMLHttpRequest.prototype.open; var _send = XMLHttpRequest.prototype.send; XMLHttpRequest.prototype.open = function (method, url) { this._method = method; this._url = url; return _open.apply(this, arguments); }; XMLHttpRequest.prototype.send = function (body) { console.log(`XHR [${this._method}] ${this._url}`, body); this.addEventListener("load", () => { console.log(`XHR response [${this._method}] ${this._url}`, this.responseText); }); return _send.apply(this, arguments); }; } // ===== Hook WebSocket API ===== // 拦截并打印 WebSocket 收发数据 function hookWebSocket() { var _ws_send = WebSocket.prototype.send; WebSocket.prototype.send = function (data) { console.log("WS send:", data); return _ws_send.apply(this, arguments); }; var _WebSocket = window.WebSocket; window.WebSocket = function (...args) { var ws = new _WebSocket(...args); ws.addEventListener("message", function (event) { console.log("WS message:", event.data); }); return ws; }; } // ===== Hook WebRTC send ===== // 拦截 WebRTC 数据 function hookWebRTC() { if (window.RTCPeerConnection) { var _send = RTCDataChannel.prototype.send; RTCDataChannel.prototype.send = function (data) { console.log("WebRTC send:", data); return _send.apply(this, arguments); }; } }
2023年04月25日
488 阅读
0 评论
33 点赞
2023-01-19
此内容被密码保护
加密文章,请前往内页查看详情
2023年01月19日
29 阅读
0 评论
3 点赞
0:00