Skip to content
KitploitKITPLOIT
ИнструментыЭксплойтыБлог
Log in
Отправить
ИнструментыЭксплойтыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

ЛентыКонтактыКонфиденциальность© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
aotopsy — Статический анализатор AOT-снимков Flutter/Dart — восстанавливает имена функций, иерархии классов, графы вызовов и поведенческие сигналы из libapp.so без встраивания или выполнения Dart VM. Поддерживает ARM64 и x86_64, Dart 2.10–3.12. | Kitploit
Инструменты/GitHubGitHub/bronils/aotopsy
Статический анализПентестинг мобильных приложенийОбратная инженерияМобильная безопасностьАнализ Бинарных Файлов
GitHubbronils/aotopsy

aotopsy

Статический анализатор AOT-снимков Flutter/Dart — восстанавливает имена функций, иерархии классов, графы вызовов и поведенческие сигналы из libapp.so без встраивания или выполнения Dart VM. Поддерживает ARM64 и x86_64, Dart 2.10–3.12.

Репозиторий
41111111 месяц назадПроверено Kitploit

Популярное

Смотреть все →

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

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться
# AOTopsy

[![CI](https://github.com/BroNils/aotopsy/actions/workflows/ci.yml/badge.svg)](https://github.com/BroNils/aotopsy/actions/workflows/ci.yml)
[![Release](https://img.shields.io/github/v/release/BroNils/aotopsy?sort=semver)](https://github.com/BroNils/aotopsy/releases)
[![License](https://img.shields.io/badge/license-BSD--3--Clause-blue.svg)](LICENSE)

Анализатор AOT-снимков Dart. Превращает `libapp.so` — скомпилированный код Dart внутри release-APK Flutter — в имена функций, структуры классов, графы вызовов, поведенческие сигналы и читаемый псевдокод. Без Dart VM, без компиляции SDK, без резервного выполнения во время работы.

> **Уведомление о форке:** AOTopsy — это форк **unflutter**, изначально созданного **Anthony Zboralski**. Исходный репозиторий `zboralski/unflutter` больше недоступен (удалён автором); продолжение сообщества существует по адресу [`KristijanZic/unflutter`](https://github.com/KristijanZic/unflutter). Все заслуги за исходный парсер снимков, десериализатор кластеров, конвейер дизассемблирования ARM64 и интеграцию с Ghidra/IDA принадлежат оригинальному автору. AOTopsy расширяет его поддержкой x86_64, собственным декомпилятором, выводом типов для всей программы, генерацией скриптов Frida и подробной документацией.

## Что восстанавливается

| Выходные данные | Что это |
|--------|-----------|
| Имена функций | Исходное имя Dart для каждой скомпилированной функции |
| Структуры классов | Имена полей, байтовые смещения, цепочки наследования |
| Граф вызовов | Прямые (BL) и косвенные (BLR/dispatch) рёбра вызовов с указанием происхождения |
| Ссылки на строки | Какие функции загружают какие строковые литералы из пула объектов |
| Поведенческие сигналы | Классификация по ключевым словам: криптография, сеть, азартные игры, SIM, местоположение, WebView, блокчейн |
| Псевдокод | Декомпилированный вывод, независимый от архитектуры, из машинного кода ARM64 или x86_64 |
| Экспорт исходного кода Dart | Модульные файлы `.dart` для всего проекта, восстановленные с классами, полями и методами |

Поддерживаются **ARM64** и **x86_64**. Охватывает **Dart 2.10–3.13** (3.13.2 — текущий стабильный рубеж) — каждая смоделированная версия разбирается без ошибок на обеих архитектурах, см. [COVERAGE.md](https://github.com/bronils/aotopsy/blob/main/COVERAGE.md) (93 образца сборок, 0 сбоев).

## Точность и честность

AOTopsy измеряется относительно эталонных данных, а не декларируется. Два свойства проверяются
набором тестов при каждом изменении:

| Метрика | Значение | Что это означает |
|--------|-------|---------------|
| **Согласованность восстановления имён** | **90,2%** в целом (81,3% худший диапазон, порог ≥ 0,81) по 44 эталонным сборкам | Восстановленные имена функций сравниваются с собственным ELF `.symtab` каждой сборки — внешним эталоном — `TestSymtabDifferential`. Полная таблица по сборкам: [BENCHMARK.md](https://github.com/bronils/aotopsy/blob/main/BENCHMARK.md) (`make bench`). |
| **Синтаксическая корректность декомпилятора** | **100%** корректный Dart | Каждая выданная функция псевдокода разбирается как Dart — `TestDecompileQualityCorpus`. |
| **Доля выдуманных данных** | **0%** | Правило §2: никогда не выдавать угаданное имя, тип или цель вызова за факт. Неизвестные значения отображаются честно (`indirectCall`, `<unknown>`, `dynamic`). |

Эталонные двойники — это реальные production-сборки, которые мы не можем распространять, поэтому эти
дифференциальные проверки выполняются **локально**; публичный CI проверяет сборку, vet, `gofmt`,
`staticcheck`, модульные тесты (в перемешанном порядке) и минимальный порог покрытия по матрице
платформ. `samples/` не подлежит распространению и добавлен в gitignore, поэтому зависящие от образцов
тесты там пропускаются — но только когда корпус полностью отсутствует; корпус, который
присутствует, но не содержит зарегистрированного образца, приводит к сбою, потому что это означает противоположные
вещи. Как измеряется каждое число здесь (эталонные данные, определения метрик, воспроизведение): [METHODOLOGY.md](https://github.com/bronils/aotopsy/blob/main/METHODOLOGY.md). См.
[SECURITY.md](https://github.com/bronils/aotopsy/blob/main/SECURITY.md) для проверки release-бинарников и честного описания области применения ниже.

## Быстрый старт

```bash
make build
./aotopsy libapp.so                    # full pipeline
./aotopsy doctor libapp.so             # quick diagnostic
./aotopsy export-dart --lib libapp.so --out ./lib  # reconstruct entire Dart source project
./aotopsy _debug decompile-native --lib libapp.so --find MyClass  # find and decompile a function
```

См. [DEMO.md](https://github.com/bronils/aotopsy/blob/main/DEMO.md) — пятиминутное пошаговое руководство на реальном снимке, или `WORKFLOW.md` — пошаговую методологию на случай, когда у вас есть необработанный APK и вы не знаете, с чего начать.

## Как это работает

AOTopsy рассматривает снимок Dart AOT как детерминированную бинарную грамматику. Каждый байт имеет ровно одну правильную интерпретацию при наличии правильных ограничений (структура ELF, магия снимка, хеш версии, таблица CID, кодировка кластера). Парсер применяет ограничения до тех пор, пока не останется только одна интерпретация — никаких эвристик, никаких догадок.

Конвейер выполняется поэтапно, каждый этап — чистая функция от байтов к структурированным данным:

```mermaid
flowchart TD
    A[libapp.so] --> B[ELF parse]
    B --> C[snapshot region extraction]
    C --> D[version detection]
    D --> E[cluster alloc<br/>object census]
    E --> F[cluster fill<br/>field values, names, strings]
    F --> G[instructions table<br/>code ranges, stub boundaries]
    G --> H{architecture?}
    H -->|ARM64| I[ARM64 disassembly]
    H -->|x86_64| J[x86_64 disassembly]
    I --> K[CFG + call edges<br/>register provenance]
    J --> K
    K --> L[type inference<br/>BLR receiver type resolution]
    L --> M[signal classification<br/>behavioral keyword matching]
    M --> N[JSONL + HTML + DOT<br/>pseudocode output]
```

Два независимых бэкенда используют одну и ту же первую половину (ELF до заполнения кластера), затем разделяются по архитектуре: `internal/disasm` для ARM64, `internal/disasm/x86.go` для x86_64. Декомпилятор (`internal/decompiler`) обрабатывает обе архитектуры через единый IR.

```mermaid
flowchart LR
    subgraph "Shared front half"
        A[elfx] --> B[snapshot]
        B --> C[cluster]
    end
    subgraph "ARM64 backend"
        C --> D1[disasm ARM64]
        D1 --> E1[callgraph]
        E1 --> F1[signal]
    end
    subgraph "x86_64 backend"
        C --> D2[disasm x86_64]
        D2 --> E2[callgraph]
        E2 --> F2[signal]
    end
    subgraph "Decompiler (both archs)"
        C --> G[decompiler IR]
        G --> H[pseudocode]
    end
```

## Сравнение с Blutter

```mermaid
flowchart LR
    subgraph Blutter
        direction TB
        B1[libapp.so] --> B2[Compile matching<br/>Dart SDK]
        B2 --> B3[Embed Dart VM]
        B3 --> B4[Deserialize via<br/>VM internal APIs]
        B4 --> B5[Perfect fidelity]
    end
    subgraph AOTopsy
        direction TB
        A1[libapp.so] --> A2[Parse binary format<br/>directly]
        A2 --> A3[No VM, no SDK]
        A3 --> A4[Version-specific<br/>format modeling]
        A4 --> A5[Portability + speed]
    end
```

[Blutter](https://github.com/worawit/blutter) встраивает Dart VM для десериализации снимка через собственные пути кода. Идеальная точность, но требует компиляции соответствующего Dart SDK для каждой целевой версии — и поддерживает только ARM64, без статической поддержки x86_64. AOTopsy — единственный статический, независимый от версии анализатор с нативным декомпилятором псевдокода и опубликованной точностью относительно эталонных данных.

AOTopsy разбирает бинарный формат напрямую. Без VM, без SDK. Компромисс: каждое изменение формата между версиями Dart должно моделироваться явно. Нет среды выполнения, которая обработала бы это автоматически.

## Команды

### Полный конвейер

```bash
aotopsy libapp.so              # disasm + call edges + signal + metadata (ARM64: + Ghidra/IDA)
aotopsy signal libapp.so       # same, skip metadata
aotopsy libapp.so --graph      # also build call graph DOT files
```

Флаги: `--out <dir>` (по умолчанию: `<basename>.aotopsy/`), `--quiet`, `--strict`, `--max-steps <n>`, `--k <n>` (глубина контекста сигнала, по умолчанию 2), `--decompile`.

`--decompile` записывает псевдокод Dart для каждой функции в `<out>/dart/`. По умолчанию он отключён, поскольку примерно утраивает размер выходного каталога; каждый запуск без него сообщает об этом, так что возможность можно обнаружить, а не просто она присутствует.

### Диагностика

```bash
aotopsy doctor libapp.so       # Dart version, pointer size, support status, build features
aotopsy find-libapp --apk app.apk  # locate libapp.so inside an APK
```

### Экспорт исходного кода Dart всего проекта

Восстанавливает все классы, поля, методы, геттеры, сеттеры и конструкторы в модульные файлы `.dart`, сопоставленные с исходными URI библиотек:

```bash
aotopsy export-dart --lib libapp.so --out ./reconstructed_lib/   # full project export
aotopsy export-dart --lib libapp.so --out ./lib/ --app-only      # filter out core/flutter framework
aotopsy export-dart --lib libapp.so --out ./lib/ --filter Auth   # targeted export by name
```

### Высокоуровневый нативный декомпилятор (ARM64 + x86_64)

Создаёт чистый, идиоматичный код Dart непосредственно из машинных инструкций бинарного файла:
- **Структурный поток управления**: итераторы `for-in`, `while`, `for`, `try-catch-finally` с точной привязкой к PC.
- **Линеаризация Async/Await**: разворачивает конечные автоматы `_SuspendState` в линейные `await future` и `await for`.
- **Встраивание лямбд**: синтезирует стрелочные колбэки `(item) => process(item)` непосредственно в местах вызова.
- **Решётка типов**: распространяет конкретные типы Dart (`String`, `int`, `UserModel`) по SSA-значениям без запуска живой VM.
- **Идиомы Dart**: null-aware (`?.`, `??`, `??=`), каскад (`..`), литералы Set/List/Map, строковая интерполяция (`"${a}${b}"`).

```bash
aotopsy _debug decompile-native --lib libapp.so --find MyClass         # locate by name
aotopsy _debug decompile-native --lib libapp.so --func 0x1a92728       # one function at a VA
aotopsy _debug decompile-native --lib libapp.so --from-main --out out/ # reachability from app entry
aotopsy _debug decompile-native --lib libapp.so --all --filter MyClass # bulk, filtered
```

Предупреждение: `--all` без небольшого `--max` может потребовать ~64 ГБ ОЗУ на реальном приложении. Предпочитайте `--find`/`--func`/`--from-main`.

### Ghidra / IDA (только ARM64)

```bash
aotopsy ghidra libapp.so        # headless Ghidra with metadata injection
aotopsy ida libapp.so           # headless IDA via idalib
```

Оба отклоняют входные данные x86_64. Используйте `decompile-native` для псевдокода x86_64.

### Генерация скриптов Frida

```bash
aotopsy _debug decompile-native --lib libapp.so --func 0x1a92728 --gen-frida --gen-frida-out hooks.js
frida -U -f com.example.app -l hooks.js --no-pause
```

Полное руководство см. в `FRIDA.md`.

### Перекрёстные ссылки и трассировка

```bash
aotopsy _debug strings --lib libapp.so --find "X-Signature" --xref   # which function loads this string?
aotopsy _debug ffi-trace --lib libapp.so --filter MyClass            # dart:ffi call sites
aotopsy _debug dispatch-table --lib libapp.so --filter MyClass       # dispatch table entries
aotopsy _debug fingerprint --lib libapp.so                           # build-id and version markers
aotopsy _debug funcdiff --old old.so --new new.so                    # function set diff
aotopsy _debug symbolmap --stripped lib.so --unstripped debug.so     # resolve stripped targets
```

### Инструменты для работы с корпусом

```bash
aotopsy inventory --dir samples/                    # catalog APKs
aotopsy parity --samples samples/ --out out/        # cross-version parse report
aotopsy _debug thr-audit -lib libapp.so -out thr.jsonl  # THR access scan
```

## Выходные артефакты

| Файл | Содержимое |
|------|----------|
| `functions.jsonl` | Имя, адрес, размер, владелец, количество параметров для каждой функции |
| `call_edges.jsonl` | Рёбра BL/BLR с разрешёнными целями и происхождением |
| `classes.jsonl` | Имена полей, смещения, размеры экземпляров для каждого класса |
| `string_refs.jsonl` | Ссылки на строки из загрузок пула объектов |
| `dispatch_table.jsonl`| Выведенные типы получателей таблицы диспетчеризации и отображение целей |
| `signal.html` | Отчёт о поведенческих сигналах с графом контекста |
| `dart_meta.json` | Метаданные снимка, флаг сжатых указателей, раскладка THR |
| `flutter_meta.json` | Унифицированные метаданные для Ghidra/IDA (только ARM64) |
| `aotopsy.sarif` | Отчёт о находках безопасности в формате SARIF 2.1.0 (для GitHub Code Scanning) |
| `evidence.jsonl` | Унифицированная модель доказательств с уровнем достоверности и происхождением для каждого места вызова |
| `asm/*.txt` | Аннотированный дизассемблированный код для каждой функции |
| `asm/*.bin` | Необработанные байты инструкций для каждой функции (обе архитектуры) |
| `dart/*.dart` | Декомпилированный псевдокод для каждой функции (с `--decompile`) |
| `cfg/*.dot` | CFG для каждой функции (с `--graph`) |

## Структура пакета

```
cmd/aotopsy/          CLI entry point and command handlers
internal/
  analysis/           Pipeline orchestration, snapshot loader, and analysis engines
  sdk/                Dart VM ground-truth facts, register mappings, and predicates
  vmtables/           Versioned THR field offsets, stub names, and stub orders
  thraudit/           Thread-relative memory access audit and classification
  arch/arm64/         Centralized ARM64 bitmask instruction decoders
  arch/x86/           Centralized x86_64 decode primitives and register helpers
  naming/             Central pool lookups, name resolution, and stub builders
  elfx/               ELF validation and symbol extraction
  snapshot/           Snapshot region extraction, version profiles
  dartfmt/            Dart VM variable-length integer encoding
  cluster/            Two-phase snapshot deserialization (alloc + fill)
  disasm/             ARM64 + x86_64 decode, CFG, call-edge provenance
  callgraph/          Call graph construction and DOT rendering
  signal/             Behavioral string and malware signal classification
  render/             HTML/DOT/SVG visualization
  output/             JSONL and SARIF 2.1.0 serialization
  decompiler/         Dart-AOT pseudocode decompiler (both architectures)
  typetrack/          Whole-program type inference and receiver recovery
  fingerprint/        Build-id and version marker identification
  funcdiff/           Function-set diffing between builds
  symbolmap/          Stripped-vs-unstripped symbol resolution
  ffitrace/           Static dart:ffi call-site tracing
  strxref/            String-to-function cross-referencing
  strutil/            Dart syntax sanitization and metadata serialization
  jsonutil/           Generic JSONL stream readers and writers
  evidence/           Unified evidence model with confidence and provenance
  frida/              Frida runtime hook and probe generation
  cli/                ANSI color helpers for CLI output
tools/                Standalone utilities (THR table extractor and validator)
ghidra_scripts/       Ghidra integration (Python)
ida_scripts/          IDA integration (Python)
```

См. `ARCHITECTURE.md` для подробного описания каждого пакета.

## Сборка

Требуется Go 1.25+.

```bash
make build      # build ./aotopsy
make install    # install to ~/.aotopsy/bin, plus the Ghidra/IDA integration
                # assets into ~/.aotopsy/ghidra_scripts and ~/.aotopsy/ida_scripts
make test       # run tests
make bench      # regenerate BENCHMARK.md (needs local ground-truth twins)
make coverage   # regenerate COVERAGE.md (needs local corpus samples)
make analyze    # cross-check export-dart output against `dart analyze`
```

Интеграционные тесты берут входные данные из `internal/samplecorpus`, который ищет каталог `samples/`; настраивать ничего не нужно. `samples/` указан в gitignore, поэтому при checkout без него эти тесты пропускаются — но если в checkout *есть* корпус и в нём отсутствует зарегистрированный образец, тест падает, потому что рассинхронизированный корпус и отсутствующий корпус означают разные вещи.

Публичный CI запускает `gofmt`, `staticcheck`, сборку, vet и перемешанные юнит-тесты на linux/amd64, darwin/arm64 и windows/amd64, а также задание race+coverage с минимальным порогом покрытия.

## Релизы и ветки

AOTopsy использует модель с двумя ветками:

| Ветка | Роль |
|--------|------|
| `main` | **Стабильная.** Каждый коммит — это прошедший проверки релизный кандидат, влитый через squash-merge. Отсюда выпускаются тегированные релизы (с готовыми кроссплатформенными бинарниками). |
| `develop` | **Текущая / ночная.** Здесь в первую очередь появляются повседневные мелкие коммиты, функции и исследования. Может быть нестабильной между слияниями. Пакетно вливается в `main` через PR со squash-merge, как только проверки зелёные. |

Вносите изменения в `develop`; открывайте PR в `main` только когда пакет работы прошёл проверки.

Готовые бинарники для Linux, macOS и Windows (amd64/arm64) прикреплены к каждому
[релизу на GitHub](../../releases). AOTopsy написан на чистом Go, поэтому `make build` без проблем кросс-компилируется под любую цель.
Каждый архив релиза также содержит `ghidra_scripts/` и `ida_scripts/` рядом с
бинарником — именно такую структуру ищут `aotopsy ghidra` и `aotopsy ida`, поэтому эти
команды работают прямо из распакованной загрузки, без необходимости в checkout.

## Ограничения и область применения

AOTopsy честно указывает, что он восстанавливает, а что нет. Часть ограничений — это
инженерная область охвата; другие — **жёсткие ограничения формата AOT** — информация, которую компилятор Dart удаляет в
release-сборках (PRODUCT), проверено по исходникам SDK. Мы документируем ограничения, а не выдумываем поверх них.

**Жёсткие ограничения AOT (проверено — не ожидайте улучшений):**
- **Имена полей экземпляров отсутствуют на ~97–99%.** `Precompiler::DropFields` сохраняет имена полей
  только под `#if !defined(PRODUCT)`; в реальном приложении ~233 именованных объектов `Field` против
  ~16k синтетических. Восстановление через аксессоры (`get:`/`set:` всё ещё несут имя) пробивает
  это частично (−11–22%, детерминированно, без угадывания); остальное действительно утрачено.
- **Имена локальных и захваченных переменных утрачены.** Отображаются как `local_*` / `tN`.
- **Истинно полиморфные цели диспетчеризации статически не разрешимы.** BLR через
  таблицу диспетчеризации / динамический объект `Closure` — это ограничение AOT, а не пробел в анализе; они
  честно отображаются как `indirectCall` / `dynamicCall`. См. [METHODOLOGY.md](https://github.com/bronils/aotopsy/blob/main/METHODOLOGY.md#limits-of-this-method-honestly).

**Инженерная область охвата:**
- **Только AOT.** Поддержки JIT нет.
- **Декомпиляция Ghidra/IDA только для ARM64.** x86_64 отклоняется с понятной ошибкой — используйте вместо этого `decompile-native` (единственный статический декомпилятор Flutter для x86_64).
- **Декомпиляция `--all` может уронить хост.** Реальному приложению полного размера нужно ~64GB RAM для неограниченного `--all`. Используйте целевые режимы (`--find`, `--func`, `--from-main`) или ограничьте через `--max`.
- **Виртуальная диспетчеризация невидима для анализа достижимости `--from-main`.** Обратные вызовы жизненного цикла виджетов идут через диспетчеризацию фреймворка Flutter, а не через прямые инструкции вызова. Эвристика по касанию класса восстанавливает часть, но это сверхприближение. Для остального используйте Frida.
- **Каждое изменение версии Dart должно быть смоделировано.** Нет VM, которая автоматически обрабатывала бы изменения формата. Снимок несёт хеш, производный от git, а не номер версии, поэтому поддержка основана на структуре. Сейчас смоделировано: Dart 2.10 → 3.13.
- **Эталонные двойники не подлежат распространению** (реальные production-сборки), поэтому
  дифференциальный прогон восстановления имён выполняется локально, а не в публичном CI.

## Лицензия

BSD-3-Clause. Таблицы CID, смещения полей THR и имена заглушек производны от [Dart SDK](https://github.com/dart-lang/sdk) (также BSD-3-Clause). См. `LICENSE` и `NOTICE`.
Скачать инструмент