变量名 / 字符串混淆与还原
本节目标
- 理解「变量名混淆」和「字符串混淆」分别怎么坑你
- 会用浏览器「美化格式化」+ 搜索还原变量名
- 理解「字符串数组 + 下标取用」这种常见字符串混淆
变量名混淆:把 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' 再读实战手法:
- DevTools Sources 里点
{}「Pretty Print」美化压缩代码,结构立刻清楚。 - 对字符串数组,下「条件断点」在「访问数组时打印下标和值」,快速建立「下标→真实字符串」映射表。
- 用之前的 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 课程的价值落地)。记住:混淆改变的是「呈现」,改变不了「逻辑」,你只要把呈现还原,逻辑就现形。