JS代码安全之路:用JS对JS代码混淆加密( 三 )


文章插图
 
例程代码输出为:
图15:

JS代码安全之路:用JS对JS代码混淆加密

文章插图
 
运行混淆后的代码:
图16:
JS代码安全之路:用JS对JS代码混淆加密

文章插图
 
从简单的例程,可以初步学习到对AST的操作方法 。
接下来,实现一个有点难度的功能 。
成员表达式转为IIFE成员表达式通常指调用对象的成员,例如 console 对象的 log 成员 。
IIFE,全称为:Immediately Invoked Function Expression,在JAVAScript编程中,是指:立即调用函数表达式 。
为了方便理解,先展示此功能实现后的效果:
图17:
JS代码安全之路:用JS对JS代码混淆加密

文章插图
 
如上图中,console的log、warn、error方法,以及字符串的toUperCase()方法,在保护后都会成为匿名自执行的函数,且方法名都以数组化的形式被另外存放,代码相比之前混乱了许多 。
图18、IIFE代码执行效果:
JS代码安全之路:用JS对JS代码混淆加密

文章插图
 
实现方法如下:
主架构与之前略有差异,traverse方法改为replace,enter事件改为leave事件,如下图:
图19:
JS代码安全之路:用JS对JS代码混淆加密

文章插图
 
对变量定义结点,如console.log输出的信息,以及成员函数,如console的log方法进行操作 。
图20、改写字符串定义、成员函数调用:
JS代码安全之路:用JS对JS代码混淆加密

文章插图
 
Add_string函数把字符串信息、方法名,都写入到一个新的字符串数组,并且把方法改为IIFE 。
字符串数组建立、方法改为IIFE的具体实现如下图:
图21:
JS代码安全之路:用JS对JS代码混淆加密

文章插图
 
然后,把新增的数组加入到AST中,最重再重建代码:
图22:
JS代码安全之路:用JS对JS代码混淆加密

文章插图
 
这样就完成了本例功能 。
注:本例仅供功能演示,尚有不严谨的逻辑,比如成员方法IIFE化之前,除应该判断node.type为MemberExpression,还应排除节点computed为true的情况,否则代码执行会发生错误 。
正如前文中所述,能对AST进行操作的模块不止esprima,babel也是个很好的选择 。
接下来的例子,将使用babel来完成 。
Babel的使用方式与esprima极为相似,其代码框架如下:
图23:
JS代码安全之路:用JS对JS代码混淆加密

文章插图
 
同样是:JS代码→AST→节点处理→JS代码 。
用Babel修改AST实例:去除代码中的console.log输出语句 。代码如下图所示:
图24、用Babel在AST中去除console.log节点:
JS代码安全之路:用JS对JS代码混淆加密

文章插图
 
匹配AST中的成员操作节点,且满足条件callee的对像名为console,属性方法名为log,如检测掉,则remove该节点 。
运行效果如下图所示,测试代码中含有console.log,修改后输出中已经被去除 。
图25:
JS代码安全之路:用JS对JS代码混淆加密

文章插图
 
严谨的考虑的话,需要注意对象挂载的识别,如global.console.log,此时remove则会剩下global,将导致语法错误,因此还应该判断父节点类型来排除这种情况 。
指定局部变量变形图26、对min、number两个局部变量变形:
JS代码安全之路:用JS对JS代码混淆加密

文章插图
 
相当于是可设定、可配置的对某些变量进行变形 。
反向思考,也可以排除对某些变量的处理,等同于白名单,类似于JShaman平台中的“保留字”功能 。
删除代码中的空行 。图27:
JS代码安全之路:用JS对JS代码混淆加密

文章插图
 
EmptyStatement表示空语句AST节点 。
字符串转Unicode 。图28:
JS代码安全之路:用JS对JS代码混淆加密

文章插图
 
代码及执行结果如上图,原理为:判断节字符串字面量节点是否为Unicode格式,如不是则转为Unicode 。
在这几个例子中,可看到与esprima的差异,esprima使用的是enter、leave方法,Babel中是直接对要处理的节点类型操作,如上图中的StringLiteral 。
更条理化的写法,上面的代码可以修改如下,这个方法被称为Babel-plugin(插件):


推荐阅读