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和爬虫技巧。

相关推荐
期待のcode3 分钟前
Java Object 类
java·开发语言
如旧呀4 分钟前
爬虫小知识
数据库·爬虫·mysql
培根芝士5 分钟前
解决DBeaver对PostgresSQL备份数据库时报错
数据库
weixin_461769406 分钟前
3. 无重复字符的最长子串
c++·算法·滑动窗口·最长字串
Morwit8 分钟前
【力扣hot100】 312. 戳气球(区间dp)
c++·算法·leetcode
悟能不能悟9 分钟前
如何处理 丢失更新(不可重复读)
java
李拾叁的摸鱼日常15 分钟前
Java Optional 最佳实践+注意事项+避坑指南
java·后端·面试
CoovallyAIHub17 分钟前
摄像头如何“看懂”你的手势?手势识别实现新人机交互
深度学习·算法·计算机视觉
Hello World呀19 分钟前
登录时,redis出现错误
数据库·redis·缓存
雨中飘荡的记忆21 分钟前
MyBatis配置解析模块详解
java·mybatis