AST反混淆实战|reese84_jsvmp反编译前的优化处理

关注它,不迷路。

本文章中所有内容仅供学习交流,不可用于任何商业用途和非法用途,否则后果自负,如有侵权,请联系作者立即删除!

1.样本DEMO**:**

javascript 复制代码
var aaa = function (A) {    return function (B) {      return function (A) {        return Q[function (A) {          return function (A) {            return function (B) {              return function (A) {                return +function (A) {                  return !function (A) {                    return null;                  }();                }();              }() << A();            };          }(function (A) {            return !function (A) {              return null;            }();          })();        }()];      }()[A()];    };}

2.代码分析**:**

最显眼的莫过于 return null 了,因为它是一个字面量,并且代码也比较单一,比如这段代码里:

javascript 复制代码
return !function (A) {   return null;}();

这里的形式参数A,其实是没有用的。可以直接还原成 return !null

其实也就是

javascript 复制代码
!function (A) {return null;}();

===>

javascript 复制代码
!null;

这样的拆解,大家更容易理解。

根据特征写还原插件,优化后的代码如下:

javascript 复制代码
var aaa = function (A) {  return function (B) {    return Q[function (A) {      return function (A) {        return function (B) {          return function (A) {            return +function (A) {              return !null;            }();          }() << A();        };      }(function (A) {        return !null;      })();    }()][A()];  };};

这里,又看到了 !null ,又可以进行处理,即:

!null ===> true;

这个使用 常量折叠插件 就可以了。优化后的代码如下:

javascript 复制代码
var aaa = function (A) {  return function (B) {    return Q[function (A) {      return function (A) {        return function (B) {          return function (A) {            return +function (A) {              return true;            }();          }() << A();        };      }(function (A) {        return true;      })();    }()][A()];  };};

这里的 return true 这第一步是类似的,因此又回到了第一步的处理。加个循环处理就好,优化后的代码:

javascript 复制代码
var aaa = function (A) {  return function (B) {    return Q[function (A) {      return function (A) {        return function (B) {          return 1 << A();        };      }(function (A) {        return true;      })();    }()][A()];  };};

处理后,发现,仍然有地方没有被处理,如

javascript 复制代码
(function (A) { return true;})()

拿去在线网站上进行解析,发现它被解析成了FunctionExpression,并不是我们以为的CallExpression,而且,它仅仅只是作为实参,因此没有被之前的插件处理。

这时,我们从其他地方入手,发现了这个:

javascript 复制代码
function (A) {  return function (A) {    return function (B) {      return 1 << A();    };  }(function (A) {    return true;  })();}()

它其实可以直接出值,虽然是个callexpression,但是直接eval的话会报错,你可以给它赋给另外一个变量,如:

javascript 复制代码
var aaa = function (A) {  return function (A) {    return function (B) {      return 1 << A();    };  }(function (A) {    return true;  })();}()

这个时候就可以进行处理了,还原后的效果如下:

javascript 复制代码
var aaa = function (A) {  return function (B) {    return Q[2][A()];  };};

这就是还原后的最终形态了,当然,它只一个例子,并不包含所有情况,如:

javascript 复制代码
function (A) {    return function (B) {      return function (A) {        return function (B) {          return false + A();        };      }(function (A) {        return window;      })()[A()];    };  }

因为window不是字面量,并且在node下面是未定义的,因此是没办法直接得出值的。

这个时候,我们可以根据形参的引用用实参来替换形参,它的还原效果:

javascript 复制代码
function (A) {    return function (B) {      return function () {        return function (B) {          return false + window;        };      }()()[A()];    };  }

还能继续简化:

javascript 复制代码
function (A) {  return function (B) {    return (false + window)[A()];  };};

继续简化:

javascript 复制代码
function (A) {  return function (B) {    return ('false[object Window]')[A()];  };};

这应该就是它简化后的最终形态了。

今天的分享就到这里,感谢阅读。

欢迎加入知识星球,学习更多AST和爬虫技巧。

相关推荐
雨中飘荡的记忆1 小时前
Step Builder模式实战
java·设计模式
踩着两条虫1 小时前
开源一个架构,为什么能让VTJ.PRO在低代码赛道“炸裂”?
前端·低代码
爱看书的小沐1 小时前
【小沐学WebGIS】基于Cesium.JS绘制雷达波束/几何体/传感器Sensor(Cesium / vue / react )
javascript·vue.js·react.js·雷达·cesium·传感器·波束
踢球的打工仔1 小时前
前端css(2)
前端·css
悟空码字1 小时前
SpringBoot实现日志系统,Bug现形记
java·spring boot·后端
iナナ1 小时前
Java自定义协议的发布订阅式消息队列(二)
java·开发语言·jvm·学习·spring·消息队列
狂奔小菜鸡1 小时前
Day24 | Java泛型通配符与边界解析
java·后端·java ee
dragoooon341 小时前
[优选算法专题十一.字符串 ——NO.60~63 最长公共前缀、5最长回文子串、 二进制求和 、字符串相乘]
算法·leetcode·动态规划
半瓶榴莲奶^_^1 小时前
后端Web实战(登录认证)--会话技术,统一拦截技术
前端