特别说明:本文 生成节点时,函数的使用对于 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); } })
在进行以再次加密一遍
标识符随机生成
上面的标识符混淆,还是能看着不是太混乱,我们在继续混乱一点
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++);
版权声明:《 【AST 混淆】三、实现表示符混淆 》为明非原创文章,转载请注明出处!
最后编辑:2022-4-13 10:04:43