变量名 / 字符串混淆与还原

本节目标

变量名混淆:把 encrypt 改成 _0x1a2b。还原靠「格式化 + 重命名」或「直接搜函数体的特征代码」。

字符串混淆:把 "password" 藏进一个数组,代码里只写 _0xArr[12],你看到的是数字不是明文。

// 运行环境:Node.js 16+(无需依赖)
// 运行:node jsr-l11.cjs
// 模拟「字符串数组混淆」:真实字符串被挪到数组,代码用下标取
const _0xStr = ['password', 'encrypt', 'hello']
function check(input) {
  // 代码里看到的是 _0xStr[0],不是 'password'——这就是混淆
  return input === _0xStr[0] ? _0xStr[1] : _0xStr[2]
}
console.log(check('password')) // 'encrypt'

// 还原思路:在 DevTools 里给 _0xStr 下「数组取值」断点,
// 或写脚本把 `check('password')` 里出现的 _0xStr[0] 替换回 'password' 再读

实战手法:

  1. DevTools Sources 里点 {}「Pretty Print」美化压缩代码,结构立刻清楚。
  2. 对字符串数组,下「条件断点」在「访问数组时打印下标和值」,快速建立「下标→真实字符串」映射表。
  3. 用之前的 AST 知识(见 ast-pro 课程)写脚本批量替换下标为明文。

名词解释

变量名混淆(Identifier Obfuscation):把有意义的名字(user、encrypt)换成无意义短名(_0x1a2b、a)。它不防「读逻辑」,只增加「阅读难度」。还原手段是「格式化 + 按函数重命名」或「直接读函数体行为」,名字丑不影响你理解它在算什么。

字符串混淆(String Obfuscation):把写在代码里的明文(如 'password'、'AES_KEY')抽到一个数组,代码改用「数组下标」引用。它让你搜关键字时搜不到——因为字面量不在原地了。还原方法是「建立下标→明文的映射表」,或下数组访问断点把值打印出来。

课后练习

练习 1:为什么「字符串数组混淆」会让「全局搜索 password 关键字」失效?

答案:因为 'password' 字面量被挪到了数组定义处,算法代码里只剩 _0xArr[0] 这样的下标。你搜 password 只能搜到数组那一行,搜不到「使用它的算法」——必须先把下标映射回明文,或断点观察数组访问。

练习 2:美化格式化(Pretty Print)能解决变量名混淆吗?

答案:不能解决「名字无意义」的问题,但能解决「压缩成一行的可读性」问题——它把一行几万字符的代码按结构换行缩进,让花括号层级清晰,配合人工重命名才能读懂。它是第一步,不是全部。

总结

混淆的存在不是为了「防住高手」,而是为了「拖慢你」。我的观点很明确:变量名混淆基本是纸老虎——名字再丑,函数体在那、调用关系在那、算法逻辑也还在,格式化后读懂只是时间问题。真正有点烦的是字符串混淆,因为它让你「搜不到关键字」,断了你最快的定位路径。应对字符串混淆,我有两个真招:一是下数组访问断点,运行时把「下标→真实值」打出来建表;二是直接用 AST 脚本批量替换(这正是前面 ast-pro 课程的价值落地)。记住:混淆改变的是「呈现」,改变不了「逻辑」,你只要把呈现还原,逻辑就现形。