守护线程 - walkes - JavaEye技术网站

本文介绍了守护线程的概念及其在Java中的应用。守护线程主要用于为其他线程提供辅助功能,并且不会阻碍程序的正常终止。文章还解释了如何将一个线程设置为守护线程,以及设置过程中可能遇到的异常情况。

 

守护线程
关键字: 守护线程

守护线程是为其他线程的运行提供便利的线程。守护线程不会阻止程序的终止。

Java的垃圾收集机制的某些实现就使用了守护线程。

非守护线程包括常规的用户线程或诸如用于处理GUI事件的事件调度线程。

程序可以包含守护线程和非守护线程。

程序只有守护线程时,该程序便可以结束运行。

如果要使一个线程成为守护线程,则必须在调用它的start方法之前进行设置(通过以true作为参数调用线程的setDaemon方法,可以将该线程定义为一个守护线程),否则会抛出IllegalThreadStateException异常。如果线程是守护线程,则isDaemon方法返回真。

注:1、如果在线程已经启动后,再试图使该线程成为守护线程,则会导致IllegalThreadStateException异常

        2、事件调度线程是一个无穷循环的线程,而不是守护线程。因而,在基于窗口的应用程序调用System类的exit方法之前,事件调度线程不会终止。

        3、不能将关键任务分配给守护线程。这些任务将会在事先没有警告的情况下终止,这可能导致不能正确地完成它们

守护线程 - walkes - JavaEye技术网站

<!DOCTYPE html> <html> <head> <title>终极版 JS 混淆解密工具</title> <style> /* 保留原有样式并优化布局 */ .container { max-width: 1400px; margin: 0 auto; padding: 20px; } .alert { padding: 10px 15px; margin: 10px 0; border-radius: 4px; display: none; } .alert.error { background: #fee; color: #d32f2f; } .alert.success { background: #efe; color: #2e7d32; } .alert.warning { background: #ffe; color: #f57c00; } .alert.show { display: block; } .config-panel { background: #f5f5f5; padding: 15px; border-radius: 4px; margin-bottom: 15px; } .config-group { display: flex; gap: 20px; flex-wrap: wrap; } .config-item { display: flex; align-items: center; gap: 5px; } .buttons { margin: 15px 0; display: flex; gap: 12px; } button { padding: 10px 20px; cursor: pointer; border: none; border-radius: 4px; background: #2196f3; color: white; transition: background 0.3s; } button:hover { background: #0b7dda; } button:disabled { background: #bbb; cursor: not-allowed; } .code-container { display: flex; gap: 20px; margin-top: 10px; } .code-box { flex: 1; display: flex; flex-direction: column; } textarea { width: 100%; height: 400px; padding: 12px; font-family: 'Consolas', monospace; border: 1px solid #ddd; border-radius: 4px; resize: vertical; } label { margin-bottom: 8px; font-weight: 500; } .progress { height: 4px; background: #eee; border-radius: 2px; margin: 10px 0; overflow: hidden; display: none; } .progress.show { display: block; } .progress-bar { height: 100%; background: #4caf50; width: 0%; transition: width 0.3s; } </style> </head> <body> <div class="container"> <div class="alert" id="alert"></div> <div class="config-panel"> <h4>混淆配置</h4> <div class="config-group"> <div class="config-item"> <input type="checkbox" id="mangleVars" checked> <label for="mangleVars">混淆变量名</label> </div> <div class="config-item"> <input type="checkbox" id="mangleFuncs" checked> <label for="mangleFuncs">混淆函数名</label> </div> <div class="config-item"> <input type="checkbox" id="mangleClasses" checked> <label for="mangleClasses">混淆类名</label> </div> <div class="config-item"> <input type="checkbox" id="flattenControl" checked> <label for="flattenControl">控制流扁平化</label> </div> <div class="config-item"> <input type="checkbox" id="antiDebug" checked> <label for="antiDebug">防调试保护</label> </div> </div> </div> <div class="buttons"> <button onclick="handleObfuscate()" id="obfBtn">混淆代码</button> <button onclick="handleDeobfuscate()" id="deobfBtn">解密代码</button> <button onclick="copyResult()">复制结果</button> </div> <div class="progress"> <div class="progress-bar" id="progressBar"></div> </div> <div class="code-container"> <div class="code-box"> <label for="inputCode">输入代码:</label> <textarea id="inputCode" placeholder="输入要处理的JS代码...">// 测试用例:模板字符串、try/catch、循环 const user = "World"; const str = `Hello ${user}! Current time: ${new Date().getHours()}`; try { let a = 10; if (a > 5) throw new Error("测试异常"); } catch (e) { let a = 20; // 应与try块中的a区分 console.log(`捕获异常: ${e.message}, a=${a}`); } // 循环结构测试 for (let i = 0; i < 3; i++) { console.log(`循环第${i}次`); } while (Math.random() > 0.5) { console.log("随机循环"); }</textarea> </div> <div class="code-box"> <label for="outputCode">处理结果:</label> <textarea id="outputCode" placeholder="处理结果将显示在这里..." spellcheck="false"></textarea> </div> </div> </div> <!-- 引入AST解析库 --> <script src="https://cdn.jsdelivr.net/npm/acorn@8.10.0/dist/acorn.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/walkes@0.2.0/walkes.min.js"></script> <!-- Web Worker 脚本 --> <script id="worker-script" type="javascript/worker"> // 导入所需库(Worker内通过importScripts加载) importScripts( 'https://cdn.jsdelivr.net/npm/acorn@8.10.0/dist/acorn.min.js', 'https://cdn.jsdelivr.net/npm/walkes@0.2.0/walkes.min.js', 'https://cdn.jsdelivr.net/npm/text-encoding@0.7.0/lib/encoding.min.js' ); // 模块封装:字符串工具 const StringUtil = (() => { class _StringUtil { /** * 处理模板字符串,分离静态和动态部分 * @param {string} template 模板字符串内容(不含外层`) * @returns {Array} 格式: [{type: 'static', value: 'xxx'}, {type: 'dynamic', value: 'expr'}] */ static parseTemplate(template) { const parts = []; let currentStatic = ''; let inExpression = false; let braceDepth = 0; for (let i = 0; i < template.length; i++) { // 检测模板表达式开始 ${ if (!inExpression && template[i] === '$' && template[i+1] === '{') { if (currentStatic) { parts.push({ type: 'static', value: currentStatic }); currentStatic = ''; } inExpression = true; i++; // 跳过{ continue; } // 检测模板表达式结束 } if (inExpression) { if (template[i] === '{') braceDepth++; if (template[i] === '}') { if (braceDepth === 0) { inExpression = false; continue; } braceDepth--; } parts.push({ type: 'dynamic', value: template[i] }); continue; } currentStatic += template[i]; } if (currentStatic) { parts.push({ type: 'static', value: currentStatic }); } return parts; } /** * 转义字符串中的引号 * @param {string} str 原始字符串 * @param {string} quote 目标引号 * @returns {string} 转义后字符串 */ static escapeQuotes(str, quote) { const escapeChar = quote === '"' ? '\\"' : "\\'"; return str.replace(new RegExp(quote, 'g'), escapeChar); } /** * 兼容IE的replaceAll * @param {string} str 原始字符串 * @param {string} search 搜索值 * @param {string} replacement 替换值 * @returns {string} 替换后字符串 */ static replaceAll(str, search, replacement) { return String.prototype.replaceAll ? str.replaceAll(search, replacement) : str.split(search).join(replacement); } } return _StringUtil; })(); // 模块封装:加密工具 const CryptoUtil = (() => { class _CryptoUtil { /** * 生成会话级密钥(存储在sessionStorage) * @returns {string} 随机密钥 */ static generateSessionKey() { const key = Array.from(window.crypto.getRandomValues(new Uint8Array(16))) .map(b => b.toString(16).padStart(2, '0')) .join(''); sessionStorage.setItem('obf_session_key', key); return key; } /** * 获取会话密钥 * @returns {string} 密钥 */ static getSessionKey() { return sessionStorage.getItem('obf_session_key') || this.generateSessionKey(); } /** * AES-GCM加密 * @param {string} str 待加密字符串 * @returns {Promise<object>} 加密结果 */ static async encrypt(str) { try { const keyMaterial = await window.crypto.subtle.importKey( 'raw', new TextEncoder().encode(this.getSessionKey()), { name: 'AES-GCM' }, false, ['encrypt'] ); const iv = window.crypto.getRandomValues(new Uint8Array(12)); const encrypted = await window.crypto.subtle.encrypt( { name: 'AES-GCM', iv }, keyMaterial, new TextEncoder().encode(str) ); return { data: btoa(String.fromCharCode(...new Uint8Array(encrypted))), iv: btoa(String.fromCharCode(...iv)), method: 'aes' }; } catch (e) { throw new Error(`加密失败: ${e.message}`); } } /** * AES-GCM解密 * @param {object} payload 加密数据 * @returns {Promise<string>} 解密结果 */ static async decrypt(payload) { try { const keyMaterial = await window.crypto.subtle.importKey( 'raw', new TextEncoder().encode(this.getSessionKey()), { name: 'AES-GCM' }, false, ['decrypt'] ); const iv = Uint8Array.from(atob(payload.iv), c => c.charCodeAt(0)); const encrypted = Uint8Array.from(atob(payload.data), c => c.charCodeAt(0)); const decrypted = await window.crypto.subtle.decrypt( { name: 'AES-GCM', iv }, keyMaterial, encrypted ); return new TextDecoder().decode(decrypted); } catch (e) { throw new Error(`解密失败: ${e.message}`); } } } return _CryptoUtil; })(); // 模块封装:作用域分析器 const ScopeAnalyzer = (() => { class _ScopeAnalyzer { constructor() { this.scopeStack = [new Map()]; // 初始全局作用域 this.varIndex = 0; } /** * 进入新作用域 */ enterScope() { this.scopeStack.push(new Map()); } /** * 退出当前作用域 */ exitScope() { if (this.scopeStack.length > 1) this.scopeStack.pop(); } /** * 生成安全变量名 * @returns {string} 变量名 */ generateVarName() { const keywords = new Set(['break', 'case', 'catch', 'class', 'const', 'continue', 'debugger', 'default', 'delete', 'do', 'else', 'export', 'extends', 'finally', 'for', 'function', 'if', 'import', 'in', 'instanceof', 'new', 'return', 'super', 'switch', 'this', 'throw', 'try', 'typeof', 'var', 'let', 'void', 'while', 'with', 'yield']); const chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; let name; do { const char = chars[this.varIndex % chars.length]; const num = Math.floor(this.varIndex / chars.length); name = `_${char}${num > 0 ? num : ''}`; this.varIndex++; } while (keywords.has(name) || this.isNameInScope(name)); return name; } /** * 检查变量名是否在作用域中存在 * @param {string} name 变量名 * @returns {boolean} 是否存在 */ isNameInScope(name) { return this.scopeStack.some(scope => Array.from(scope.values()).includes(name) ); } /** * 获取变量混淆名 * @param {string} originalName 原始变量名 * @returns {string} 混淆名 */ getMangledName(originalName) { const currentScope = this.scopeStack[this.scopeStack.length - 1]; if (currentScope.has(originalName)) { return currentScope.get(originalName); } const mangled = this.generateVarName(); currentScope.set(originalName, mangled); return mangled; } /** * 获取当前作用域链的所有变量映射 * @returns {Map} 变量映射表 */ getAllMappings() { return this.scopeStack.reduce((acc, scope) => { scope.forEach((v, k) => acc.set(k, v)); return acc; }, new Map()); } } return _ScopeAnalyzer; })(); // 模块封装:混淆器 const Obfuscator = (() => { class _Obfuscator { /** * 处理模板字符串 * @param {string} code 代码 * @returns {Promise<string>} 处理后代码 */ static async processTemplates(code) { const ast = acorn.parse(code, { ecmaVersion: 2020, sourceType: 'module' }); let result = code; let offset = 0; walkes(ast, { TemplateLiteral(node) { // 提取模板字符串内容 const start = node.start + offset; const end = node.end + offset; const templateRaw = code.slice(start, end); const templateContent = templateRaw.slice(1, -1); // 移除外层` // 解析静态和动态部分 const parts = StringUtil.parseTemplate(templateContent); if (parts.length === 0) return; // 加密静态部分 const processedParts = parts.map(async part => { if (part.type === 'static') { const encrypted = await CryptoUtil.encrypt(part.value); return `await CryptoUtil.decrypt(${JSON.stringify(encrypted)})`; } return part.value; // 动态部分保留原样 }); // 生成新模板字符串 Promise.all(processedParts).then(processed => { const newTemplate = `\`\${[${processed.join(',')}].join('')}\``; // 替换原始模板 result = result.slice(0, start) + newTemplate + result.slice(end); offset += newTemplate.length - (end - start); }); } }); return result; } /** * 处理作用域(包含try/catch) * @param {string} code 代码 * @returns {string} 处理后代码 */ static processScopes(code) { const analyzer = new ScopeAnalyzer(); const ast = acorn.parse(code, { ecmaVersion: 2020 }); // 遍历AST标记作用域 walkes(ast, { // 函数作用域 FunctionDeclaration(node) { analyzer.enterScope(); node.params.forEach(param => this.processParam(param, analyzer)); }, FunctionExpression(node) { analyzer.enterScope(); node.params.forEach(param => this.processParam(param, analyzer)); }, ArrowFunctionExpression(node) { analyzer.enterScope(); node.params.forEach(param => this.processParam(param, analyzer)); }, // 块级作用域 BlockStatement() { analyzer.enterScope(); }, // try/catch作用域 TryStatement(node) { analyzer.enterScope(); // try块 if (node.handler) { analyzer.enterScope(); // catch块 this.processParam(node.handler.param, analyzer); } }, // 类作用域 ClassDeclaration() { analyzer.enterScope(); }, // 退出作用域 'FunctionDeclaration:exit'() { analyzer.exitScope(); }, 'FunctionExpression:exit'() { analyzer.exitScope(); }, 'ArrowFunctionExpression:exit'() { analyzer.exitScope(); }, 'BlockStatement:exit'() { analyzer.exitScope(); }, 'TryStatement:exit'(node) { analyzer.exitScope(); // 退出try块 if (node.handler) analyzer.exitScope(); // 退出catch块 }, 'ClassDeclaration:exit'() { analyzer.exitScope(); } }, this); // 替换变量名 return this.replaceIdentifiers(code, analyzer.getAllMappings()); } /** * 处理函数参数 * @param {object} param 参数节点 * @param {ScopeAnalyzer} analyzer 作用域分析器 */ static processParam(param, analyzer) { if (param.type === 'Identifier') { analyzer.getMangledName(param.name); } } /** * 替换标识符 * @param {string} code 代码 * @param {Map} mappings 变量映射表 * @returns {string} 处理后代码 */ static replaceIdentifiers(code, mappings) { let result = code; mappings.forEach((mangled, original) => { const regex = new RegExp(`\\b${original}\\b(?!\\.)`, 'g'); result = StringUtil.replaceAll(result, regex, mangled); }); return result; } /** * 控制流扁平化(支持循环和switch) * @param {string} code 代码 * @returns {string} 处理后代码 */ static flattenControlFlow(code) { // 处理for循环 code = code.replace(/for\s*\(\s*let\s+(\w+)\s*=\s*(\d+)\s*;\s*\1\s*<\s*(\d+)\s*;\s*\1\+\+\s*\)\s*\{/g, (match, varName, start, end) => { return `{let ${varName}=${start};const _loop=()=>{if(${varName}<${end}){`; } ).replace(/}\s*(\/\/.*)?$/gm, (match) => { return `${match}${varName}++;_loop();}};_loop();}`; }); // 处理while循环 code = code.replace(/while\s*\((.*?)\)\s*\{/g, `{const _loop=()=>{if($1){` ).replace(/}\s*(\/\/.*)?$/gm, (match) => { return `${match}_loop();}};_loop();}`; }); // 处理if-else if-else let caseIdx = 1; code = code.replace(/if\s*\((.*?)\)\s*\{/g, () => { const idx = caseIdx++; return `switch(true){case ${idx}:`; }).replace(/}\s*else\s+if\s*\((.*?)\)\s*\{/g, () => { const idx = caseIdx++; return `break;case ${idx}:`; }).replace(/}\s*else\s*\{/g, 'break;default:'); return code; } /** * 添加防调试保护 * @param {string} code 代码 * @returns {string} 处理后代码 */ static addAntiDebug(code) { const antiDebugCode = ` (()=>{ const check = ()=>{ const t=performance.now(); debugger; if(performance.now()-t>160)throw new Error("检测到调试行为"); }; setInterval(check, 100); })(); `; return antiDebugCode + code; } /** * 分块处理大文件 * @param {string} code 代码 * @param {object} config 配置 * @returns {Promise<string>} 混淆结果 */ static async processInChunks(code, config) { const chunkSize = 1024 * 10; // 10KB每块 const chunks = []; for (let i = 0; i < code.length; i += chunkSize) { chunks.push(code.slice(i, i + chunkSize)); } // 并行处理所有块 const processedChunks = await Promise.all(chunks.map(async (chunk, idx) => { self.postMessage({ type: 'progress', value: Math.floor((idx / chunks.length) * 80) }); let processed = chunk; processed = await this.processTemplates(processed); processed = this.processScopes(processed); if (config.flattenControl) processed = this.flattenControlFlow(processed); return processed; })); let result = processedChunks.join(''); if (config.antiDebug) result = this.addAntiDebug(result); self.postMessage({ type: 'progress', value: 100 }); return result; } /** * 执行混淆 * @param {string} code 代码 * @param {object} config 配置 * @returns {Promise<string>} 混淆结果 */ static async run(code, config) { try { return await this.processInChunks(code, config); } catch (e) { const category = e.message.includes('加密') ? 'security' : 'syntax'; throw { message: e.message, category }; } } } return _Obfuscator; })(); // 模块封装:解密器 const Deobfuscator = (() => { class _Deobfuscator { /** * 分块解密 * @param {string} code 代码 * @returns {Promise<string>} 解密结果 */ static async processInChunks(code) { const chunkSize = 1024 * 10; const chunks = []; for (let i = 0; i < code.length; i += chunkSize) { chunks.push(code.slice(i, i + chunkSize)); } const processedChunks = await Promise.all(chunks.map(async (chunk, idx) => { self.postMessage({ type: 'progress', value: Math.floor((idx / chunks.length) * 100) }); return await this.restoreStrings(chunk); })); return processedChunks.join(''); } /** * 还原加密字符串 * @param {string} code 代码 * @returns {Promise<string>} 处理后代码 */ static async restoreStrings(code) { const regex = /await CryptoUtil\.decrypt\((\{.*?\})\)/g; const matches = []; let match; while ((match = regex.exec(code)) !== null) { matches.push({ full: match[0], payload: JSON.parse(match[1]), index: match.index }); } // 倒序替换 matches.sort((a, b) => b.index - a.index).forEach(async (item) => { try { const decrypted = await CryptoUtil.decrypt(item.payload); code = code.slice(0, item.index) + decrypted + code.slice(item.index + item.full.length); } catch (e) { console.warn(`解密片段失败: ${e.message}`); } }); return code; } /** * 执行解密 * @param {string} code 代码 * @returns {Promise<string>} 解密结果 */ static async run(code) { try { return await this.processInChunks(code); } catch (e) { const category = e.message.includes('解密') ? 'security' : 'syntax'; throw { message: e.message, category }; } } } return _Deobfuscator; })(); // Worker消息处理 self.onmessage = async (e) => { const { type, code, config } = e.data; try { // 暴露加密工具供解密函数使用 self.CryptoUtil = CryptoUtil; let result; if (type === 'obfuscate') { result = await Obfuscator.run(code, config); } else { result = await Deobfuscator.run(code); } self.postMessage({ type: 'success', result }); } catch (e) { self.postMessage({ type: 'error', message: e.message, category: e.category || 'unknown' }); } }; </script> <script> // 主页面脚本 (() => { // 工具函数 const showAlert = (message, isError = true, category = 'unknown') => { const alertEl = document.getElementById('alert'); alertEl.textContent = message; alertEl.className = `alert ${ isError ? (category === 'security' ? 'error' : 'error') : 'success' } show`; setTimeout(() => alertEl.classList.remove('show'), 3000); }; const updateProgress = (percent) => { const progress = document.querySelector('.progress'); const bar = document.getElementById('progressBar'); progress.classList.add('show'); bar.style.width = `${Math.min(100, percent)}%`; if (percent >= 100) { setTimeout(() => progress.classList.remove('show'), 500); } }; // 创建Web Worker const createWorker = () => { const workerScript = document.getElementById('worker-script').textContent; const blob = new Blob([workerScript], { type: 'application/javascript' }); const url = URL.createObjectURL(blob); return new Worker(url); }; // 混淆处理 window.handleObfuscate = () => { const input = document.getElementById('inputCode').value.trim(); if (!input) return showAlert('请输入要混淆的代码'); const obfBtn = document.getElementById('obfBtn'); obfBtn.disabled = true; updateProgress(0); const worker = createWorker(); const config = { mangleVars: document.getElementById('mangleVars').checked, mangleFuncs: document.getElementById('mangleFuncs').checked, mangleClasses: document.getElementById('mangleClasses').checked, flattenControl: document.getElementById('flattenControl').checked, antiDebug: document.getElementById('antiDebug').checked }; worker.onmessage = (e) => { if (e.data.type === 'progress') { updateProgress(e.data.value); } else if (e.data.type === 'success') { document.getElementById('outputCode').value = e.data.result; showAlert('混淆成功', false); obfBtn.disabled = false; } else if (e.data.type === 'error') { showAlert(`混淆失败: ${e.data.message}`, true, e.data.category); obfBtn.disabled = false; } }; worker.postMessage({ type: 'obfuscate', code: input, config }); }; // 解密处理 window.handleDeobfuscate = () => { const input = document.getElementById('inputCode').value.trim(); if (!input) return showAlert('请输入要解密的代码'); const deobfBtn = document.getElementById('deobfBtn'); deobfBtn.disabled = true; updateProgress(0); const worker = createWorker(); worker.onmessage = (e) => { if (e.data.type === 'progress') { updateProgress(e.data.value); } else if (e.data.type === 'success') { document.getElementById('outputCode').value = e.data.result; showAlert('解密成功', false); deobfBtn.disabled = false; } else if (e.data.type === 'error') { showAlert(`解密失败: ${e.data.message}`, true, e.data.category); deobfBtn.disabled = false; } }; worker.postMessage({ type: 'deobfuscate', code: input }); }; // 复制结果 window.copyResult = () => { const output = document.getElementById('outputCode'); if (!output.value) return showAlert('没有可复制的内容'); output.select(); document.execCommand('copy'); showAlert('复制成功', false); }; })(); </script> </body> </html>
11-06
<!DOCTYPE html> <html> <head> <title>AST缓存与闭包优化版 JS 混淆工具</title> <style> .container { max-width: 1400px; margin: 0 auto; padding: 20px; } .alert { padding: 10px 15px; margin: 10px 0; border-radius: 4px; display: none; } .alert.error { background: #fee; color: #d32f2f; } .alert.success { background: #efe; color: #2e7d32; } .alert.show { display: block; } .config-panel { background: #f5f5f5; padding: 15px; border-radius: 4px; margin-bottom: 15px; } .config-group { display: flex; gap: 20px; flex-wrap: wrap; } .config-item { display: flex; align-items: center; gap: 5px; } .buttons { margin: 15px 0; display: flex; gap: 12px; } button { padding: 10px 20px; cursor: pointer; border: none; border-radius: 4px; background: #2196f3; color: white; transition: background 0.3s; } button:hover { background: #0b7dda; } button:disabled { background: #bbb; cursor: not-allowed; } .code-container { display: flex; gap: 20px; margin-top: 10px; } .code-box { flex: 1; display: flex; flex-direction: column; } textarea { width: 100%; height: 400px; padding: 12px; font-family: 'Consolas', monospace; border: 1px solid #ddd; border-radius: 4px; resize: vertical; } label { margin-bottom: 8px; font-weight: 500; } .progress { height: 4px; background: #eee; border-radius: 2px; margin: 10px 0; overflow: hidden; display: none; } .progress.show { display: block; } .progress-bar { height: 100%; background: #4caf50; width: 0%; transition: width 0.3s; } </style> </head> <body> <div class="container"> <div class="alert" id="alert"></div> <div class="config-panel"> <h4>混淆配置</h4> <div class="config-group"> <div class="config-item"> <input type="checkbox" id="mangleVars" checked> <label for="mangleVars">混淆变量名</label> </div> <div class="config-item"> <input type="checkbox" id="mangleFuncs" checked> <label for="mangleFuncs">混淆函数名</label> </div> <div class="config-item"> <input type="checkbox" id="flattenControl" checked> <label for="flattenControl">控制流扁平化</label> </div> <div class="config-item"> <input type="checkbox" id="antiDebug" checked> <label for="antiDebug">防调试保护</label> </div> </div> </div> <div class="buttons"> <button onclick="handleObfuscate()" id="obfBtn">混淆代码</button> <button onclick="handleDeobfuscate()" id="deobfBtn">解密代码</button> <button onclick="copyResult()">复制结果</button> </div> <div class="progress"> <div class="progress-bar" id="progressBar"></div> </div> <div class="code-container"> <div class="code-box"> <label for="inputCode">输入代码:</label> <textarea id="inputCode" placeholder="输入要处理的JS代码...">// 测试用例:闭包+嵌套模板+循环累加 function outer() { let count = 0; // 闭包变量 const prefix = "计数:"; // 嵌套模板字符串 const log = (step) => `嵌套${prefix}${step} - ${count++}`; // 循环累加测试 let sum = 0; for (let j = 0; j < 10000; j++) { sum += j; } console.log(`总和:${sum}`); return () => log("内部调用"); } const inner = outer(); console.log(inner()); console.log(inner()); // 多层嵌套模板 const a = true; const b = "测试"; const c = "默认"; const nested = `嵌套${a ? `内部${b}` : c}`;</textarea> </div> <div class="code-box"> <label for="outputCode">处理结果:</label> <textarea id="outputCode" placeholder="处理结果将显示在这里..." spellcheck="false"></textarea> </div> </div> </div> <script src="https://cdn.jsdelivr.net/npm/acorn@8.10.0/dist/acorn.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/walkes@0.2.0/walkes.min.js"></script> <script id="worker-script" type="javascript/worker"> importScripts( 'https://cdn.jsdelivr.net/npm/acorn@8.10.0/dist/acorn.min.js', 'https://cdn.jsdelivr.net/npm/walkes@0.2.0/walkes.min.js', 'https://cdn.jsdelivr.net/npm/text-encoding@0.7.0/lib/encoding.min.js' ); // 模块封装:AST缓存管理器 const ASTCache = (() => { class _ASTCache { constructor() { this.cache = new Map(); // 存储哈希值 -> AST的映射 this.maxSize = 50; // 最大缓存条目数 } /** * 生成代码片段的哈希值(用于缓存键) * @param {string} code 代码片段 * @returns {string} 哈希字符串 */ generateHash(code) { let hash = 0; for (let i = 0; i < code.length; i++) { const char = code.charCodeAt(i); hash = ((hash << 5) - hash) + char; hash |= 0; // 转换为32位整数 } return hash.toString(16); } /** * 获取缓存的AST * @param {string} code 代码片段 * @returns {object|undefined} AST对象或undefined */ getAST(code) { const hash = this.generateHash(code); return this.cache.get(hash); } /** * 缓存AST * @param {string} code 代码片段 * @param {object} ast AST对象 */ setAST(code, ast) { const hash = this.generateHash(code); // 缓存满时移除最旧的条目 if (this.cache.size >= this.maxSize) { const oldestKey = this.cache.keys().next().value; this.cache.delete(oldestKey); } this.cache.set(hash, ast); } /** * 解析代码并使用缓存 * @param {string} code 代码片段 * @returns {object} AST对象 */ parseWithCache(code) { const cachedAST = this.getAST(code); if (cachedAST) { return cachedAST; } // 新解析并缓存 const ast = acorn.parse(code, { ecmaVersion: 2020 }); this.setAST(code, ast); return ast; } } return new _ASTCache(); // 单例模式 })(); // 模块封装:字符串工具(增强嵌套模板解析) const StringUtil = (() => { class _StringUtil { /** * 查找模板表达式结束位置(支持多层嵌套) * @param {string} template 模板内容 * @param {number} start 起始索引 * @returns {number} 结束索引 */ static findExpressionEnd(template, start) { let depth = 1; for (let i = start; i < template.length; i++) { if (template[i] === '{' && template[i-1] === '$') depth++; // 检测嵌套${ if (template[i] === '}') { if (--depth === 0) return i; } } return template.length; } /** * 解析嵌套模板字符串 * @param {string} template 模板内容 * @returns {Array} 解析结果 */ static parseTemplate(template) { const parts = []; let pos = 0; while (pos < template.length) { if (template.substr(pos, 2) === '${') { // 添加静态部分 if (pos > 0) { parts.push({ type: 'static', value: template.slice(0, pos) }); } // 解析动态表达式(支持嵌套) const exprStart = pos + 2; const exprEnd = this.findExpressionEnd(template, exprStart); parts.push({ type: 'dynamic', value: template.slice(exprStart, exprEnd) }); // 移动指针 template = template.slice(exprEnd + 1); pos = 0; } else { pos++; } } // 添加剩余静态内容 if (template.length > 0) { parts.push({ type: 'static', value: template }); } return parts; } } return _StringUtil; })(); // 模块封装:作用域与闭包分析器 const ScopeAnalyzer = (() => { class _ScopeAnalyzer { constructor() { this.scopeStack = [new Map()]; // 作用域栈 this.varIndex = 0; this.closureVars = new Set(); // 闭包变量集合 this.currentScopeId = 0; // 用于追踪作用域关系 this.scopeRelations = new Map(); // 作用域ID -> 父作用域ID } enterScope() { const newScopeId = ++this.currentScopeId; this.scopeRelations.set(newScopeId, this.scopeStack.length - 1); this.scopeStack.push(new Map()); } exitScope() { if (this.scopeStack.length > 1) { this.scopeStack.pop(); } } /** * 追踪闭包变量(跨作用域引用的变量) * @param {string} varName 变量名 * @returns {boolean} 是否为闭包变量 */ trackClosureVar(varName) { // 检查变量是否在当前作用域 const currentScope = this.scopeStack[this.scopeStack.length - 1]; if (currentScope.has(varName)) { return false; } // 检查是否在父作用域中存在 for (let i = this.scopeStack.length - 2; i >= 0; i--) { if (this.scopeStack[i].has(varName)) { this.closureVars.add(varName); return true; } } return false; } /** * 处理闭包变量(从AST中识别) * @param {object} ast AST对象 */ processClosureVars(ast) { const self = this; walkes(ast, { Identifier(node) { // 引用变量时检查是否为闭包变量 self.trackClosureVar(node.name); }, FunctionExpression: () => self.enterScope(), 'FunctionExpression:exit': () => self.exitScope(), ArrowFunctionExpression: () => self.enterScope(), 'ArrowFunctionExpression:exit': () => self.exitScope() }); } // 其他方法(变量名生成等)保持不变 generateVarName() { const keywords = new Set(['break', 'case', 'catch', 'class', 'const', 'continue', 'debugger', 'default', 'delete', 'do', 'else', 'export', 'extends', 'finally', 'for', 'function', 'if', 'import', 'in', 'instanceof', 'new', 'return', 'super', 'switch', 'this', 'throw', 'try', 'typeof', 'var', 'let', 'void', 'while', 'with', 'yield']); const chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; let name; do { const char = chars[this.varIndex % chars.length]; const num = Math.floor(this.varIndex / chars.length); name = `_${char}${num > 0 ? num : ''}`; this.varIndex++; } while (keywords.has(name) || this.isNameInScope(name)); return name; } isNameInScope(name) { return this.scopeStack.some(scope => Array.from(scope.values()).includes(name) ); } getMangledName(originalName) { // 闭包变量使用特殊命名规则(避免混淆后引用失效) if (this.closureVars.has(originalName)) { const currentScope = this.scopeStack[this.scopeStack.length - 1]; if (!currentScope.has(originalName)) { currentScope.set(originalName, `_c${originalName}`); // 闭包变量前缀标记 } return currentScope.get(originalName); } // 普通变量处理 const currentScope = this.scopeStack[this.scopeStack.length - 1]; if (currentScope.has(originalName)) { return currentScope.get(originalName); } const mangled = this.generateVarName(); currentScope.set(originalName, mangled); return mangled; } } return _ScopeAnalyzer; })(); // 模块封装:混淆器(含调试保护优化) const Obfuscator = (() => { class _Obfuscator { /** * 处理模板字符串(支持多层嵌套) * @param {string} code 代码 * @returns {Promise<string>} 处理后代码 */ static async processTemplates(code) { // 使用AST缓存 const ast = ASTCache.parseWithCache(code); let result = code; let offset = 0; walkes(ast, { TemplateLiteral: (node) => { const start = node.start + offset; const end = node.end + offset; const templateRaw = code.slice(start, end); const templateContent = templateRaw.slice(1, -1); const parts = StringUtil.parseTemplate(templateContent); if (parts.length === 0) return; const processedParts = parts.map(async (part) => { if (part.type === 'static') { const encrypted = await CryptoUtil.encrypt(part.value); return `await CryptoUtil.decrypt(${JSON.stringify(encrypted)})`; } else { // 递归处理嵌套模板中的表达式 return this.processNestedExpressions(part.value); } }); Promise.all(processedParts).then(processed => { const newTemplate = `\`\${[${processed.join(',')}].join('')}\``; result = result.slice(0, start) + newTemplate + result.slice(end); offset += newTemplate.length - (end - start); }); } }); return result; } /** * 处理嵌套表达式中的模板字符串 * @param {string} expr 表达式字符串 * @returns {string} 处理后表达式 */ static processNestedExpressions(expr) { // 检测表达式中是否包含模板字符串 if (expr.includes('`')) { // 使用AST缓存解析嵌套模板 const ast = ASTCache.parseWithCache(`(${expr})`); let processedExpr = expr; let offset = 0; walkes(ast, { TemplateLiteral: (node) => { const start = node.start + offset - 1; // 调整括号偏移 const end = node.end + offset - 1; const templateRaw = expr.slice(start, end); const templateContent = templateRaw.slice(1, -1); const parts = StringUtil.parseTemplate(templateContent); if (parts.length === 0) return; const processedParts = parts.map(part => part.type === 'static' ? `\${await CryptoUtil.decrypt(...)}` : part.value ); const newTemplate = `\`\${[${processedParts.join(',')}].join('')}\``; processedExpr = processedExpr.slice(0, start) + newTemplate + processedExpr.slice(end); offset += newTemplate.length - (end - start); } }); return processedExpr; } return expr; } /** * 处理作用域与闭包变量 * @param {string} code 代码 * @returns {string} 处理后代码 */ static processScopes(code) { const analyzer = new ScopeAnalyzer(); const ast = ASTCache.parseWithCache(code); // 先识别闭包变量 analyzer.processClosureVars(ast); // 再处理作用域 walkes(ast, { FunctionDeclaration: (node) => { analyzer.enterScope(); node.params.forEach(param => this.processParam(param, analyzer)); }, FunctionExpression: (node) => { analyzer.enterScope(); node.params.forEach(param => this.processParam(param, analyzer)); }, ArrowFunctionExpression: (node) => { analyzer.enterScope(); node.params.forEach(param => this.processParam(param, analyzer)); }, BlockStatement: () => analyzer.enterScope(), TryStatement: (node) => { analyzer.enterScope(); if (node.handler) { analyzer.enterScope(); this.processParam(node.handler.param, analyzer); } }, ForStatement: (node) => { if (node.init?.type === 'VariableDeclaration' && node.init.kind === 'let') { analyzer.enterScope(); node.init.declarations.forEach(decl => { if (decl.id.type === 'Identifier') { analyzer.getMangledName(decl.id.name); } }); } }, 'FunctionDeclaration:exit': () => analyzer.exitScope(), 'FunctionExpression:exit': () => analyzer.exitScope(), 'ArrowFunctionExpression:exit': () => analyzer.exitScope(), 'BlockStatement:exit': () => analyzer.exitScope(), 'TryStatement:exit': (node) => { analyzer.exitScope(); if (node.handler) analyzer.exitScope(); }, 'ForStatement:exit': (node) => { if (node.init?.type === 'VariableDeclaration' && node.init.kind === 'let') { analyzer.exitScope(); } } }, this); return this.replaceIdentifiers(code, analyzer); } /** * 替换标识符(保留闭包变量引用) * @param {string} code 代码 * @param {ScopeAnalyzer} analyzer 分析器 * @returns {string} 处理后代码 */ static replaceIdentifiers(code, analyzer) { let result = code; const mappings = analyzer.getAllMappings(); // 优先处理闭包变量(避免被普通变量替换规则覆盖) analyzer.closureVars.forEach(varName => { const mangled = mappings.get(varName); if (mangled) { const regex = new RegExp(`\\b${varName}\\b(?!\\.)`, 'g'); result = result.replace(regex, mangled); } }); // 处理普通变量 mappings.forEach((mangled, original) => { if (!analyzer.closureVars.has(original)) { const regex = new RegExp(`\\b${original}\\b(?!\\.)`, 'g'); result = result.replace(regex, mangled); } }); return result; } /** * 循环状态机转换(确保累加正确性) * @param {string} code 代码 * @returns {string} 处理后代码 */ static flattenControlFlow(code) { let loopId = 0; // 处理for循环(确保累加逻辑正确) code = code.replace(/for\s*\(\s*let\s+(\w+)\s*=\s*(\d+)\s*;\s*\1\s*<\s*(\d+)\s*;\s*\1\+\+\s*\)\s*\{/g, (match, varName, start, end) => { const id = loopId++; return `{let ${varName}=${start};let _s${id}=0;while(_s${id}!==-1){switch(_s${id}){case 0:${varName}=${start};_s${id}=1;break;case 1:if(${varName}<${end}){_s${id}=2;}else{_s${id}=-1;}break;case 2:`; } ).replace(/}\s*(?=[^\}])/g, (match) => { const id = loopId - 1; return `${match}${varName}++;_s${id}=1;break;}}}`; }); return code; } /** * 优化的防调试保护(含性能检测) * @param {string} code 代码 * @returns {string} 处理后代码 */ static addAntiDebug(code) { const antiDebugCode = ` (()=>{ let antiDebugActive = true; // 性能检测:内存超限关闭保护 const checkPerformance = () => { if (performance?.memory?.usedJSHeapSize > 500_000_000) { antiDebugActive = false; } }; // 多层防调试陷阱 const traps = [ ()=>{if(!antiDebugActive)return;try{debugger}catch(e){location.reload()}}, ()=>{if(!antiDebugActive)return;if(console?.profile){console.profile();console.profileEnd()}}, ()=>{if(!antiDebugActive)return;const s=performance.now();debugger;if(performance.now()-s>160)throw new Error("调试检测")} ]; // 随机执行陷阱 setInterval(()=>{ checkPerformance(); if(antiDebugActive)traps[Math.floor(Math.random()*traps.length)](); }, 300); })(); `; return antiDebugCode + code; } /** * 执行混淆 * @param {string} code 代码 * @param {object} config 配置 * @returns {Promise<string>} 混淆结果 */ static async run(code, config) { let processed = code; processed = await this.processTemplates(processed); // 使用AST缓存提升处理速度 const ast = ASTCache.parseWithCache(processed); processed = this.processScopes(processed); if (config.flattenControl) { processed = this.flattenControlFlow(processed); } if (config.antiDebug) { processed = this.addAntiDebug(processed); } return processed; } } return _Obfuscator; })(); // 其他模块(CryptoUtil、Deobfuscator)保持核心逻辑不变,略... // 加密工具(复用之前的安全实现) const CryptoUtil = (() => { class _CryptoUtil { static #keyCache = new WeakMap(); static generateKey() { return Array.from(crypto.getRandomValues(new Uint8Array(32))) .map(b => b.toString(16).padStart(2, '0')) .join(''); } static getSessionKey() { if (!this.#keyCache.has(self)) { this.#keyCache.set(self, this.generateKey()); } return this.#keyCache.get(self); } static async encrypt(str) { try { const key = this.getSessionKey(); const keyMaterial = await crypto.subtle.importKey( 'raw', new TextEncoder().encode(key), { name: 'AES-GCM' }, false, ['encrypt'] ); const iv = crypto.getRandomValues(new Uint8Array(12)); const encrypted = await crypto.subtle.encrypt( { name: 'AES-GCM', iv }, keyMaterial, new TextEncoder().encode(str) ); return { data: btoa(String.fromCharCode(...new Uint8Array(encrypted))), iv: btoa(String.fromCharCode(...iv)), method: 'aes' }; } catch (e) { throw new Error(`加密失败: ${e.message}`); } } static async decrypt(payload) { try { const key = this.getSessionKey(); const keyMaterial = await crypto.subtle.importKey( 'raw', new TextEncoder().encode(key), { name: 'AES-GCM' }, false, ['decrypt'] ); const iv = Uint8Array.from(atob(payload.iv), c => c.charCodeAt(0)); const encrypted = Uint8Array.from(atob(payload.data), c => c.charCodeAt(0)); const decrypted = await crypto.subtle.decrypt( { name: 'AES-GCM', iv }, keyMaterial, encrypted ); return new TextDecoder().decode(decrypted); } catch (e) { throw new Error(`解密失败: ${e.message}`); } } } return _CryptoUtil; })(); // 解密器 const Deobfuscator = (() => { class _Deobfuscator { static async run(code) { const regex = /await CryptoUtil\.decrypt\((\{.*?\})\)/g; const matches = []; let match; while ((match = regex.exec(code)) !== null) { matches.push({ full: match[0], payload: JSON.parse(match[1]), index: match.index }); } matches.sort((a, b) => b.index - a.index).forEach(async (item) => { try { const decrypted = await CryptoUtil.decrypt(item.payload); code = code.slice(0, item.index) + decrypted + code.slice(item.index + item.full.length); } catch (e) { console.warn(`解密失败: ${e.message}`); } }); return code; } } return _Deobfuscator; })(); // Worker消息处理 self.onmessage = async (e) => { const code = new TextDecoder().decode(e.data.buffer); const { type, config } = e.data; try { self.CryptoUtil = CryptoUtil; let result; if (type === 'obfuscate') { result = await Obfuscator.run(code, config); } else { result = await Deobfuscator.run(code); } const encoder = new TextEncoder(); const buffer = encoder.encode(result).buffer; self.postMessage({ type: 'success', buffer }, [buffer]); } catch (e) { self.postMessage({ type: 'error', message: e.message }); } }; </script> <script> // 主页面脚本 (() => { const showAlert = (message, isError = true) => { const alertEl = document.getElementById('alert'); alertEl.textContent = message; alertEl.className = `alert ${isError ? 'error' : 'success'} show`; setTimeout(() => alertEl.classList.remove('show'), 3000); }; const updateProgress = (percent) => { const progress = document.querySelector('.progress'); const bar = document.getElementById('progressBar'); progress.classList.add('show'); bar.style.width = `${percent}%`; if (percent >= 100) { setTimeout(() => progress.classList.remove('show'), 500); } }; const createWorker = () => { const workerScript = document.getElementById('worker-script').textContent; const blob = new Blob([workerScript], { type: 'application/javascript' }); const url = URL.createObjectURL(blob); return new Worker(url); }; window.handleObfuscate = () => { const input = document.getElementById('inputCode').value.trim(); if (!input) return showAlert('请输入代码'); const obfBtn = document.getElementById('obfBtn'); obfBtn.disabled = true; updateProgress(10); const encoder = new TextEncoder(); const data = encoder.encode(input); const worker = createWorker(); const config = { mangleVars: document.getElementById('mangleVars').checked, mangleFuncs: document.getElementById('mangleFuncs').checked, flattenControl: document.getElementById('flattenControl').checked, antiDebug: document.getElementById('antiDebug').checked }; worker.onmessage = (e) => { if (e.data.type === 'success') { const result = new TextDecoder().decode(e.data.buffer); document.getElementById('outputCode').value = result; updateProgress(100); showAlert('混淆成功', false); obfBtn.disabled = false; } else if (e.data.type === 'error') { showAlert(`混淆失败: ${e.data.message}`); obfBtn.disabled = false; } }; worker.postMessage({ type: 'obfuscate', buffer: data.buffer, config }, [data.buffer]); }; window.handleDeobfuscate = () => { const input = document.getElementById('inputCode').value.trim(); if (!input) return showAlert('请输入代码'); const deobfBtn = document.getElementById('deobfBtn'); deobfBtn.disabled = true; updateProgress(10); const encoder = new TextEncoder(); const data = encoder.encode(input); const worker = createWorker(); worker.onmessage = (e) => { if (e.data.type === 'success') { const result = new TextDecoder().decode(e.data.buffer); document.getElementById('outputCode').value = result; updateProgress(100); showAlert('解密成功', false); deobfBtn.disabled = false; } else if (e.data.type === 'error') { showAlert(`解密失败: ${e.data.message}`); deobfBtn.disabled = false; } }; worker.postMessage({ type: 'deobfuscate', buffer: data.buffer }, [data.buffer]); }; window.copyResult = () => { const output = document.getElementById('outputCode'); if (!output.value) return showAlert('没有可复制的内容'); output.select(); document.execCommand('copy'); showAlert('复制成功', false); }; })(); </script> </body> </html>
最新发布
11-06
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值