[AST混淆篇01]数值常量的混淆

目录

什么是数值常量混淆

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,那么拿 100800141 进行异或运算就自然得到了 800233

一句话:100 = 800141 ^ 800233

拿上面的例子来说,随机生成了 800141,然后与 100 进行异或得到 800233,那么 800141800233 异或的值必然是 100

思路如下:

  1. 遍历所有 NumericLiteral 节点
  2. 取出当前节点的值 value
  3. 使用 Math.random() 得到随机数 A
  4. 使 valueA 进行异或得到 B
  5. 然后生成 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 即可获得。

关注我们

微信公众号:【趣码周

关注公众快速了解最新文章。

猜你喜欢

转载自blog.csdn.net/baoshuowl/article/details/125659963