JavaScript反混淆插件八:还原简单的CallExpression 类型

今天来学习下怎么将简单的CallExpression 类型进行处理。

昨天写了这篇文章 JavaScript 代码混淆实战(二):将 BinaryExpression 类型转换为 CallExpression 类型,今天来看看它的逆过程。

如何将下面的代码:

var Xor = function (p,q)
{
  return p ^ q;
}


let a = Xor(111,222);

转变成下面的:

var Xor = function (p,q)
{
  return p ^ q;
}


let a = 111 ^ 222;

01

分析及思路

分析:上面的转变其实就是将  Xor(111,222) 变成 111 ^ 222

  1. Xor 函数以 var 的方式定义,因此这里最好遍历 VariableDeclarator 类型,可以同时获取函数名和函数体。

  2. 这个函数体很简单,只有一个 return 语句。

  3. 功能只是对两个参数进行异或运算。

思路:

  1. 遍历 VariableDeclarator 路径,对参数、函数体之间的关系进行判断。

  2. 遍历 函数 所在的作用域,函数名相同替换即可。

02


实战

一.插件编写,遍历 VariableDeclarator, 判断其 init 节点:

JavaScript反混淆插件八:还原简单的CallExpression 类型_第1张图片

二.功能编写:

function call2express(path)
{
}
  1. 函数名获取:

    const {init,id} = path.node;
    const name = id.name;
    
  2. 获取参数,并判断长度:

    const params = init.params;
    if (params.length !== 2) return;
    let first_arg  = params[0].name;
    let second_arg = params[1].name; 
    
  3. 判断函数体长度是否为1:

    const body = init.body;
    if (!body.body || body.body.length !== 1) return;
    
  4. 判断 ReturnStatement 及其 参数类型

    const t  = require("@babel/types");
    let return_body = body.body[0];
    let argument = return_body.argument;
    if (!t.isReturnStatement(return_body) ||
        !t.isBinaryExpression(argument))
       {
          return;
       }
    
  5. 判断函数的参数与 return语句的参数是否一致:

    let {left,right,operator} = argument;
    if (!t.isIdentifier(left, {name:first_arg}) ||
        !t.isIdentifier(right,{name:second_arg}))
       {
            return;
       }
    
  6. 函数声明所在的作用域:

    let scope = path.scope;
    
  7. 遍历作用域块节点,找出所有 CallExpression 判断成功后替换:

    traverse(scope.block,{
            CallExpression:function(_path) {
            let _node = _path.node;
            let args = _path.node.arguments;
            if (args.length === 2 && t.isIdentifier(_node.callee,{name:name}))
            {
                _path.replaceWith(t.BinaryExpression(operator, args[0], args[1]))
            }
        },
      }) 
    

完整代码:

JavaScript反混淆插件八:还原简单的CallExpression 类型_第2张图片

本文旨在告诉小白如何去编写简单的插件,在分析的过程中可以对照在线解析网站,总之,熟能生巧吧。

你可能感兴趣的:(javascript,js,python,java,编程语言)