JavaScript 反混淆的一般套路和技巧: 结

本来《JavaScript 反混淆的一般套路和技巧》是打算作为一篇单独的长文来写的, 后来硬生生被我拆成了《起》、《承》、《转》、《结》四章, 在《转》里面整个反混淆的事情其实已经被我们解决了, 结果就是这作为最后一篇的《结》, 变成了多余的一章. 这章该写些什么让我想了很久, 最后决定还是想到什么写什么.

下面是我在写这篇文章时暂时能够想到的一些反混淆中的注意事项.

避开陷阱和可能利用陷阱实现的混淆

由于JavaScript和ES在历史上遗留的问题很多, 运行环境复杂, 所以存在不少的陷阱. 一旦遇到可能是陷阱的代码, 请立即运行查看结果, 否则到最后发现出现了什么问题, 由于调试困难, 半天都找不到问题在哪, 会白白浪费很多时间.

比如在JavaScript中很不可靠, 在确定修改为=后执行效果不变的情况下, 建议将全部修改为=. 发现和解决陷阱的另一个好处是, 能帮助自己养成良好的JavaScript编码习惯.

事实上我印象中有一个绝大多数JavaScript程序员都会犯错的陷阱, 可惜一时半会想不起来了(也忘了记录), 不然拿出来当例子真是极好的.

混淆代码中混有浏览器兼容代码

这是反混淆中很容易遇到的情况, 个人的建议是直接删掉与你测试用的环境无关的兼容代码, 如有需要, 在反混淆的最后将兼容代码自己加回来. 不过, 在反混淆结束后把兼容代码加回来并非易事, 而且必定会造成可读性的下降.

建议直接删除的理由很简单, 因为有不少古老的浏览器兼容代码采用的是旁敲侧击式的判断方法, 在没有注释的情况下很难看出它究竟兼容的是哪种浏览器的哪个版本, 还有一些兼容代码写得就像巫师的巫术一样, 你很难分清这究竟是混淆代码还是兼容用的代码, 所以只保留你测试环境需要的代码即可(建议的测试环境是V8引擎和Webkit引擎, 也就是Chrome). 反混淆的过程中你应当只关注测试环境与代码的执行效果本身, 而不应该被兼容代码所拖累.

代码可读性太差的情况

在这种情况下你可以考虑用js2cofee这样的工具, 将原JavaScript代码转换为你所熟悉的其他语法干净的语言, 比如CoffeeScript(前提是你对这门语言足够熟悉, 知道它存在的语法陷阱, 而且转换后不会比原来可读性更差, 并且这门语言可以将代码转换为普通的JavaScript). 通常在去除了大量堪称糟粕的C类语言关键字和符号之后, 代码的可读性会大幅上升.

如果你把代码转换成了CoffeeScript, 那么在猜解变量名时会特别难受, 因为CoffeeScript的变量作用域和JavaScript使用的都是词法作用域, 而CoffeeScript里是无法像JavaScript一样用var关键字来声明一个变量的, 倘若代码里存在重复的变量名, 你需要小心翼翼的把不同作用域的变量名区别命名, 以免在编译后混用同一个作用域的变量.

各个步骤的代码保存

你可以使用版本控制系统来保存代码, 也可以手工复制代码文件来保存各个版本, 不过无论你用的是哪种方法, 我都建议你备一个文本比较工具或者带有比较功能的编辑器.