函数的 toString() 方法仅能获取函数原始定义字符串,用于静态混淆特征初筛,但无法还原加密逻辑或应对动态代码、构建工具处理及高级混淆,需配合 AST 解析与多层检测。
函数的 tostring() 方法本身不能直接实现代码混淆检测或逻辑分析,但它可以作为**辅助手段获取函数原始定义字符串**,从而为后续分析提供基础输入。关键在于:它返回的是函数声明/表达式在源码中的文本形式(非运行时行为),这对识别某些静态混淆特征(如字符串拼接、base64、控制流扁平化痕迹)有一定价值,但无法还原加密逻辑或处理动态生成的代码。
获取未压缩/未转译的函数源码
现代 JS 环境中,function.toString() 通常返回函数定义的原始字符串(包括注释、空格和换行),前提是该函数不是内置函数(如 Array.prototype.map 返回 "function map() { [native code] }")或箭头函数在某些打包工具中被重写。这使得你可以检查其是否包含可疑模式:
- 大量连续的字符串拼接:
"eval" + "(" + atob("...") + ")" - 显式的 Base64 解码调用:
atob(...)、btoa(...) - 重复的无意义变量名:
var _0x123a = [...]; var _0x456b = [...]; - 异常长的单行函数体(可能被压缩器合并)
识别常见混淆结构(需配合正则或 AST)
仅靠字符串匹配较脆弱,但可快速初筛。例如:
const fn = function() {
const key = '789';
return 'abc' + key + 'def';
};
console.log(fn.toString());
// → "function() {
const key = '789';
return 'abc' + key + 'def';
}"若发现类似 return eval(atob("...")) 或 _0x2a3b[0x1c](_0x2a3b[0x2d]) 这类模式,就值得进一步用 AST 工具(如 acorn 或 esprima)解析语法树,判断是否为典型的混淆器输出(如 JavaScript Obfuscator 的 stringArray + rotatedStrings)。
注意局限性与反制措施
该方法极易失效,尤其在生产环境中:
- Webpack/Vite 等构建工具常将函数内联、拆分或转为箭头函数,
toString()返回结果不可靠 - 服务端渲染(SSR)或代码分割后,目标函数可能尚未加载
- 高级混淆器(如 Dead Code Injection、Control Flow Flattening)会让字符串内容看似“正常”,但逻辑已完全重构
- 恶意代码可能主动覆盖
toString方法:fn.toString = () => "function x(){}"
实用建议:轻量级检测可这样组合使用
不追求 100% 准确,而是作为前端运行时的一道简单探针:
- 对关键函数(如登录校验、支付签名)调用
toString(),用正则扫描/atobs*(|btoas*(|evals*(|_0x[0-9a-f]{3,}|\u[da-f]{4}/i - 若匹配成功,记录日志并上报函数名 + 截断后的源码片段(避免敏感信息)
- 配合
Function.constructor检查是否被重写(如fn.constructor !== Function可能表示被代理或沙箱封装) - 不要依赖它做安全决策,仅用于异常提示或调试辅助

















