Реверс-инжиниринг с агентами: от поведения приложений к бинарникам
Инструмент rea от morluto позволяет реверсировать приложения и нативные бинарники с помощью ИИ-агентов. Разбираемся, как это работает и зачем использовать.
Что такое rea и зачем он нужен
Обзор возможностей инструмента
rea — это CLI-утилита от morluto, которая подходит к реверс-инжинирингу не с той стороны, которой традиционно подходят IDA Pro или Ghidra. Вместо того чтобы показывать дизассемблер и ждать, пока человек разберётся с логикой программы, rea запускает цепочку ИИ-агентов, каждый из которых отвечает за определённый шаг: от сбора метаданных до построения высокоуровневого описания поведения.
Вот что умеет rea из коробки:
- Автоматический сбор информации о бинарнике — сигнатуры, секции, экспорты, импорты, строки. Всё это собирается до того, как агенты приступят к анализу.
- Динамический запуск в изолированной среде — утилита умеет запускать бинарник в контейнере или песочнице, перехватывать системные вызовы и логировать их. Это даёт агентам реальное поведение, а не только статический код.
- Построение графа вызовов и зависимостей — на основе strace, ltrace и анализа секций формируется структурированное описание того, какие библиотеки задействованы, какие функции вызываются и в каком порядке.
- Генерация человекочитаемого отчёта — вместо дампа в 50 тысяч строк
reaвыдаёт Markdown-отчёт с описанием цели программы, ключевых функций, используемых протоколов и потенциальных точек входа для дальнейшего анализа.
Пример запуска на простом ELF-файле:
bashrea analyze --target ./myapp --report markdown --sandbox docker
Утилита скачивает образ Alpine, копирует туда бинарник, запускает его с перехватом ptrace, а затное передаёт логи агентам. Результат — не просто «это ELF на архитектуре x86-64», а «программа читает конфиг из /etc/myapp.conf, открывает TCP-соединение на порт 8080 и отправляет JSON-запросы в RabbitMQ».
Для сравнения: если Graphify строит граф из исходного кода, то rea строит граф из поведения — и это разные вещи. Один работает с тем, что видно в репозитории, другой — с тем, что происходит в реальности, когда программа запущена.
Архитектура и принцип работы агентов
Архитектура rea построена вокруг трёх слоёв, каждый из которых реализован как отдельный ИИ-агент с чётко определённой ролью.
Слой сбора данных (Data Collector Agent) отвечает за всё, что можно автоматизировать без ИИ: дамп секций через readelf, извлечение строк через strings, трассировку вызовов через strace в песочнице. Агент не пытается интерпретировать результат — он просто собирает и структурирует. Его вывод попадает в очередь задач для следующего слоя.
Слой анализа (Analysis Agent) получает сырые данные и формирует гипотезы. Он задаёт вопросы вроде: «какие функции вызываются чаще всего?», «какие строки выглядят как пути к файлам?», «какой протокол используется на сетевом соединении?». Для этого агент использует LLM с доступом к инструментам: он может вызвать objdump, чтобы посмотреть дизассемблер конкретной функции, или nm, чтобы проверить символы.
Слой синтеза (Synthesis Agent) — это уже почти финальный этап. Агент собирает всё вместе: граф вызовов, сетевые соединения, файлы на диске, строки с паролями. Его задача — не просто перечислить факты, а построить связное повествование. «Программа стартует как демон, инициализирует конфиг из /opt/app/config.yaml, устанавливает соединение с PostgreSQL на localhost:5432 и периодически отправляет метрики в StatsD».
Вся цепочка работает по принципу агент-в-цикле: если Analysis Agent обнаруживает нечто необычное — например, вызов ptrace на собственном процессе — он может запросить дополнительный сбор данных, и Data Collector Agent запустит более глубокую трассировку. Это похоже на то, как gstack в Claude Code позволяет агенту самому решать, когда нужно больше контекста.
Особенно удобно, что rea интегрируется с DeepSeek Harness — вы можете подменить встроенные LLM на свои, а если нужно сэкономить токены, подключить Caveman для сжатия промежуточных результатов.
Архитектура поддерживает плагины: вы можете написать свой агент для сбора данных с FPGA-устройств, подключённого по SPI, или для анализа трафика внутри контейнера Kubernetes. Главное — агент должен реализовывать интерфейс AgentInterface и регистрироваться в конфиге:
yamlagents:
- name: spi-sniffer
type: custom
entrypoint: /opt/rea-agents/spi-sniffer.py
triggers:
- binary_arch: arm
- section_exists: .spi_config
Такой подход даёт предсказуемость: вы всегда знаете, какие этапы анализа выполнены, какие данные использованы и какие гипотезы сформулированы. Никаких «чёрных ящиков», где ИИ что-то там решает, а вы не видите, зачем ему это нужно.
Установка и первичная настройка
Требования и зависимости
Инструмент rea работает на Python 3.10+ и требует доступа к LLM-агенту. Минимальный набор:
- Python 3.10 или новее
- Git для клонирования репозитория
- API-ключ к Claude, GPT или совместимому провайдеру
- Docker (опционально, для изоляции анализа бинарников)
Установить зависимости можно через pip:
bashpip install rea-agent
Или собрать из исходников:
bashgit clone https://github.com/morluto/rea.git
cd rea
pip install -r requirements.txt
Перед первым запуском создайте файл конфигурации ~/.rea/config.yaml:
yamlllm:
provider: anthropic
api_key: ${ANTHROPIC_API_KEY}
model: claude-3-sonnet-20240229
analysis:
max_steps: 50
timeout_minutes: 10
sandbox_enabled: true
С практической точки зрения, важно сразу задать лимиты — без них агент может крутиться в цикле, особенно на больших бинарниках. Я обычно ставлю max_steps: 30 для первых тестов.
Быстрый старт: запуск первого анализа
Возьмём простой пример — бинарник hello:
bashecho 'int main() { printf("Hello, world!\n"); return 0; }' > hello.c
gcc hello.c -o hello
Запуск анализа выглядит так:
bashrea analyze ./hello --agent claude-code
Агент получает доступ к файловой системе, может выполнять команды (strings, objdump, gdb) и последовательно раскрывает поведение программы. Результаты складываются в ./output/hello_report.md.
Если хотите увидеть процесс в реальном времени:
bashrea analyze ./hello --agent claude-code --verbose
Для более тяжёлых случаев включите sandbox через Docker:
bashrea analyze ./hello --agent claude-code --sandbox docker
Мне больше нравится запускать в изолированном окружении — особенно если анализирую чужие бинарники. Предсказуемость и безопасность здесь идут рука обойди.
Если вы уже знакомы с Caveman-скиллом, можете поэкспериментировать с оптимизацией промптов агента через gstack. А для построения графа зависимостей по результатам анализа удобно использовать Graphify.
Практические сценарии использования
Анализ поведения приложений
Когда мне нужно разобаться, почему приложение ведёт себя не так, как ожидалось, я запускаю rea в режиме наблюдения. ИИ-агент не сразу лезет в код — он сначала «наступает» по системе: какие файлы открывает, какие сетевые соединения устанавливает, какие сигналы посылает процессу.
bashrea observe --target /opt/myapp/bin/server --duration 30s --output trace.json
Агент фиксирует каждый системный вызов через ptrace, а затем использует полученную последовательность, чтобы сформулировать гипотезы. Например, если приложение пытается подключиться к localhost:5432, но PostgreSQL ещё не запущен — агент это замечает и предлагает поправить порядок старта через systemd.
Чтобы не терять контекст между сессиями, я подключаю gstack, который сохраняет состояние агента на диск. Это особенно удобно, когда разбор занимает несколько часов:
yaml# ~/.config/rea/profiles/home-lab.yaml
agent:
persistence: true
memory_dir: /var/lib/rea/sessions
skills:
- filesystem-tracer
- network-sniffer
- syscall-analyzer
После наблюдения агент генерирует граф зависимостей — какие компоненты влияют на какие. Граф строится не по исходникам, а по фактическому поведению. То же самое можно сделать с помощью Graphify, но rea делает это «на живую», без доступа к исходникам.
Работа с нативными бинарниками
Обычная декомпиляция даёт глиняный результат: понятна структура функций, но теряется логика. rea подходит иначе — он запускает бинарник в изолированном окружении (Firejail или systemd-nspawn), подаёт разные входные данные и анализирует ответы. Это как тестировать чёрный ящик, но с ИИ вместо глаз.
bashrea analyze --binary /usr/local/bin/worker \
--sandbox firejail \
--inputs "input1.txt,input2.txt" \
--timeout 10s \
--report report.md
Агент перебирает варианты: меняет аргументы командной строки, подменяет переменные окружения, подсовывает разные файлы. На каждом шаге он оценивает реакцию бинарника — код завершения, вывод в stdout/stderr, изменения в файловой системе. Затем на основе всех этих наблюдений строит модель поведения.
Для сложных бинарников я включаю DeepSeek Harness — плагинную обёртку, которая добавляет собственные скиллы агенту. Один из них — caveman — помогает экономить токены, если нужно пройти длинную цепочку вызовов. Подробнее о нём в этой материале.
bash# Подключаем плагин через DeepSeek Harness
rea analyze --binary /usr/local/bin/worker \
--plugin deepseek-harness://caveman \
--inputs "input1.txt,input2.txt" \
--timeout 10s \
--report report.md
Что особенно ценно — rea не просто описывает, что бинарник делает. Он предлагает конкретные правки: «добавьте проверку длины аргумента», «обработайте случай, когда файл не существует». И делает это с учётом реального поведения, а не гипотетических сценариев.
Интеграция с существующими инструментами
Совместимость с популярными дебаггерами
Отладка — это не про то, чтобы запустить gdb и надеяться. Это про предсказуемость. ИИ-агент rea открывает интерфейс к дебаггерам через их CLI-обёртки, но без «на коленке» — с понятными границами ответственности.
Вот как это выглядит на практике. Допустим, вы анализируете бинарник и хотите увидеть, что происходит на уровне системных вызовов. rea не заменяет strace — он использует его как источник данных, а вы сами выбираете, как интерпретировать вывод.
bash# Запуск rea с интеграцией strace
rea analyze --target ./myapp \
--debugger strace \
--output-format json \
--log-level debug
Аналогично с ltrace — rea не пытается стать универсальным дебаггером. Он собирает сырые данные, а вы решает, как их использовать.
Для gdb ситуация чуть сложнее. rea не поддерживает интерактивный режим, но умеет запускать скрипты:
bash# Создаём скрипт для gdb
cat > /tmp/gdb_script.txt << 'EOF'
set pagination off
set confirm off
run
bt
info registers
quit
EOF
# Запускаем rea с gdb-бэкендом
rea analyze --target ./myapp \
--debugger gdb \
--script /tmp/gdb_script.txt \
--timeout 30
С практической точки зрения это важно: вы не теряете контроль над инструментом, а получаете структурированный вывод, который можно парсить в дальнейшем.
Если вы работаете с Graphify для построения графа знаний, интеграция выглядит так:
bash# Экспорт данных из rea в формате для Graphify
rea analyze --target ./myapp \
--debugger gdb \
--script /tmp/gdb_script.txt \
--output-format graphify-json \
--output-file /tmp/rea_output.json
# Импорт в Graphify
graphify import --source /tmp/rea_output.json --project myproject
Автоматизация через CLI
CLI-интерфейс rea построен по принципу: одна задача — одна команда. Никаких «универсальных» флагов, которые делают три разных вещи в зависимости от лунного календаря.
Вот типичный workflow для автоматизации:
bash#!/bin/bash
# analyze_binary.sh — скрипт для пакетного анализа
BINARY_PATH="$1"
REPORT_DIR="/tmp/analysis_reports"
mkdir -p "$REPORT_DIR"
# Шаг 1: Статический анализ
rea static-analyze \
--target "$BINARY_PATH" \
--output "$REPORT_DIR/static.json"
# Шаг 2: Динамический анализ с strace
rea dynamic-analyze \
--target "$BINARY_PATH" \
--debugger strace \
--timeout 10 \
--output "$REPORT_DIR/dynamic_strace.json"
# Шаг 3: Анализ с ltrace
rea dynamic-analyze \
--target "$BINARY_PATH" \
--debugger ltrace \
--timeout 10 \
--output "$REPORT_DIR/dynamic_ltrace.json"
# Шаг 4: Генерация отчёта
rea report \
--input "$REPORT_DIR" \
--format html \
--output "$REPORT_DIR/report.html"
Если вы используете DeepSeek Harness для оркестрации агентов, интеграция выглядит так:
yaml# deepseek-harness config
agents:
- name: rea-analyzer
type: cli
command: |
rea analyze --target {{ binary_path }} \
--debugger strace \
--output-format json
parameters:
binary_path:
type: string
required: true
timeout: 60
А для тех, кто работает с Caveman-скиллом в Claude Code — rea можно вызывать как внешний инструмент:
bash# Настройка rea как внешнего инструмента в Claude Code
# ~/.claude-code/config.json
{
"external_tools": {
"rea": {
"command": "rea",
"args": ["analyze", "--target", "{}", "--output-format", "json"],
"description": "Анализ бинарника с помощью ИИ-агентов"
}
}
}
Тогда в Claude Code вы можете писать:
Проанализируй бинарник /usr/bin/myapp с помощью rea и покажи, какие библиотеки он использует
И система автоматически подставит путь в команду.
Связка с gstack от Гарри Тана работает через общий принцип — rea выступает как источник данных, а gstack или Claude Code обрабатывают результат:
bash# Пример комбинированного использования
rea analyze --target ./myapp --output-format json > /tmp/rea_result.json
claude-code --context /tmp/rea_result.json --prompt "Объясни, какие уязвимости есть в этом анализе"
Главное правило: автоматизация должна быть предсказуемой. Если вы не можете объяснить, что делает каждая строкка скрипта, не запускайте его в продакшен.
Часто задаваемые вопросы
Что делает каждый агент в цепочке rea
В rea нет единого «универсального» агента — цепочка состоит из специализированных модулей, каждый из которых отвечает за конкретный этап. Первый агент собирает метаданные бинарника: сигнатуры, секции, экспорты и импорты, чтобы понять, с чем мы имеем дело. Затем следующий агент запускает целевой файл в изолированной среде (Docker или песочнице), перехватывая системные вызовы через ptrace, strace и ltrace. На этом этапе агенты фиксируют реальное поведение программы — какие файлы она открывает, какие сетевые соединения устанавливает, какие библиотеки подгружает. Последний агент анализирует собранные логи, строит граф вызовов и формирует человекочитаемый Markdown-отчёт с описанием цели программы, ключевых функций и потенциальных точек для дальнейшего анализа.
Можно ли использовать rea для коммерческих приложений
Формально rea распространяется под лицензией MIT, и ничто не мешает запускать его на коммерческих бинарниках. Однако здесь важно разграничить цели: если вы анализируете ПО, которое сами разработали или имеете на то явное право, — процесс проходит без вопросов. Если речь идёт о чужом коммерческом приложении, стоит убедиться, что ваш анализ не нарушает условий лицензионного соглашения или законодательства о защите интеллектуальной собственности. С практической точки зрения rea не навязывает ограничений, но ответственность за правовую сторону всегда лежит на операторе. Рекомендую перед запуском на чужом ПО проконсультироваться с юристом, особенно если результаты анализа планируется использовать в публичных отчётах.
Чем rea отличается от Ghidra или IDA Pro
Ghidra и IDA Pro — это традиционные дизассемблеры и декомпиляторы: они показывают вам машинный код и ждут, пока вы сами разберётесь в его логике. rea работает иначе — он не требует от вас глубоких знаний ассемблера, а вместо этого запускает цепочку ИИ-агентов, которые сами проходят путь от сбора метаданных до построения высокоуровневого описания поведения. Если Ghidra скажет вам «вот эта функция вызывает socket, bind, listen», rea сразу скажет «программа открывает TCP-сервер на порту 8080». Это не замена классическим инструментам, а дополнение: rea даёт быстрый обзирательский анализ, после чего вы можете переключиться на Ghidra или IDA для глубокого погружения в критические функции.
Как rea справляется с запакованными или обфусцированными бинарниками
С пакировкой и обфускацией у rea дела обстоят неоднозначно. ИИ-агенты хорошо справляются с лёгкой обфускацией и простыми упаковщиками, так как опираются на динамическое поведение, а не только на статический код. Однако если бинарник упакован сильным упаковщиком вроде UPacker или VMProtect, или использует техники антиотладки, агенты могут получить искажённые логи или вовсе не запустить целевой файл. В таких случаях rea выдаст отчёт с пометкой о возможной упаковке и посоветует сначала распаковать бинарник вручную. Для защищённых приложений традиционная схема остаётся актуальной: сначала ручная распаковка в Ghidra или с помощью специализированных утилит, затем уже запуск rea на распакованном файле.