目录
什么是数值常量混淆
100 就是我们常说的数值,那么是什么 常量 ,即在代码中不会改变的值即为常量,常量也不允许被修改,为了更直观的看下什么是常量,如下代码
function add(a, b) {
const c = 100; // 即为常量
// c = 200; 此语句执行会报错,因此常量不允许修改
return a + b + c;
}
console.log(add(10, 20));
输出结果: 130
混淆前后对比
混淆前
function add(a, b) {
const c = 100; // 即为常量
// c = 200; 此语句执行会报错,因此常量不允许修改
return a + b + c;
}
console.log(add(10, 20));
输出结果: 130
混淆后,发现代码中的数字常数已经被 800141 ^ 800233 这样的代码给替换了,对于位于算不太熟悉的小伙伴看起来比较懵,这样的代码看起来相比上面的代码多了一点复杂度。
function add(a, b) {
const c = 800141 ^ 800233; // 即为常量
// c = 200; 此语句执行会报错,因此常量不允许修改
return a + b + c;
}
console.log(add(220865 ^ 220875, 708957 ^ 708937));
直接执行混淆后的代码,输出结果依然是 130。
混淆思路
上方混淆的方法其实就是使用了 异或 ,那么什么是 异或 ,大家可自行百度学习,本文不过多介绍。
拿这句代码来说明 const c = 100; ,我们随机生成一个比较大的数字,例如上面混淆后代码中的 800141 ,那么拿 100 与 800141 进行异或运算就自然得到了 800233 。
一句话: 100 = 800141 ^ 800233 。
拿上面的例子来说,随机生成了 800141 ,然后与 100 进行异或得到 800233 ,那么 800141 与 800233 异或的值必然是 100
思路如下:
- 遍历所有
NumericLiteral节点 - 取出当前节点的值
value - 使用
Math.random()得到随机数A - 使
value与A进行异或得到B - 然后生成
binaryExpression节点来替换当前节点,binaryExpression需要 3 个参数,第一个为^操作符,第二个为A,第三个为B。
混淆代码
function fix(path) {
const node = path.node;
let value = node.value;
let key = parseInt(Math.random() * (999999 - 100000) + 100000, 10);
let cipherNum = value ^ key;
path.replaceWith(types.binaryExpression(
'^',
types.numericLiteral(cipherNum),
types.numericLiteral(key)
));
// 替换后的节点里面也是 NumericLiteral 节点,会造成死循环,因此这里需要加入 path.skip()
path.skip();
}
完整代码
关注公众号【 趣码周 】回复 AST 即可获得。
关注我们
微信公众号:【 趣码周 】
关注公众快速了解最新文章。
版权声明:本文为baoshuowl原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。