Что делать, если код в модуле 1С выглядит как непонятный набор меток и переходов Goto?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

В практике разработчика 1С иногда встречаются модули, текст которых напоминает «спагетти-код»: обилие операторов Goto, странные метки вида ~IL_5842, переменные с именами _0 или _1 и использование английских ключевых слов вроде endif. На первый взгляд такой код кажется синтаксической ошибкой или результатом сбоя, однако он успешно компилируется и выполняется системой. Разберем по шагам, что это такое, почему так происходит и как с этим работать.

Выясним причину: что такое обфускация кода

Ситуация, описанная в сообщении, — это классический пример обфускации. Обфускация (от лат. obfuscation — запутывание) — это приведение исходного текста программы к виду, сохраняющему его функциональность, но максимально затрудняющему анализ, понимание алгоритмов и модификацию человеком. Проанализируем основные приемы, которые применяются в таких случаях:

  1. Запутывание потока управления (Control Flow Flattening): Это именно то, что мы видим в примере. Вместо привычных структур Если... Иначе... КонецЕсли или циклов Для... Цикл, обфускатор превращает код в плоский список инструкций, связанных операторами Перейти (Goto). Логика «прыгает» из начала в конец модуля и обратно, что делает невозможным отслеживание алгоритма в уме.
  2. Переименование переменных и функций: Все осмысленные имена (например, СуммаДокумента или РассчитатьНалоги) заменяются на бессмысленные короткие идентификаторы.
  3. Использование альтернативного синтаксиса: Обфускаторы часто переключают код на английский язык, так как он воспринимается разработчиками в СНГ сложнее при быстром чтении.

Рассмотрим использование оператора Перейти (Goto) и меток

Многие разработчики ошибочно полагают, что Goto — это пережиток старых языков программирования типа Basic или Fortran. Однако в платформе 1С:Предприятие 8 оператор Перейти является штатным механизмом. Рассмотрим подробнее синтаксис, который использует обфускатор. Код, приведенный в примере:


if _0=false then goto ~IL_5842 endif; 
goto ~46; 
~IL_5842:; 
goto ~53;

Проанализируем ситуацию: здесь используется английский вариант операторов. В 1С любая команда имеет двуязычное написание. Рассмотрим соответствия:

Метки, такие как ~IL_5842, в данном контексте являются просто именами точек перехода. Префикс ~IL_ часто намекает на «Intermediate Language» — это почерк инструментов, которые имитируют работу низкоуровневых компиляторов. Платформа 1С позволяет использовать символ тильды в именах меток, что активно эксплуатируется защитными скриптами.

Разберем, почему код написан на английском языке

Платформа 1С полностью двуязычна. Любой модуль можно написать как на русском, так и на английском языке, и они будут абсолютно равносильны. Например, стандартный цикл может выглядеть так:


For Each Item In Collection Do
    If Item.Value = True Then
        Goto ~Label1;
    EndIf;
EndDo;

Обфускаторы выбирают английский язык по двум причинам. Во-первых, это позволяет использовать более компактные ключевые слова. Во-вторых, это создает дополнительный психологический барьер для русскоязычного программиста, привыкшего к кириллице в конфигураторе.

Возможно ли восстановить исходный код?

Существует мнение, что «фарш невозможно провернуть назад». В значительной степени это так: если оригинальные имена переменных были удалены, вернуть их автоматически не получится (информация о том, что переменная _0 называлась Отказ, нигде в скомпилированном коде не хранится). Однако рассмотрим способы упрощения работы с таким кодом:

  1. Применение форматеров (Beautifiers): Первым делом нужно восстановить отступы и структуру текста. Это не уберет Goto, но хотя бы расставит операторы по строкам в читаемом порядке.
  2. Анализ графа вызовов: Продвинутые деобфускаторы пытаются заменить цепочки If... Goto обратно на стандартные If... Else. Это сложная математическая задача анализа графа переходов, но частичный успех возможен.
  3. Ручное переименование: Это самый надежный, но долгий путь. Выделяете переменную (например, _0), находите все её вхождения через Ctrl+F и, анализируя контекст (например, если она передается в Предупреждение()), даете ей осмысленное имя через «Поиск и замену».

Практические советы при встрече с таким кодом

Если вы столкнулись с подобной обработкой от стороннего сервиса, выясним причину вашего интереса к коду. Обычно такая защита ставится на платные решения или модули интеграции, чтобы скрыть алгоритмы взаимодействия с API или защитить лицензионную проверку.

Рекомендуем следующий порядок действий:

Посмотрим на пример того, во что превращается простейшее условие после обфускации. Обычный код:


Если Сумма > 100 Тогда
    Статус = "Много";
Иначе
    Статус = "Мало";
КонецЕсли;

Тот же код после обработки может выглядеть так:


~Begin: 
_var1 = (Сумма > 100);
If _var1 = False Then Goto ~Label_Else EndIf;
Статус = "Много";
Goto ~End;
~Label_Else:
Статус = "Мало";
~End:
;

Как мы видим, логика сохранена, но читать её стало значительно труднее. Подводя итог, помните: наличие такого кода — это не ошибка, а преднамеренная защита интеллектуальной собственности. Работа с ним требует высокой квалификации и понимания внутреннего устройства платформы 1С.

← На главную