特别说明:本文 生成节点时,函数的使用对于 Js 来说是错误的(不能指定参数给值),这样写是方便 看节点属性
使用例子
Date.prototype.format = function (formatSTr) { var str = formatSTr; str = str.replace(/yyyy|YYYY/, this.getFullYear()) str = str.replace(/MM/, (this.getMonth() + 1) > 9 ? (this.getMonth() + 1).toString() : '0' + (this.getMonth() + 1)); str = str.replace(/dd|DD/, this.getDate() > 9 ? this.getDate().toString() : '0' + this.getDate()) return str } console.log(new Date().format('yyyy-MM-dd'))
实现数值常量的加密
NumberLiteral节点:
value
-> BinaryExpression节点:cipherNum ^ key
代码中的 数值常量 可以遍历 NumberLiteral
,获取其中的 value
属性得到,然后随机生成
一个 Key
,把 Key 和 Value 进行异或
,得到 加密后的 cipherNum
,即 cipherNum = value ^ key
,这样就可以用 BinaryExpression
节点 等价的替换 NumberLiteral
节点
/* 加密数值常量:1 --> 343333 ^ 343332 cipherNum = value ^ key value = cipherNum ^ key */ traverse(ast, { NumericLiteral(path) { let value = path.node.value; let key = parseInt(Math.random() * (999999 - 100000), 10) let cipherNum = value ^ key; path.replaceWith( type.binaryExpression( '^', left = type.numericLiteral(value = cipherNum), right = type.numericLiteral(value = key))) // 替换节点里 也有 NumericLiteral 节点,会造成死循环,因此需要加入 path.skip() path.skip() } })
实现字符串常量的加密
字符串常量的加密,是使用一个
加密函数
,对字符串进行加密,在使用时
,又解密
成原始字符串
先遍历 StringLiteral
节点,获取 value
属性,然后对 value
进行加密
,把 StringLiteral
节点 替换
成 CallExpression
节点(调用表达式)
例子
这里的例子,需要改变一下,把
调用方法
使用之前的文章,改成字符串调用
的方式
window["Date"]["prototype"]["format"] = function (formatSTr) { var str = formatSTr; str = str["replace"](/yyyy|YYYY/, this["getFullYear"]()); str = str["replace"](/MM/, this["getMonth"]() + 1 > 9 ? (this["getMonth"]() + 1)["toString"]() : '0' + (this["getMonth"]() + 1)); str = str["replace"](/dd|DD/, this["getDate"]() > 9 ? this["getDate"]()["toString"]() : '0' + this["getDate"]()); return str; }; window["console"]["log"](new window["Date"]()["format"]('yyyy-MM-dd'));
加密
对 字符串进行
base64
编码,然后浏览器
在运行时
,调用atob
再解码
encFun = (str) => { return Buffer.from(str, 'utf-8').toString('base64'); } traverse(ast, { StringLiteral(path) { let str = path.node.value; let encStr = encFun(path.node.value); path.replaceWith( type.callExpression( callee = type.identifier(value = 'atob'), // atob() 不支持中文解码 _arguments = [ type.stringLiteral(value = encStr) ]) ) // 替换节点里 也有 stringLiteral 节点,会造成死循环,因此需要加入 path.skip() path.skip(); } })
版权声明:《 【AST 混淆】一、常量 & 标识符的混淆 》为明妃原创文章,转载请注明出处!
最后编辑:2022-4-10 13:04:07