目录
什么是数值常量混淆
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
即可获得。
关注我们
微信公众号:【趣码周
】
关注公众快速了解最新文章。