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

相关推荐
重生之我是Java开发战士1 小时前
【优选算法】模拟算法:替换所有的问号,提莫攻击,N字形变换,外观数列,数青蛙
算法
黄诂多1 小时前
APP原生与H5互调Bridge技术原理及基础使用
前端
前端市界1 小时前
用 React 手搓一个 3D 翻页书籍组件,呼吸海浪式翻页,交互体验带感!
前端·架构·github
仟濹1 小时前
算法打卡 day1 (2026-02-06 周四) | 算法: DFS | 1_卡码网98 可达路径 | 2_力扣797_所有可能的路径
算法·leetcode·深度优先
文艺理科生1 小时前
Nginx 路径映射深度解析:从本地开发到生产交付的底层哲学
前端·后端·架构
yang)1 小时前
欠采样时的相位倒置问题
算法
千寻girling1 小时前
主管:”人家 Node 框架都用 Nest.js 了 , 你怎么还在用 Express ?“
前端·后端·面试
南极企鹅1 小时前
springBoot项目有几个端口
java·spring boot·后端
历程里程碑1 小时前
Linux20 : IO
linux·c语言·开发语言·数据结构·c++·算法
A尘埃1 小时前
物流公司配送路径动态优化(Q-Learning算法)
算法