字符串混淆
所有字符串字面量被收集进加密常量池,按需解密。原始字符串不再以明文形式出现。
三层叠加保护:字符串加密、OLLVM 风格控制流平坦化、自定义虚拟机字节码。无法安全虚拟化的语法会自动降级为强混淆,确保运行结果与原文件完全一致。
function checkLicense(key) {
if (key === "SK-PROD-2024") {
return true;
}
return false;
}
var _0x4f2a=_0x8b91(0x1a);function _0x2c91(_0x3d){var _0x1e=[0x53,0x4b];while(!![]){switch(_0x4f2a(0x1a3)){case 0x7:if(_0x3d===_0xe4(0x2b1,0x7))return _0x4f2a(0xff);case 0x21:return _0x4f2a(0x100);}}}
所有字符串字面量被收集进加密常量池,按需解密。原始字符串不再以明文形式出现。
函数体切分为基本块,重组为 switch(state) 状态机分发,叠加不透明控制流噪声。
可虚拟化的函数被编译为自定义操作码,由运行时栈式 VM 执行,源逻辑隐藏在随机化 dispatcher 之后。
检测时间差异常、自动化环境、被 patch 的原生方法,以及可疑的运行时特征。
识别 jsdom、Headless Chrome、Puppeteer、Selenium 等自动化分析环境。
将保护产物绑定到指定域名。fail-closed 模式会阻止未知环境下的执行。
采用紧凑二进制 payload、函数级懒解密、派生密钥与完整性校验,而非可读的 JSON 中间表示。
HTML 内联事件(onclick)、外部脚本和全局 API 通常按函数名调用。使用 /* @public */ 保留导出名,使用 /* @VM */ 优先为关键函数启用 VM 保护。
/* @public */;关键算法函数可再加 /* @VM */ 强制尝试 VM。/* @public */ function myFunction(){
// 函数名会被保留,onclick 才能正常调用。
return compute();
}
保留导出名字,避免重命名破坏 onclick="myFunction()"、外部 script 或 window.x 调用。函数内部变量仍会继续混淆。
/* @VM */ function score(a, b){
return (a ^ b) + 123;
}
强制为该函数尝试 VM 化。csp-safe 与 compat 仍会做保守检查;若当前模式无法安全 VM 化,会自动降级并给出 warning。
/* @public @VM */ function submitForm(){
return protectedSubmit();
}
两者可以组合使用。@public 只负责保留名字,@VM 只负责强制尝试虚拟化,互不冲突。
/* @public */ function exportedApi(){ return 1; }
/* @public */ const exportedFn = function(){ return 2; };
/* @public */ const exportedArrow = (x) => x + 1;
/* @VM */ const core = function(x){ return x * 7; };
/* @public @VM */ const publicCore = function(x){
return core(x) + 1;
};
把标记写在函数声明或变量声明之前最稳定。@public 与 @VM 的推荐写法保持一致。
<button onclick="submitForm()">提交</button>
<script>
/* @public @VM */ function submitForm(){
var token = buildToken();
console.log(token);
}
/* @VM */ function buildToken(){
return Date.now() ^ 0x5a5a;
}
</script>
submitForm 被 HTML 字符串引用,所以必须标注 @public;它也可以同时标注 @VM。内部算法 buildToken 没有被 HTML 直接引用,只需要 @VM 即可。
@public 不会降低保护强度,它只保留外部可见的名字。@VM 是强制尝试,不是强制破坏兼容性。在 allowEval=false 的模式下,捕获外层局部变量的函数可能会降级并返回 warning。建议把标记写在声明之前,避免写在 return 语句中间。