
Обфускатор JavaScript, основанный на криптографических методах неразличимого запутывания (Indistinguishability Obfuscation)
Этот проект не обеспечивает неразличимую обфускацию. Не следует использовать этот продукт для защиты секретов. Он существует для того, чтобы затруднить обратную разработку, а не предотвратить её
JavaScript-обфускатор, предназначенный для того, чтобы сделать код чрезвычайно трудным для чтения и анализа как людьми, так и LLM. Написан на TypeScript. Реализует техники из рецензируемых исследований по криптографической обфускации.
npm install
npm run build
# Basic usage
node dist/index.js input.js > output.js
# With target token budget (default: 2,000,000)
node dist/index.js --target-tokens 500000 input.js > output.js
# Minimal obfuscation (small output)
node dist/index.js --target-tokens 10000 input.js > output.js
# Maximum bloat (10M tokens)
node dist/index.js --target-tokens 10000000 input.js > output.js
# Using environment variable
INPUT_FILE=input.js node dist/index.js > output.js
# Help
node dist/index.js --help
| Option | Default | Description |
|---|---|---|
--target-tokens <n> | 2000000 | Целевой размер вывода в токенах. Небольшие входные данные раздуваются до этого предела. Крупные входные данные дают меньше раздувания, чтобы оставаться в рамках бюджета. |
--help, -h | Показать справочное сообщение |
npm run build # Compile TypeScript to dist/
npm run start # Run the obfuscator (reads input.js)
npm run test # Run the test suite
npm run obfuscate-package # Run compatibility tests against npm packages
const { obfuscate } = require('./dist/obfuscator');
const code = 'function add(a, b) { return a + b; }';
const obfuscated = obfuscate(code);
// With options
const obfuscated = obfuscate(code, { targetTokens: 500000 });
Обфускатор применяет 20 преобразований в 4 фазах. Каждый этап опирается на предыдущий.
| Порядок | Преобразование | Файл | Описание |
|---|---|---|---|
| 1 | Анти-отладочные ловушки | transforms/antiDebug.ts | Внедряет операторы eval("debugger") и 10–20 циклов setInterval с интервалами в виде простых чисел (5–600 с), которые многократно вызывают точки останова отладчика. Каждый экземпляр использует уникальные закодированные строки. |
| 2 | Ловушки проколотой программы | transforms/tripwires.ts | Встраивает скрытые проверки, сравнивающие хеши параметров с секретными значениями. 5 шаблонов хешей (битовый отпечаток, модулярная арифметика, charCodeAt, числовой хеш, typeof+length). При секретных входных данных вызывает незаметное повреждение состояния, бесконечные циклы или исключения. [Paper 4] |
| 3 | Внедрение шума LPN | transforms/noiseInjection.ts | Добавляет и компенсирует случайный шум через разделённые пути в арифметических вычислениях. 6 шаблонов: сложение/вычитание, XOR, умножение/деление, разделение по двум переменным, вычисляемая хеш-цепочка, циклический битовый сдвиг. Промежуточные значения бессмысленны без трассировки полной компенсации. [Paper 7] |
| Порядок | Преобразование | Файл | Описание |
|---|---|---|---|
| 4 | Уплощение потока управления | transforms/controlFlowFlattening.ts | Преобразует тела функций в конечные автоматы вида while(true) { switch((_s * P) % M) { ... } } с диспетчеризацией через модулярную арифметику — значения case кодируются через (stateId * multiplier) % modulus с использованием случайных простых параметров. [Paper 3] |
| 5 | Непрозрачные предикаты | transforms/opaquePredicates.ts | Внедряет условия if, которые всегда истинны или ложны, но математически сложно доказуемы (например, (x*x+x)%2===0). 15 формул предикатов в категориях модулярной арифметики, битовых операций и проверок типов. |
| 6 | Прокси-функции | transforms/proxyFunctions.ts | Направляет все вызовы функций через два диспетчера: _fc(fn, ...args) для простых вызовов и _mc(obj, prop, ...args) для вызовов методов. Использует Function.prototype.apply, сохранённый в локальной переменной, для повышения устойчивости. |
| 7 | Истощение контекстного окна | transforms/contextExhaustion.ts | Оборачивает выражения в глубоко вложенные тернарные операторы с непрозрачными условиями, цепочки void-выражений и условное заполнение через void. Вынуждает LLM тратить токены контекстного окна на шум. |
| 8 | Слияние выражений с запятой | transforms/commaExpressions.ts | Сворачивает последовательные выражения-инструкции в одиночные выражения с запятой: a(); b(); return c() превращается в return a(), b(), c(). |
| Порядок | Проход | Файл | Описание |
|---|---|---|---|
| 9 | Проход 1: Каталогизация | passes/firstPass.ts | Обходит AST и каталогизирует каждый идентификатор, создавая карту глобальных переменных, которая назначает каждому случайное имя Unicode длиной 6–16 символов из 16 диапазонов письменностей (CJK, хангыль, греческий, кириллица, деванагари, тайский, арабский, катакана и т. д.). |
| 10 | Проход 2: Подстановка | passes/secondPass.ts | Заменяет все имена идентификаторов на их обфусцированные эквиваленты Unicode. Кодирует аргументы require() как String.fromCharCode(...). Кодирует источники статических import/export как строковые литералы с unicode-escape. Подставляет ссылки superClass классов, выражения шаблонных литералов, паттерны деструктуризации. |
| 11 | Проход 3: Фиктивные параметры | passes/thirdPass.ts | Внедряет от 0 до 15 случайных неиспользуемых параметров в каждое объявление и выражение функции. Пропускает функции с rest-параметрами. Удаляет все комментарии. |