• AST反混淆插件|如何删除多余的window标识


    关注它,不迷路。       

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

    1. 需求分析

    在阿卡迈2.0还原后的混淆代码中,可以看到类似的代码:

    1. for (mU = ",",
    2. CU = true,
    3. LU = 0; LU < window["Math"]["floor"](3 * window["Math"]["random"]()) + 3; ++LU) {
    4. for (lU = 0; lU < window["Math"]["floor"](3 * window["Math"]["random"]()) + 3; ++lU)
    5. mU += VU[window["Math"]["floor"](window["Math"]["random"]() * VU["length"])];
    6. mU += ",";
    7. }

    代码中有 很多的 window 标识,它是可以进一步进行处理的:

    1. for (mU = ",", CU = true, LU = 0; LU < Math["floor"](3 * Math["random"]()) + 3; ++LU) {
    2. for (lU = 0; lU < Math["floor"](3 * Math["random"]()) + 3; ++lU) mU += VU[Math["floor"](Math["random"]() * VU["length"])];
    3. mU += ",";
    4. }

    因为window它是浏览器的一个全局对象,而一些另外的全局对象,默认是绑定window,因此,去掉不会影响它的运行逻辑和结果。

    2. 混淆代码

    还原前:

    1. for (mU = ",",
    2. CU = true,
    3. LU = 0; LU < window["Math"]["floor"](3 * window["Math"]["random"]()) + 3; ++LU) {
    4. for (lU = 0; lU < window["Math"]["floor"](3 * window["Math"]["random"]()) + 3; ++lU)
    5. mU += VU[window["Math"]["floor"](window["Math"]["random"]() * VU["length"])];
    6. mU += ",";
    7. }

    还原后:

    1. for (mU = ",", CU = true, LU = 0; LU < Math["floor"](3 * Math["random"]()) + 3; ++LU) {
    2. for (lU = 0; lU < Math["floor"](3 * Math["random"]()) + 3; ++lU) mU += VU[Math["floor"](Math["random"]() * VU["length"])];
    3. mU += ",";
    4. }

    3. 思路

    • 提前将 MemberExpression 类型统一成 a[b] 格式,方便处理;

    • 直接遍历 MemberExpression 表达式,判断其object是否为 Identifier 类型,并且其值必须是 "window";

    • 利用浏览器上的window对象,判断 typeof window[property.value] 的结果;

    • 如果上述判断不是 undefined,说明它是 浏览器上的全局对象,直接替换即可。

    4. 插件源码

    1. const MemberExpressionToIdentifier = {
    2. MemberExpression(path) {
    3. let {object, property} = path.node;
    4. if (!types.isIdentifier(object, {
    5. name: "window"
    6. }) || !types.isStringLiteral(property) || typeof window[property.value] == 'undefined') {
    7. return;
    8.         }
    9. let IdentifierNode = types.Identifier(property.value);
    10.         path.replaceWith(IdentifierNode);
    11. }
    12. }

    注意,该插件需要在浏览器上运行。运行方法请参考这篇文章:

    AST实战|如何用浏览器执行你写的AST插件?

    今天的文章就分享到这里,后续分享更多的技巧,敬请期待。

    265004a6cda84b30e0fe6f3c8277e4bd.jpeg

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

  • 相关阅读:
    计算机网络常识通览
    基于QT实现的图书室管理系统
    元年洞察|如何打造企业数据能力组件中心
    基于Jeecgboot前后端分离的ERP系统开发代码生成(二)
    【k8s】(二)kubernetes1.29.4离线部署之-镜像文件准备
    性能测试场景用例【模板】
    基于springboot+vue的社区健康码管理系统(前后端分离)
    java IO流【常用流对象二】
    关于Flask_运行导入Flask的py文件的两种方式
    PostMan接口测试(很全面的接口测试教程)
  • 原文地址:https://blog.csdn.net/qq523176585/article/details/127644517