/** * 浏览器Hook脚本 * 在浏览器Console中运行此脚本,可以拦截并分析API请求参数 * * 使用方法: * 1. 打开开发者工具 (F12) * 2. 切换到 Console 标签 * 3. 复制粘贴此脚本并回车 * 4. 进行正常操作,脚本会自动捕获并显示请求信息 */ (function() { console.log('🚀 参数捕获Hook已启动'); console.log('📍 监听目标: getInstituteDarenData 及相关API'); console.log('─'.repeat(80)); // 配置 const TARGET_APIS = [ 'getInstituteDarenData', 'authorTradeData', 'api/data', 'ark/api' ]; // 工具函数 function shouldCapture(url) { return TARGET_APIS.some(api => url.includes(api)); } function extractParams(url) { try { const urlObj = new URL(url); const params = {}; urlObj.searchParams.forEach((value, key) => { params[key] = value; }); return params; } catch (e) { return {}; } } function formatParams(params) { const signParams = ['verifyFp', 'fp', 'msToken', 'a_bogus']; const result = { sign: {}, business: {} }; Object.entries(params).forEach(([key, value]) => { if (signParams.includes(key)) { result.sign[key] = value; } else { result.business[key] = value; } }); return result; } function printCapturedRequest(method, url, params, headers) { console.log('\n' + '='.repeat(80)); console.log(`🔍 捕获到 ${method} 请求`); console.log('='.repeat(80)); // URL try { const urlObj = new URL(url); console.log(`\n📍 URL: ${urlObj.origin}${urlObj.pathname}`); } catch (e) { console.log(`\n📍 URL: ${url}`); } // 参数分组 const { sign, business } = formatParams(params); if (Object.keys(sign).length > 0) { console.log('\n🔑 验签参数:'); console.table(sign); } if (Object.keys(business).length > 0) { console.log('\n📋 业务参数:'); console.table(business); } // 关键请求头 if (headers) { const importantHeaders = {}; ['cookie', 'user-agent', 'referer', 'origin'].forEach(key => { if (headers[key]) { const value = headers[key]; importantHeaders[key] = value.length > 100 ? value.substring(0, 100) + '...' : value; } }); if (Object.keys(importantHeaders).length > 0) { console.log('\n📨 关键请求头:'); console.table(importantHeaders); } } // 调用栈 console.log('\n📚 调用栈:'); console.trace(); console.log('='.repeat(80) + '\n'); } // Hook XMLHttpRequest const originalXHROpen = XMLHttpRequest.prototype.open; const originalXHRSend = XMLHttpRequest.prototype.send; const originalXHRSetRequestHeader = XMLHttpRequest.prototype.setRequestHeader; XMLHttpRequest.prototype.setRequestHeader = function(header, value) { if (!this._requestHeaders) { this._requestHeaders = {}; } this._requestHeaders[header.toLowerCase()] = value; return originalXHRSetRequestHeader.apply(this, arguments); }; XMLHttpRequest.prototype.open = function(method, url) { this._method = method; this._url = url; return originalXHROpen.apply(this, arguments); }; XMLHttpRequest.prototype.send = function(data) { if (this._url && shouldCapture(this._url)) { const params = extractParams(this._url); printCapturedRequest( this._method, this._url, params, this._requestHeaders ); // 保存数据供后续分析 if (!window._capturedRequests) { window._capturedRequests = []; } window._capturedRequests.push({ timestamp: Date.now(), method: this._method, url: this._url, params: params, headers: this._requestHeaders, data: data }); } return originalXHRSend.apply(this, arguments); }; // Hook fetch const originalFetch = window.fetch; window.fetch = function(...args) { const url = typeof args[0] === 'string' ? args[0] : args[0].url; if (shouldCapture(url)) { const options = args[1] || {}; const params = extractParams(url); // 提取headers const headers = {}; if (options.headers) { if (options.headers instanceof Headers) { options.headers.forEach((value, key) => { headers[key.toLowerCase()] = value; }); } else { Object.entries(options.headers).forEach(([key, value]) => { headers[key.toLowerCase()] = value; }); } } printCapturedRequest( options.method || 'GET', url, params, headers ); // 保存数据 if (!window._capturedRequests) { window._capturedRequests = []; } window._capturedRequests.push({ timestamp: Date.now(), method: options.method || 'GET', url: url, params: params, headers: headers, data: options.body }); } return originalFetch.apply(this, arguments); }; // Hook WebSocket (如果需要) const originalWebSocket = window.WebSocket; window.WebSocket = function(url, protocols) { if (shouldCapture(url)) { console.log('🔌 WebSocket连接:', url); } return new originalWebSocket(url, protocols); }; // 添加全局辅助函数 window._showCapturedRequests = function() { if (!window._capturedRequests || window._capturedRequests.length === 0) { console.log('📭 暂无捕获的请求'); return; } console.log(`\n📊 已捕获 ${window._capturedRequests.length} 个请求:\n`); window._capturedRequests.forEach((req, index) => { const time = new Date(req.timestamp).toLocaleTimeString(); console.log(`${index + 1}. [${time}] ${req.method} ${req.url}`); }); console.log('\n💡 使用 window._capturedRequests[index] 查看详细信息'); }; window._clearCapturedRequests = function() { window._capturedRequests = []; console.log('🗑️ 已清空捕获的请求'); }; window._exportCapturedRequests = function() { if (!window._capturedRequests || window._capturedRequests.length === 0) { console.log('📭 暂无可导出的请求'); return; } const dataStr = JSON.stringify(window._capturedRequests, null, 2); const blob = new Blob([dataStr], { type: 'application/json' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = `captured_requests_${Date.now()}.json`; a.click(); URL.revokeObjectURL(url); console.log('💾 请求数据已导出'); }; // Hook常见的加密函数(如果存在) const cryptoFunctions = ['md5', 'sha1', 'sha256', 'hmac', 'sign', 'encrypt']; cryptoFunctions.forEach(funcName => { if (window[funcName] && typeof window[funcName] === 'function') { const original = window[funcName]; window[funcName] = function(...args) { console.log(`🔐 调用加密函数: ${funcName}`, args); const result = original.apply(this, args); console.log(`🔐 返回结果:`, result); return result; }; } }); // 监听全局变量变化(如果有签名相关的全局变量) const watchedGlobals = ['_signature', '_token', '_bogus', 'msToken']; watchedGlobals.forEach(varName => { let value = window[varName]; Object.defineProperty(window, varName, { get() { return value; }, set(newValue) { console.log(`📝 全局变量 ${varName} 被设置:`, newValue); console.trace('调用栈:'); value = newValue; } }); }); console.log('\n✅ Hook安装完成!'); console.log('\n💡 可用命令:'); console.log(' - window._showCapturedRequests() 查看所有捕获的请求'); console.log(' - window._clearCapturedRequests() 清空捕获记录'); console.log(' - window._exportCapturedRequests() 导出为JSON文件'); console.log(' - window._capturedRequests[0] 查看第一个请求详情'); console.log('\n🎯 现在可以进行正常操作,脚本会自动捕获请求!\n'); })();