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

一句话: 100 = 800141 ^ 800233

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

思路如下:

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

关注我们

微信公众号:【 趣码周

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


版权声明:本文为baoshuowl原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。