Всем привет, я хочу рассказать вам о возможностях трансформации AST в контексте JS. Зачем это нужно? В основном, чтобы избавиться от рутины по трансформации кода.Помимо этого, такие манипуляции позволяют минимизировать количество допускаемых ошибок во время ручно манипуляции, а так же имеют свои преимущества по сравнению с регулярными выражениями. Это будет цикл статей, которые направлены на то, чтобы заинтересовать вас и показать что-то новое. Многие сайты обфусцируют свои файлы для того, чтобы вам было сложнее в них разобраться и понять как они работают. Обфускация так же проходит при помощи AST трансформации кода - открыв любой open source обфускатор вы можете в этом легко убедиться. Чем тебе не угодил beautifier.io, de4js, jsnice и прочие? Дело в том что они не поддерживают многие виды обфускаций, как, например, те, что используются на https://obfuscator.io Таким образом, я собираюсь показать вам некоторые примеры деобфускации при помощи AST трансформаций, на примере своего кода, пропущенного через obfuscator.io; В общем клин клином выбивается)) Код в виде текста прикреплен в конце. В данной части будет продемонстрировано как из массива строк и функции, которая из него вытаскивает нужные строки, заменить вызовы функций на эквивалентные литералы. Код манипуляций будет простым, чтобы больше людей могли понять о чем речь. Бонусом я дам модуль для преобразования console['log'] в console.log. Code Бонусом я дам модуль для преобразования console['log'] в console.log. Мы будем делать из: делать такой код: Рассмотрев код, можно сделать вывод что функция, которая вытаскивает строки называется _0x3d28, массив строк под именем _0x4dfe, а за ним идет iife функция перемешивания. Разберем функцию _0x3d28 : На вход подается 2 аргумента, второй из которых нигде не используется. Затем второй аргумент(индекс) преобразуется в число путем вычитания 0x0 что является нулем. После этого объявляется и возвращается переменная, которая равна индексу из массива строк(объявлен первой строкой). Чистый вариант: Рассмотрим iife функцию: Она вызывается сразу после объявления с аргументами - массив строк и число на которое нужно сдвинуть массив. Суть данной функции в том, что она сдвигает начальные элементы массива в конец, пока число, на которое нужно сдвинуть массив, не будет равно 0. Push и shift мутируют массив, так что не важно что она возвращает. Ее чистый вариант будет выглядеть примерно так: И так инициализация массива происходит путем объявления переменной с массивом и аншафла строк. Данные из нее получаем путем выполнения функции, которая на вход получает индекс. Можно автоматизировать выдергивание числа для аншафла, и значение массива, но мы обойдемся без этого, так как этого бы усложнило наш код. Теперь напишем манипулятор. Я предлагаю использовать nodejs модули: meriyah для парсинга и преобразования кода в дерево, которая, astring для генерации текстового кода из AST, и astray для манипуляций с деревом. Установить их можно при помощи команды: npm i astray astring meriyah Перед этим прописав инициализацию(хороший тон): npm init Так же нам понадобится fs для чтения и записи файлов. Импортировать модули, а так же прочесть файл и сгенерировать для него дерево можно данным кодом: Готовый манипулятор будет выглядеть как то так: Многие траверсеры AST работают по паттерну visitor, поэтому каждый вызов функции(CallExpression) будет передаваться в нашу функцию. В самой функции мы проверяем вызов функции - что вызывается и с какими аргументами и если он удовлетворяем нашим хотелкам - возвращаем новую ноду в виде простой строки, вместо вызова функции. Мини пояснение: Чтобы это работало нужно определить getValue - это просто переименованная _0x3d28, для нашего же удобства; Все! Мы изменили код)) Осталось его сохранить - пишем в файл то, что вернет astring: writeFileSync("./output.js", generate(AST)); Code writeFileSync("./output.js", generate(AST)); В output будет уже измененный код. В нем уже можно удалить весь код который относится к инициализации массива и получению из него переменной, потому что он там более не используется. Для ренейминга переменных я предлагаю использовать модуль для vscode: https://marketplace.visualstudio.com/items?itemName=cmstead.jsrefactor Он переименовывает все идентификаторы указанной переменной, обращая внимание на scope. Финальная и чуть измененная(модульная) версия будет состоять из 2 файлов (cори за пастбин): index js: https://pastebin.com/VpgpWFay ASTmodules js: https://pastebin.com/QnwnUKEF Итог: в файл input.js помещаете ваш код, запускаете через node index скрипт, в output.js получаете изменненый. Code Итог: в файл input.js помещаете ваш код, запускаете через node index скрипт, в output.js получаете изменненый. Понять почему именно такой код мы написали, вам так же поможет https://astexplorer.net. В него можно совать куски валидного кода, и он будет распаршивать их в AST, наглядно показывая результат. Так же могу порекомендовать великолепный плейграунд для js кода - quokka js. Желательно Pro версию, в ней больше возможностей. Для лучшего экспириенса во время деобфускации и в целом программирования можно пользоваться дебаггингом с брейкпоинтами в vscode. (Попробуйте нажать F5) Автор: https://t.me/elevengate Предложения по оформлению, что интересно по теме - пишите тут.