淘宝UA反混淆之常量替换(201605_64.js)

       淘宝新版 UA 文件代码反混淆分析(去数组下标)

       淘宝新版UA文件混淆函数清晰化处理(C#实现)

       C# 正则表达式实现对淘宝 UA 文件初步反混淆

       目前对淘宝UA反混淆还要进行常量替换。在esprima和C#之间徘徊了许久,最终我选择了用C#自行编写代码来实现常量替换。虽然用C#大致实现了这个功能,但是代码执行的效率,通用性,正确率应该是远不如esprima的。如果你也跟我一样正在徘徊,那我建议你使用etools。今天记录用C#实现淘宝UA反混淆步骤中的常量替换,给大家做一个反面教材吧。本文算法读取的js文件已完成去数组下标和函数反混淆。

       常量替换的基本思路

       首先我们要确定js文件中常量和它们的作用域,然后要找出常量表达式(可以被常量替换的表达式),根据常量表达式所在位置找到相应作用域的常量并进行替换。

       下面的代码以及描述中,我将一对{}当成一个作用域或者函数,尽管并不一定所有的{}都是函数,这里我们先做这样一个约定,以下的描述中的“作用域”指的是一组花括号包含的范围;而代码注释中的”函数“一般也是一组花括号包含的范围。

       根据以上基本思路,我定义类FunctionInfo来记录每一个作用域的信息,这些信息包含:

       a. 左( { )右( } )括号在整个js文件所组成的字符串中的序号;  

       b. 每一组{}的父级{}在作用域列表中的序号,父级仅记录一个;

       c. 每一组{}的子级{}在作用域列表中的序号列表,某些作用域中可能会有多个并列的子级{};

       d. 每一组{}的常量列表,该列表不包含其子集中的常量。该常量列表中的数据类型为ConstantInfo,包含常量名称及其相应的值。

       下面开始分步介绍C#实现常量替换的实现方法。

       寻找作用域列表

       用正则表达式找到所有的花括号{},根据花括号出现的顺序用stack进行配对查找,代码如下所示。当前代码是有缺陷的,并未考虑单只存在的左括号或右括号,幸运的是64.js中正好所有的花括号都是成对出现的。我觉得这个方案可以改善的方向是:js文件中用来表示函数范围的花括号一定是成对出现的,不成对出现的一般是js代码中出现的字符串中包含的单只左或右括号,所以应该改善正则表达式,让它能准确的匹配一个函数的开始和结束。这个问题留给有兴趣的同学继续。

      获取每组作用域的信息

       1. 寻找父作用域

       根据stack的作用规则,在作用域列表最后面的,一定是顶级父作用域;在列表最前面的,那就是最顶级子作用域。根据此原则,寻找父作用域时,从作用域列表的第一个序号开始遍历每一个作用域左右括号所在的序号,找到的第一个能将当前作用域包含的作用域作为其父作用域,当前作用域查找父作用域动作结束,开始查找下一个作用域的查找。

        2. 寻找子作用域

        在每一个作用域的父作用域确定后,子作用域即信手拈来。从作用域列表的最后一个序号开始遍历每一个作用域的父作用域在作用域列表中的序号,父作用域序号与当前查询序号相等的都是当前查询序号的子作用域。

        3. 获取当前作用域的常量列表

        从作用域列表的第一个序号开始遍历每一个作用域,为了不将其子作用域的常量囊括进来,首先将当前作用域的子作用域的字符串用空字符串替换,替换完成后,根据格式化之后的常量定义的规律来查找常量定义,并按照名值对存入列表中。

        由notepad++格式化之后的js文件中常量定义时有下图所示特征,每一个常量定义单独成行;但for循环中的常量定义并不会独立成行,按照此规则写的正则表达式无法匹配for循环中的常量定义,当然还有可能有其他我没有发现的无法匹配的类别。

constant in ua.js

        获取作用域信息的代码如下:

       找到常量表达式并替换

       当前代码中认为如下图所示类似的形式为常量表达式,代码中的正则表达式也会忽略另外一部分常量表达式。

constant expression in ua.js

       将常量表达式用” + “进行分割,得到变量后,对变量进行逐一替换。替换时,在常量列表中倒序查找,这里认为离常量表达式最近的常量是有效的(常量定义中会出现同一个作用域内相同变量被多次复制),当前作用域内找不到的,到其父作用域进行查找,以此类推,实现代码如下:

      当前常量替换方法的缺陷

       本文中C#实现的淘宝UA反混淆的方法的缺陷: 每一次淘宝UA更新都需要去人工查找函数作用域,常量定义,常量表达式的特征,若观察不仔细或正则表达式写的不够全面,则很可能出现过匹配或者漏匹配。所以要实现js文件的反混淆,还是要首选node和etools系列工具,一劳永逸。


       


发表评论

电子邮件地址不会被公开。 必填项已用*标注

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Fork me on GitHub