李恒道 发表于 2022-10-19 22:53:08

JS混淆分析初步理论研究篇四

# 开始
我们基于上节课的去花指令的字符串的代码继续清理
这节主要去处理花指令的函数
代码如下
```
let a = 0x1;
alert(a);

(function (_0xc2361a, _0x49f6b2, _0x4c5d49) {
var _0x4bbdd6 = {
    PTyWI: "ert",
    CFOau: function _0x2e9886(_0x27d2c4, _0x233ed3) {
      return _0x27d2c4 !== _0x233ed3;
    },
    yGZoO: "undefined",
    UQhqT: function _0xe650a3(_0x4590a1, _0x160226) {
      return _0x4590a1 === _0x160226;
    },
    TtTMq: "jsjiami.com.v5",
    FQggo: function _0x47c22c(_0x2fe61e, _0x50381a) {
      return _0x2fe61e + _0x50381a;
    },
    FTCAn: "删除版本号,js会定期弹窗",
};
_0x4c5d49 = "al";

try {
    _0x4c5d49 += "ert";
    _0x49f6b2 = encode_version;

    if (
      !(
      _0x4bbdd6["CFOau"](typeof _0x49f6b2, "undefined") &&
      _0x4bbdd6["UQhqT"](_0x49f6b2, "jsjiami.com.v5")
      )
    ) {
      _0xc2361a(
      _0x4bbdd6["FQggo"]("删除", "版本号,js会定期弹窗,还请支持我们的工作")
      );
    }
} catch (_0x2d647c) {
    _0xc2361a("删除版本号,js会定期弹窗");
}
})(window);

encode_version = "jsjiami.com.v5";

```
首先理一下思路
这里是一个Call调用,也就是函数调用
左边是对象+属性
右边则是传入的参数
我们根据对象找到对应的bingding,然后根据属性找到对应的函数
![图片.png](data/attachment/forum/202210/19/224717tj0gnd0qmmxouo5d.png)
判断函数内是否只有一行代码,也就是花指令的代码
如果只有一行,那就取出该行两个变量的操作符,替换到函数调用的位置
![图片.png](data/attachment/forum/202210/19/224805jd3dx333adp3dqde.png)
观察一下,这里是一个BinaryExpression对象
也就是说我们到时候要传入BinaryExpression对象
![图片.png](data/attachment/forum/202210/19/224849s0jqrc1br1j20v2j.png)
因为我们找的MemberExpression应该是一个调用的,根据Ast查看知道
应该父级是一个CallExpression
![图片.png](data/attachment/forum/202210/19/225129odkyrod0k3rd6krr.png)
直接基于上节课的代码继续写
因为我们直接已经解释过了
所以这节课直接出成品
```javascript
traverse(ast, {
MemberExpression(path) {
    let obj_name = path.node.object.name;
    let obj_value =
      path.node.property.type === "StringLiteral"
      ? path.node.property.value
      : undefined;
    let parent_path = path.parentPath;
    let is_call = parent_path.node.type === "CallExpression";
    //判断找到的对象.属性父级是否是一个调用函数
    if (obj_name && obj_value && is_call) {
      let obj_binding = path.scope.getBinding(obj_name);
      //判断是否找到bingding
      if (obj_binding) {
      let prop_list = obj_binding.path.node.init.properties;
      for (let index = 0; index < prop_list.length; index++) {
          let item_prop = prop_list;
          let prop_name = item_prop?.key?.name;
          if (prop_name === obj_value) {
          //判断是否是一个函数
            if (item_prop.value.type === "FunctionExpression") {
            let body = item_prop.value.body.body;
            //判断是否只有一行代码
            if (body.length === 1) {
                let binary = body.argument;
               //判断是否是BinaryExpression类型
                if (binary.type === "BinaryExpression") {
                  let opear = binary.operator;
                  //取函数.属性(参数)中的参数,并判断是否为2
                  let arg = parent_path.node.arguments;
                  if (arg.length === 2) {
                  let first = arg;
                  let second = arg;
                  //生成一个binaryExpression对象并替换
                  let insert_node = types.binaryExpression(
                      opear,
                      first,
                      second
                  );
                  parent_path.replaceInline(insert_node)
                  }
                }
            }
            return;
            }
          }
      }
      }
    }
},
});
```
我们查看一下结果
可以看到最后已经完美去掉了花指令的函数了
![图片.png](data/attachment/forum/202210/19/225251ijtq47ziu284gqsy.png)
# 结语
撒花~
页: [1]
查看完整版本: JS混淆分析初步理论研究篇四