AST入门与实战(二):删除垃圾代码

原文地址:https://zhuoyue360.com/jsnx/109.html

AST入门与实战(一):基于babel库的js反混淆模板的实践 : https://www.zhuoyue360.com/jsnx/106.html

还记的上一篇AST的文章,我们把函数调用简单的给替换了一下,但是其最终的效果并不完美.

哪里不完美呢? 有如下几点:

  1. 开头的匿名函数 ,_0x4f09 ,_0x49be 函数已经没用,我们应该删除它 (我认为手动删除就好了)
  2. 在代码中,存在不少的无效代码,例如var _0x49beab = _0x49be(); 我也也应该删除它.
(function (_0x42555b, _0x288c31) {
  var _0x2e2c7a = _0x4f09,
    _0x264ee4 = _0x42555b();
  while (!![]) {
    try {
      var _0x54167b = parseInt(_0x2e2c7a(262)) / 1 * (-parseInt(_0x2e2c7a(266)) / 2) + -parseInt(_0x2e2c7a(265)) / 3 * (parseInt(_0x2e2c7a(267)) / 4) + -parseInt(_0x2e2c7a(270)) / 5 * (parseInt(_0x2e2c7a(273)) / 6) + -parseInt(_0x2e2c7a(272)) / 7 + parseInt(_0x2e2c7a(268)) / 8 + parseInt(_0x2e2c7a(269)) / 9 * (parseInt(_0x2e2c7a(271)) / 10) + parseInt(_0x2e2c7a(264)) / 11;
      if (_0x54167b === _0x288c31) break;else _0x264ee4['push'](_0x264ee4['shift']());
    } catch (_0x1b893f) {
      _0x264ee4['push'](_0x264ee4['shift']());
    }
  }
})(_0x49be, 769884);
function hi() {
  console['log']('Hello,zhuoyue360.com');
}
function _0x4f09(_0xd05c9f, _0x352733) {
  var _0x49beab = _0x49be();
  return _0x4f09 = function (_0x4f0967, _0x3191e8) {
    _0x4f0967 = _0x4f0967 - 261;
    var _0x4f9c38 = _0x49beab[_0x4f0967];
    return _0x4f9c38;
  }, _0x4f09(_0xd05c9f, _0x352733);
}
function _0x49be() {
  var _0x13bd5d = ['12032256MLzLfN', '1251zScKBQ', '25cNqVzl', '270jbEuTF', '5872188ZkfPRj', '1062282TyhTBn', 'Hello,zhuoyue360.com', '1kakbhL', 'log', '11816574EYEQFr', '66741ytXvQy', '42550jdDgVb', '12QEFacN'];
  _0x49be = function () {
    return _0x13bd5d;
  };
  return _0x49be();
}
function h3i() {
  var _0x2b1dcb = _0x4f09;
  console["log"]("Hello,zhuoyue360.com");
}
function h2i() {
  var _0xa95bed = _0x4f09;
  console["log"]("Hello,zhuoyue360.com");
}
function h44444i() {
  var _0xb505a4 = _0x4f09;
  console["log"]("Hello,zhuoyue360.com");
}
hi();

所以,我们理想状态下的代码应该是:

function hi() {
  console['log']('Hello,zhuoyue360.com');
}
function h3i() {
  var _0x2b1dcb = _0x4f09;
  console["log"]("Hello,zhuoyue360.com");
}
function h2i() {
  var _0xa95bed = _0x4f09;
  console["log"]("Hello,zhuoyue360.com");
}
function h44444i() {
  var _0xb505a4 = _0x4f09;
  console["log"]("Hello,zhuoyue360.com");
}
hi();

我们可以通过枚举VariableDeclarator 来实现.

AST入门与实战(二):删除垃圾代码_第1张图片

思路如下:

  1. 枚举VariableDeclarator
  2. 通过scope.getBinding来获取调用的次数
  3. 如果次数为0,删除它的父节点(也就是那一整行代码)VariableDeclaration

实现代码如下:

const deleteUnUseVar = {
    VariableDeclarator(path){
        let {node,scope} = path;
        // 我们拿到变量名称, 寻找其binding的次数. 如果binding的长度为0的话,证明没用过,删除即可.
        const {id,init} = node;
        console.log(id.name)
        const bindings = scope.getBinding(id.name);
        if (!bindings || bindings.constantViolations.length > 0){
            // 这个变量被用了.
            return;
        }
        // 这个变量没任何引用.
        path.parentPath.remove();

    }
}
traverse(ast, deleteUnUseVar);

最终的展示效果如下:

解密函数我手动删除了, 感觉好像没多大必要写自动的. 毕竟只是学习~


function hi() {
  console['log']('Hello,zhuoyue360.com');
}

function h3i() {
  console["log"]("Hello,zhuoyue360.com");
}
function h2i() {
  console["log"]("Hello,zhuoyue360.com");
}
function h44444i() {
  console["log"]("Hello,zhuoyue360.com");
}
hi();

你可能感兴趣的:(ast,反混淆,babel,逆向)