【AST 混淆】三、实现表示符混淆

特别说明:本文 生成节点时,函数的使用对于 Js 来说是错误的(不能指定参数给值),这样写是方便 看节点属性

思路

标识符一般都是有语义的,把标识符 无语义化,那么分析难度就会再次增加

使用 scope.getOwnBinding() 例如:在 Program 节点下,可以获取全局的标识符,而函数内部的标识符名获取不到,要获取局部的的标识符,可以遍历局部节点()的标识符,这样就获取的是 函数局部的标识符。

标识符混淆

 let renameOwnBinding = function (path) {
        let ownBindingObj = {},  // 存放 binding 对象,重名时 需要
            globalBindingObj = {}, //
            i = 0; // 先获取 标识符 作用域
        path.traverse({
            Identifier(p) {
                let name = p.node.name;
                let binding = p.scope.getOwnBinding(name) // 当前标识符 当前节点的绑定
                binding ? (ownBindingObj[name] = binding) : (globalBindingObj[name] = 1)
            }
        })
        for (let oldName in ownBindingObj) {
            do {
                var newName = '_0xsdc2d' + i++;
            } while (globalBindingObj[newName]); // 防止 与全局标识符 混淆变量名 重复
            ownBindingObj[oldName].scope.rename(oldName, newName);
        }
    }
    traverse(ast, {
        'Program|FunctionExpression|FunctionDeclaration'(path){ // 酌情增加节点
            renameOwnBinding(path);
        }
    })

mark

在进行以再次加密一遍

mark

标识符随机生成

上面的标识符混淆,还是能看着不是太混乱,我们在继续混乱一点

 let generatorIdentifier = function (decNum) {
        let flag = ['O', 'o', '0']
        let retval = []
        while (decNum > 0) {
            retval.push(decNum & 3)
            decNum = parseInt(decNum / 3)
        }
        let Identifier = retval.reverse().map(function (v) {
            return flag[v]
        }).join('')
        Identifier.length < 6 ? (Identifier = ('OOOOOO' + Identifier).substr(-6)) :
            Identifier[0] == '0' && (Identifier = 'O' + Identifier)
        return Identifier
    }

// 修改上面的生成标识符的地方
// var newName = '_0xsdc2d' + i++;
var newName = generatorIdentifier(i++);

mark

发表评论 / Comment

用心评论~