
Обфусцирует сборки Go, оборачивая цепочку инструментов Go, заменяя идентификаторы, пути пакетов и данные о позициях хешами, а также удаляя отладочную информацию и информацию о сборке.
go install mvdan.cc/garble@latest # or @master
Обфусцирует код Go путём обёртывания инструментальной цепочки Go. Требуется Go 1.27 или новее.
garble build [build flags] [packages]
Инструмент также поддерживает garble test для запуска тестов с обфусцированным кодом,
garble run для обфускации и выполнения простых программ,
garble reverse для деобфускации текста, например трассировок стека,
и garble bug для отправки предзаполненного отчёта об ошибке.
Запустите garble -h, чтобы увидеть все доступные команды и флаги.
Создать бинарный файл, который работает так же хорошо, как обычная сборка, но содержит как можно меньше информации об исходном коде.
Инструмент разработан так, чтобы быть:
cmd/go, для поддержки модулей и кэширования сборкиИнструмент обёртывает вызовы компилятора и компоновщика Go, чтобы преобразовать сборку Go, с целью:
-literals-tinyИнструмент обфусцирует все поддерживаемые собираемые пакеты, включая стандартную среду выполнения.
Неподдерживаемые пакеты runtime/cgo и crypto/internal/fips140 исключены.
Обфускация среды выполнения следует поддерживаемым в Go целям GOOS/GOARCH; Garble не
поддерживает более узкий список разрешённых архитектур.
Обратите внимание, что такие команды, как garble build, будут использовать версию go, найденную в вашем
$PATH. Чтобы использовать другие версии Go, вы можете использовать GOTOOLCHAIN.
Частый вопрос — зачем нужен обфускатор кода для Go, компилируемого языка. Бинарные файлы Go содержат удивительно много информации об исходном коде; даже при удалённой отладочной информации и таблицах символов многие имена и позиции остаются на месте ради трассировок, рефлексии и отладки.
Некоторые сценарии использования Go требуют передачи бинарного файла Go конечному пользователю. Если исходный код бинарного файла является закрытым или требует покупки, его обфускация может помочь воспрепятствовать обратной разработке.
Похожий сценарий — библиотека Go, исходный код которой является закрытым или приобретённым. Поскольку библиотеки Go нельзя импортировать в бинарной форме, а плагины Go имеют свои недостатки, обмен обфусцированным исходным кодом становится вариантом. См. #369.
Обфускация также может помочь в аспектах, совершенно не связанных с лицензированием.
Например, флаг -tiny может сделать бинарные файлы на 15% меньше,
подобно распространённой практике в Android по уменьшению размеров приложений.
Обфускация также помогла некоторым разработчикам открытого ПО обойти
антивирусные проверки, ошибочно принимающие бинарные файлы Go за вредоносное ПО.
Использование флага -literals приводит к тому, что литеральные выражения, такие как строки,
заменяются более сложными выражениями, вычисляющимися в то же значение во время выполнения.
Строковые литералы, внедрённые через -ldflags=-X, также заменяются этим флагом.
Эта функция включается по желанию, так как может вызывать замедление в зависимости от входного кода.
Литералы, используемые в константных выражениях, не могут быть обфусцированы, поскольку они
вычисляются во время компиляции. Это включает, например, любые выражения, являющиеся частью
объявления const.
Обратите внимание, что этот процесс может быть обращён при достаточных усилиях; см. #984.
С флагом -tiny из бинарного файла Go удаляется ещё больше информации.
Информация о позициях удаляется полностью, а не обфусцируется.
Код среды выполнения, который выводит паники, фатальные ошибки и информацию трассировки/отладки, удаляется.
Многие имена символов также опускаются в секциях бинарного файла во время компоновки.
В целом это может сделать бинарные файлы примерно на 15% меньше.
С этим флагом паники или фатальные ошибки среды выполнения никогда не будут выводиться, но они
по-прежнему могут обрабатываться внутри с помощью recover как обычно.
Обратите внимание, что этот флаг может затруднить отладку сбоев, так как паника просто
завершит всю программу без вывода трассировки стека, а позиции исходного кода
и многие имена удаляются.
Аналогично, garble reverse в этом режиме, как правило, бесполезен.
См.: CONTROLFLOW.md
garble build должен занимать примерно вдвое больше времени, чем go build, так как ему нужно
выполнить две сборки. Исходную сборку, чтобы иметь возможность загрузить и проверить типы
входного кода, а затем обфусцированную сборку.
Garble обфусцирует по одному пакету за раз, повторяя то, как Go компилирует по одному пакету
за раз. Это позволяет Garble полностью поддерживать кэш сборки Go; инкрементальные
вызовы garble build должны только пересобирать и переобфусцировать изменённый код.
Обратите внимание, что первый вызов garble build может быть сравнительно медленным,
так как ему приходится обфусцировать каждый пакет впервые. Это сродни очистке
GOCACHE с помощью go clean -cache и запуску go build с нуля.
Garble также использует собственный кэш для повторного использования работы, подобно GOCACHE в Go.
По умолчанию он находится в каталоге внутри каталога кэша вашего пользователя,
например ~/.cache/garble, и может быть размещён в другом месте путём установки GARBLE_CACHE.
Как и Go, сборки garble по своей природе детерминированы и воспроизводимы.
Это даёт значительные преимущества, такие как кэширование сборок и возможность использовать
garble reverse для деобфускации трассировок стека.
По умолчанию garble обфусцирует каждый пакет уникальным образом, который изменится, если изменятся входные данные его сборки: версия garble, версия Go, исходный код пакета или любой параметр сборки, такой как GOOS или -tags. Это разумное значение по умолчанию, поскольку угадать эти входные данные очень сложно.
Вы можете использовать флаг -seed, чтобы предоставить собственное зерно случайности для обфускации.
Повторное использование одного и того же зерна может помочь получить одинаковую обфускацию кода,
что может помочь при отладке или воспроизведении проблем.
Регулярная смена зерна также может помочь против обратной разработки в долгосрочной перспективе,
так как иначе можно посмотреть на изменения в том, как обфусцируется стандартная библиотека Go,
чтобы угадать, когда версии Go или garble были изменены в серии сборок.
Чтобы всегда использовать разное зерно для каждой сборки, используйте -seed=random.
Обратите внимание, что следует проявлять особую осторожность при использовании пользовательских зерён:
если значение -seed, использованное в сборке, потеряно, garble reverse не будет работать.
Большинство из них может улучшиться со временем и усилиями. Цель этого раздела — задокументировать текущие недостатки этого инструмента.