
AI-ассистируемый реверс-инжиниринг с помощью Ghidra
Rev·Deck — это локальная однопользовательская рабочая станция статического анализа. Она объединяет веб-интерфейс с приоритетом фактов и LLM-копайлота поверх бинарного файла, анализируемого headless-сервисом Ghidra: просматривайте детерминированные факты (функции, строки, импорты, перекрёстные ссылки, ограниченный граф вызовов) напрямую или задавайте ассистенту ограниченные вопросы, фактические утверждения в ответах которых должны ссылаться на проверяемые данные.
Анализируемые бинарные файлы никогда не исполняются. Браузер взаимодействует только с этим Flask-приложением; приложение проксирует проверенные типизированные запросы к сервису Ghidra.
https://github.com/user-attachments/assets/fba14dc5-7ad5-4137-9349-ed824da64fbe
cp .env.example .env # set API_BASE and MODEL_NAME; set API_KEY if required
docker compose up --build
Docker Compose автоматически читает .env для подстановки значений. Он завершается ошибкой до запуска, если API_BASE или MODEL_NAME отсутствуют; API_KEY=not-used остаётся допустимым для локальных провайдеров без ключа. Стек запускает оба сервиса. Откройте http://127.0.0.1:5000.
Чтобы запустить только сервис Ghidra:
docker pull biniamfd/ghidra-headless-rest:latest # ensure the newest image
docker run --rm \
-p 127.0.0.1:9090:9090 \
-v "$(pwd)/data:/data/ghidra_projects" \
--security-opt no-new-privileges:true \
biniamfd/ghidra-headless-rest:latest
Для воспроизводимой фиксации версии используйте протестированный дайджест релиза вместо latest:
docker run --rm \
-p 127.0.0.1:9090:9090 \
-v "$(pwd)/data:/data/ghidra_projects" \
--security-opt no-new-privileges:true \
biniamfd/ghidra-headless-rest:1.2.1@sha256:971591a3a8448d8ed969079b452306e806f36079c3ddd298f4a618d6e2f1442d
biniamfd/ghidra-headless-rest:latest.Скопируйте .env.example в .env и заполните их; полный список и значения по умолчанию см. в этом файле.
| Переменная | По умолчанию | Значение |
|---|---|---|
API_BASE | обязательна | OpenAI-совместимый базовый URL (http/https). Compose завершается с ошибкой на раннем этапе, если переменная отсутствует. |
API_KEY | not-used | Ключ провайдера. Никогда не логируется и не отправляется в браузер; not-used допустим для локальных провайдеров без ключа. |
MODEL_NAME | обязательна | Идентификатор модели, ожидаемый настроенной конечной точкой. Compose завершается с ошибкой на раннем этапе, если переменная отсутствует. |
LLM_STREAM | auto | Режим потоковой передачи: auto (потоковая передача с однократным откатом к блокирующему режиму при ошибке совместимости до вывода), true (всегда потоковая передача), false (всегда блокирующий режим). |
GHIDRA_API_BASE | http://127.0.0.1:9090 | Базовый URL сервиса Ghidra. |
GHIDRA_IMAGE | biniamfd/ghidra-headless-rest:1.2.1@sha256:971591a3... | Протестированный релиз, зафиксированный неизменяемым дайджестом. :latest также разрешается в этот дайджест; переопределите, чтобы зафиксировать другой релиз. |
HOST / PORT | 127.0.0.1 / 5000 | Привязка dev-сервера. |
MAX_UPLOAD_BYTES | 104857600 | Ограничение размера загрузки. |
CHATS_DIR | webui/chats | Каталог истории чатов. |
Rev·Deck взаимодействует с любой OpenAI-совместимой конечной точкой Chat Completions через OpenAI SDK, настраиваемый исключительно через API_BASE / API_KEY / MODEL_NAME. Здесь нет специфичной для провайдера логики заголовков, параметров или моделей: локальный сервер Ollama (API_BASE=http://127.0.0.1:11434/v1), самостоятельно размещённая конечная точка vLLM/llama.cpp/LM Studio, сам OpenAI или шлюз вроде OpenRouter — всё работает одинаково.
Примеры настроек провайдера в .env (используйте заглушки, никогда не коммитьте реальные ключи):
# Ollama
API_BASE=http://127.0.0.1:11434/v1
API_KEY=not-used
MODEL_NAME=qwen3:8b
# OpenRouter
API_BASE=https://openrouter.ai/api/v1
API_KEY=replace-with-your-key
MODEL_NAME=anthropic/claude-opus-4.8
# OpenAI
API_BASE=https://api.openai.com/v1
API_KEY=replace-with-your-key
MODEL_NAME=replace-with-a-supported-model-id
# LM Studio, vLLM, or llama.cpp (adjust port/model to the server)
API_BASE=http://127.0.0.1:1234/v1
API_KEY=not-used
MODEL_NAME=replace-with-the-served-model-id
По умолчанию (LLM_STREAM=auto) ассистент запрашивает потоковый ответ и передаёт токены в браузер по мере их поступления. Потоковая передача также даёт более сильную гарантию отмены: когда вы останавливаете ответ (или закрываете вкладку), Rev·Deck немедленно закрывает нижележащий поток провайдера и не выполняет дальнейших раундов инструментов или модели, поэтому вышестоящая генерация прерывается, а не продолжает выполняться в фоне до завершения.
Предостережения:
auto, если провайдер отклоняет потоковый запрос с ошибкой совместимости (HTTP 400/404/405/422) до вывода какого-либо содержимого или вызовов инструментов, Rev·Deck один раз выполняет откат к блокирующему вызову и запоминает это на всё время работы процесса. Ошибки аутентификации (401/403), ограничения частоты запросов (429) и серверные ошибки (5xx) не рассматриваются как проблемы совместимости и выводятся как ошибки, а не молча повторяются. Установите LLM_STREAM=false, чтобы полностью отключить потоковую передачу, или LLM_STREAM=true, чтобы сделать её обязательной (без отката).Откройте приложение и загрузите бинарный файл, чтобы начать задачу анализа. Если содержимое явно является обычным текстом, приложение запросит подтверждение перед отправкой в Ghidra; используйте явное переопределение raw-binary только тогда, когда содержимое намеренно является прошивкой/данными, а не исполняемым форматом. После завершения анализа переключайтесь между двумя вкладками рабочей области: