Продвинутый

REAE: реинжиниринг через агентов

Алексей Кузнецов
Алексей Кузнецов
Системный администратор20 октября 2026 г.12 мин чтения

Инструмент REAE применяет ИИ-агентов для реинжиниринга: от анализа поведения приложений до разбора нативных бинарников. Разбираемся, как это работает и зачем...

REAE: реинжиниринг через агентов

Инструмент REAE применяет ИИ-агентов для реинжиниринга: от анализа поведения приложений до разбора нативных бинарников. Разбираемся, как это работает и зачем нужно.

Что такое REAE и зачем он нужен

Архитектура ИИ-агентов в реинжиниринге

REAE строится вокруг идеи, что реинжиниринг — это не разовая выгрузка бинарника в декомпилятор, а диалог с системой. Каждый агент отвечает за свой слой: один ловит сетевые вызовы, другой — трассировку системных вызовов, третий — поведение в памяти. Они не работают последовательно, а параллельно, как команда инженеров, которая одновременно копает в логах, смотрит трафик и проверяет состояние процессов.

Агент поведения приложения стартует с простого: запускает целевой бинарник в изолированном окружении и наблюдает. В моей практике на домашних серверах это выглядит так:

bash
# Запуск в контейнере с ограничением сети и доступом к ptrace
docker run --rm --cap-add SYS_PTRACE --security-opt seccomp=unconfined \
  --network none -v /tmp/reae-trace:/trace \
  reae-target:1.0

Агент перехватывает ptrace, ловит strace, а также снимки с gdb — всё это кормится в LLM с подсказкой типа «выяви паттерн инициализации конфигурации». Результат не просто лог — а структурированный вывод: какие файлы открываются, в каком порядке, какие переменные окружения влияют.

Слой анализа бинарника работает уже с нативным кодом. Здесь используется agent-skills для последовательного вызова декомпиляторов, дизассемблеров и сигнатурных сканеров. Пример конфигурации агента:

yaml
# .reae/agents/binary-analyzer.yaml
name: binary-analyzer
skills:
  - disassembly: ghidra
  - decompilation: retdec
  - signature_match: yara
  - control_flow: radare2
orchestrator: claude-code

Каждый навык — это отдельный вызов, и агент решает, какие из них применить в зависимости от архитектуры и типа бинарника. Если Ghidra возвращает мусор из-за оптимизаций компилятора — агент автоматически переключается на Radare2 и пробует другой подход.

Сравнение с традиционными декомпиляторами

Традиционные декомпиляторы — это как одноразовый фотоаппарат: вставил бинарник — получил листинг. Ghidra, RetDec, IDA Pro отлично справляются с чистым x86/x64, но ломаются на оптимизированном ARM-коде или при наличии антиотладочных приёмов.

REAE подходит иначе. Он не пытается сразу разобрать весь бинарник. Сначала агенты поведения выявляют, какие функции реально важны — например, только те, что задействованы в обработке конфигурационных файлов. Затем к декомпиляции применяются только к этим функциям, а не ко всему объёму.

Вот как это выглядит на практике. Допустим, нужно понять, как старый бинарник config_loader парсит JSON-файлы. Традиционный подход:

bash
# Ghidra: полный дизассемблинг
ghidra -import config_loader -postScript ExportFunctionNamesPcode.java

Получается тысячи строк, большинство из которых — шаблонные функции libc. REAE же действует целенаправленно:

bash
# REAE: поведенческий анализ + целевой декомпилятор
reae analyze config_loader --focus config_parsing --agent binary-analyzer

Агент поведения сначала определяет, что интересует именно работа с файлами, затем передаёт список адресов функций в декомпилятор. Результат — не 5000 строк, а 200 строк чистого кода с комментариями агента о том, где обнаружена логика валидации.

С практической точки зрения, это экономит часы ручной работы. Особенно когда речь о нативных бинарниках под ARM, где Ghidra часто путает регистры. Здесь REAE не заменяет декомпилятор — он даёт ему понять, что именно нужно разобрать.

Связанные подходы можно увидеть в Ponytail: ИИ-агент пишет меньше кода и Graphify: knowledge graph для кода, где ИИ тоже используется не как замена, а как уточнение задачи.

Установка и настройка среды

Зависимости и системные требования

REAE требует Python 3.10+ и работает с любым современным дистрибутивом Linux. На практике я запускал его на Debian 12 и Ubuntu 22.04 — обе системы дают одинаково предсказуемое поведение.

Самая важная зависимость — наличие gcc и binutils в системе. Без них агент не сможет компилировать промежуточные артефакты во время разбора бинарников. Убедиться, что всё установлено, можно одной командой:

bash
sudo apt install build-essential python3-pip python3-venv

Для работы с нативными бинарниками понадобится radare2 или Ghidra. Я предпочитаю radare2 — легче встраивается в пайплайн, а API отвечает тем же принципам, что и у REAE: минимум абстракций, максимум контроля.

bash
sudo apt install radare2

Объём оперативной памяти должен быть не менее 8 ГБ. ИИ-агенты жрут память, особенно когда одновременно анализируют несколько функций в бинарнике. На 4 ГБ у меня падало на этапе декомпиляции большого ELF-файла в прошлый раз.

Конфигурация CLI-интерфейса

После установки пакета через pip создаём виртуальное окружение и активируем его:

bash
python3 -m venv ~/.reae-env
source ~/.reae-env/bin/activate
pip install reae

Основной конфиг лежит в ~/.config/reae/config.yaml. Минимальная версия выглядит так:

yaml
# ~/.config/reae/config.yaml
agents:
  analyzer:
    model: claude-3-5-sonnet-20241022
    api_key: ${ANTHROPIC_API_KEY}
  decompiler:
    model: gpt-4o
    api_key: ${OPENAI_API_KEY}

storage:
  path: ~/reae-workspace
  max_size_gb: 50

logging:
  level: info
  format: json

Переменные окружения ANTHROPIC_API_KEY и OPENAI_API_KEY удобно хранить в ~/.bashrc или использовать менеджер секретов. Я предпочитаю pass — простенько, но надёжно:

bash
export ANTHROPIC_API_KEY=$(pass show api/anthropic | head -n1)
export OPENAI_API_KEY=$(pass show api/openai | head -n1)

Запуск агента происходит через CLI с указанием цели. Например, чтобы проанализировать бинарник:

bash
reae analyze --target ./myapp.bin --output ./report.md

Агент сам разберёт структуру файла, выделит функции, попытается восстановить логику и сгенерирует markdown-отчёт. Всё без вашего участия — как положено настоящему агенту.

Если нужно переключиться на другую модель или изменить параметры хранилища — правите config.yaml. REAE не требует перезапуска сервиса: конфиг читается при каждом запуске. Это удобно, когда экспериментируете с разными провайдерами ИИ.

Стоит обратить внимание на секцию storage.path — именно туда агент складывает промежуточные артефакты: дизассемблированный код, графы вызовов, логи. Указывайте путь на том же разделе, где есть место. На моём сторадже с ZFS это ~/reae-workspace на отдельном датасете с снапшотами — на всякий случай.

Анализ поведения приложений

Отслеживание вызовов функций и API

Когда я впервые столкнулся с необходимостью понять, почему старое приложение начало падать в проде, у меня не было ни логов, ни доступа к исходникам. Был только бинарник и сотни вызовов API в минуту. REAE решает эту задачу системно: агент подключается к процессу через ptrace или eBPF, перехватывает вызовы функций и API на лету, а затем интерпретирует их в контексте бизнес-логики.

Вот как это выглядит на практике. Допустим, у вас есть приложение, которое работает с PostgreSQL и Redis. REAE-агент может отследить цепочку вызовов:

bash
reae trace --pid 12345 --hooks "postgres*,redis*,malloc,free"

Агент не просто ловит сырые вызовы — он знает, что PQexec из libpq означает SQL-запрос, а redisCommand — обращение к кешу. Это как если бы вы взяли strace, но дали ему мозги:

c
// Что видит обычный strace
[pid 12345] sendto(3, "SELECT * FROM users WHERE id=42", 34, ...)

// Что видит REAE-агент
[agent] Function call: PQexec(conn=0x7f8b4c0008c0, query="SELECT * FROM users WHERE id=42")
[agent] Context: user_authentication_handler -> database_lookup
[agent] API call: Redis GET session:abc123 -> cache_miss

С практической точки зрения, это меняет подход к отладке. Вместо того чтобы гадать, где запрос тормозит, вы сразу видите: «О, PQexec длится 8 секунд, а перед ним был cache_miss в Redis».

Конфиг агента для отслеживания можно задать в YAML:

yaml
# .reae/agents/trace-agent.yaml
hooks:
  - name: database-tracer
    library: libpq.so
    functions:
      - PQexec
      - PQexecParams
      - PQconnectdb
    callback: log_with_context
  - name: cache-tracer
    library: libhiredis.so
    functions:
      - redisCommand
      - redisGet
    callback: annotate_with_business_logic
annotations:
  user_authentication_handler:
    maps_to: "auth_service"
  database_lookup:
    depends_on: ["postgres", "redis"]

Здесь важно не просто ловить вызовы, а понимать их смысл. Агент знает, что PQexec в контексте user_authentication_handler — это не просто SQL, а критически важный путь аутентификации.

Интерпретация логов агентов

Отслеживание без интерпретации — это как иметь тысячу строк strace без понятия, что происходит. Здесь REAE действительно выделяется: агенты не просто пишут логи, они анализируют паттерны поведения и строят модель выполнения.

Представьте, что вы запустили трассировку на приложении, которое периодически зависает. Агент фиксирует не только вызовы, но и время между ними, состояние потоков, блокировки:

bash
reae analyze --log /var/log/reae/trace-2024-04-15.log --pattern "deadlock|timeout|slow_query"

Результат — не сухой отчёт, а интерпретированная карта поведения:

[agent] Pattern detected: sequential_db_lock
  - Thread 1 acquires lock on table 'sessions' at 14:23:01.002
  - Thread 2 waits for same lock at 14:23:01.005 (wait time: 3.2s)
  - Thread 1 releases lock at 14:23:04.210
  - Thread 2 acquires lock at 14:23:04.211
  - Impact: request_timeout on /api/v1/auth (HTTP 504)

[agent] Root cause hypothesis: missing index on sessions.user_id
  - Evidence: 92% of lock wait time correlates with high-cardinality SELECT
  - Recommendation: CREATE INDEX CONCURRENTLY idx_sessions_user_id ON sessions(user_id)

Это работает потому, что агент понимает контекст. Он не просто видит futex и pthread_mutex_lock — он знает, что это блокировка, и может сопоставить её с бизнес-операцией.

Для хранения и последующего анализа логи агентов можно отправлять в Loki:

yaml
# .reae/agents/log-agent.yaml
output:
  format: json
  fields:
    - timestamp
    - agent_id
    - event_type
    - context
    - payload
  destination:
    type: loki
    url: http://loki:3100/loki/api/v1/push
    labels:
      job: reae-tracing
      environment: production

А затем запросить в Grafana:

logql
{job="reae-tracing"} | json | event_type="pattern_detected" | pattern="sequential_db_lock"

Интерпретация логов — это где ИИ-агенты действительно оправдывают своё существование. Как использовать VoltAgent для генерации UI показывает, как агенты могут работать не только с бэкендом, но и с интерфейсом. А Ponytail: ИИ-агент пишет меньше кода демонстрирует, как агенты могут автоматизировать рутину, оставляя инженеру только принятие решений.

Когда агент видит, что malloc вызывается 10 000 раз в секунду, а через 200 мс последовывает free — это не просто утечка памяти, это утечка памяти в горячем цикле обработки запросов. И такие выводы агент делает не на основе правил, а на основе анализа поведения системы в целом.

Разбор нативных бинарников

Дизассемблирование и статический анализ

Когда мне нужно разобраться, что делает бинарник, с которым я никогда не сталкивался, я не сразу запускаю его. Сначала посмотрю на структуру — как автомобилист, который открывает капот, а не садится за руль.

REAE использует agent-skills для координации нескольких ИИ-агентов: один разбирает символы, другой — секции ELF, третий ищет строки и вызовы функций. Это как если бы три коллеги одновременно читали разные главы одной книги и потом обсуждали выводы.

Вот типичный запуск статического анализа:

bash
reae analyze --binary ./app.bin --mode static --output ./report.json

Агенты последовательно:

  1. Извлекают метаданные: тип компилятора, используемые библиотеки, символы (если не стripped).
  2. Декомпилируют в pseudocode с помощью встроенного Ghidra-%D0%BF%D0%BE%D0%B4%D0%BE%D0%B1%D0%BD%D0%B8%D0%BA%D0%B0.
  3. Строят граф вызовов функций и выделяют «горячие точки» — те, ктоа вызываются чаще всего.

Пример вывода в report.json:

json
{
  "binary_type": "ELF 64-bit LSB executable, x86-64",
  "compiler": "GCC: 11.4.0",
  "libraries": ["libc.so.6", "libssl.so.3"],
  "functions": [
    {
      "name": "main",
      "address": "0x401000",
      "calls": ["init_ssl", "parse_args", "run_server"],
      "complexity": 12
    }
  ]
}

С практической точки зрения, статический анализ даёт предсказуемость: вы знаете, какие зависимости задействованы, и можете сразу увидеть, например, что приложение линкуется с libssl, но не использует pthread. Это уже подсказка — возможно, сервер однопоточный, или работает через epoll.

Динамический анализ с использованием агентов

Статика — это как чтение инструкций в руководстве. Динамика — это наблюдение за тем, как человек реально пользуется этим устройством. ИИ-агенты REAE запускают бинарник в изолированной среде (обычно через Firejail или Bubblewrap), подменяют системные вызовы и записывают всё: сетевые соединения, открытые файлы, сигналы.

Команда выглядит так:

bash
reae analyze --binary ./app.bin --mode dynamic --sandbox firejail --trace-syscalls --output ./trace.json

Агенты тут работают поэтапно:

  • Агент-наблюдатель ловит все strace-события: connect, openat, execve.
  • Агент-интерпретатор сопоставляет системные вызовы с поведением: «приложение пытается подключиться к 127.0.0.1:8080 — значит, это клиент или сервер».
  • Агент-проверяющий сравнивает поведение с типичными паттернами: если вижу bind + listen + accept — это сервер.

Пример фрагмента трассировки:

json
{
  "events": [
    {
      "syscall": "socket",
      "args": {"domain": "AF_INET", "type": "SOCK_STREAM"},
      "result": "fd=3"
    },
    {
      "syscall": "bind",
      "args": {"fd": 3, "addr": "127.0.0.1:8080"},
      "result": "0"
    },
    {
      "syscall": "listen",
      "args": {"fd": 3, "backlog": 128},
      "result": "0"
    }
  ]
}

Здесь уже понятно без запуска: это сетевой сервис, слушающий localhost:8080. А если далее в трассировке появится accept — значит, работает в блокирующем режиме. Если вместо этого я увижу epoll_wait — скорее всего, используется libevent или подобная библиотека для асинхронного ввода-вывода.

Мне кажется, это похоже на работу в техподдержке: сначала вы слышите жалобу (статический анализ), потом наблюдаете, как пользователь пытается решить проблему (динамический анализ). Оба взгляда вместе дают полную картину.

Если хотите копнуть глубже — вот как использовать VoltAgent для генерации UI под брендовый дизайн, а если интересует, как ИИ-агенты пишут код — смотрите Ponytail: ИИ-агент пишет меньше кода.

Часто задаваемые вопросы

Что делает REAE иначе классических декомпиляторов вроде Ghidra или IDA Pro

Классические декомпиляторы работают с тем, что видно в бинарнике: инструкции, таблицы импортов, структура секций. REAE добавляет к этому динамику — он запускает программу, наблюдает, как она себя ведёт, и только потом сопоставляет поведение с кодом. Это как разница между тем, чтобы просто расшифровать чертёж, и запустить устройство, посмотреть, как оно работает, и уже затем понять, зачем каждая деталь на месте.

Можно ли запустить REAE на обычном ноутбуке или нужен отдельный сервер

Можно, но с оговорками. Агенты используют LLM для анализа, и это требует вычислительных ресурсов — особенно если речь о больших бинарниках или длительных сессиях трассировки. На ноутбуке с 16 ГБ ОЗУ и без выделенной видеокарты REAE справится с небольшими утилитами или учебными примерами, но для серьёзного реинжиниринга лучше выделить отдельную машину или контейнер с доступом к GPU.

Как REAE справляется с обфускацией и упаковкой бинарников

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

Требует ли REAE доступа к исходному коду целевого приложения

Нет, REAE работает исключительно с бинарниками и их поведением во время выполнения. Исходный код не нужен — достаточно исполняемого файла, библиотек и конфигурационных файлов. Это делает инструмент пригодным для аудита чужих приложений, анализа устаревших утилит без документации или изучения закрытого ПО.

Можно ли использовать REAE для анализа вредоносного кода

Технически да, но это требует особой осторожности. REAE запускает целевой бинарник в изолированном окружении, но если вредонос использует эксплойты ядра или побегает из контейнера, защита может не сработать. Для анализа подозрительных образцов нужно дополнительно настраивать sandbox на уровне гипервизора, ограничивать доступ к сети и оборудованию, а также использовать выделенную машину, которую можно сбросить после каждого запуска.

Поделиться:TelegramX / TwitterVK

Читайте также