Files
simtrace-analyser/README_RUS.md
T
catarrh 65c8ab215b README: two explicit install paths; Windows launchers pass --db and quote paths
- the Install section now leads with the release artifacts (the wheel via
  pipx/pip, the direct release URL, `gh release download` for the
  version-agnostic case, and the source archive) and keeps the git clone as
  the development path.  It finally names the launchers (./start.sh,
  start.bat): a clone needs no install, but the README never said how to start
  it while the Running section only showed the console script that an install
  provides.
- Windows: the USB section now says the .bat launchers mirror the shell ones
  and call the `python` command (Python 3 must be on PATH); the Install section
  carries the same note.
- start.bat: --db/DB was parsed and then never passed to the server; it is
  passed now, and --gsmtap-port is sent only for gsmtap capture (as start.sh
  already did).  Both .bat files passed values unquoted and stripped the
  quotes of pass-through options, so paths with spaces broke
  (--db "C:\My Data\...", --web-dir, --pcap, --output); values are quoted now
  and pass-through keeps the original quoting (argument assembly through
  delayed expansion).
- the launcher usage comments include the `disabled` capture mode.
- verified the argument assembly with Wine cmd.exe and an echo harness: the
  quoted paths survive, --db arrives, --gsmtap-port appears only for gsmtap;
  547 Python + 80 Node tests.
2026-10-20 23:15:54 +03:00

524 lines
36 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# SIMtrace Analyser
[English](README.md) | Русский
Анализатор APDU-трассировок в формате GSMTAP-SIM — захватывает обмен с
SIM/UICC из UDP-потока GSMTAP (или импортирует файлы PCAP/PCAPNG),
декодирует его и отдаёт устанавливаемое веб-приложение для просмотра.
В репозиторий также включён **simtrace2-pysniff** — замена `simtrace2-sniff`
на Python, которая захватывает трафик с оборудования Osmocom SIMtrace2
и может передавать GSMTAP этому анализатору.
![PWA SIMtrace Analyser](frontend.png)
## Компоненты
- **Анализирующий сервер + PWA** (`simtrace-analyser-server`) — сохраняет
захваченный трафик в SQLite, декодирует его и отдаёт PWA
([`frontend/`](frontend/)) вместе с HTTP API на одном origin. Три режима
захвата: GSMTAP-листенер, захват напрямую с оборудования SIMtrace2 или
отключённый захват (только просмотр существующих записей).
- **Утилита захвата** (`simtrace2-pysniff`) — захватывает трафик
оборудования SIMtrace2 и выводит его в stdout, GSMTAP (Wireshark) или
PCAP-файлы. Это один из нескольких источников GSMTAP, которые принимает
анализатор (см. также
[sigrok_iso7816_stream](https://github.com/anttro/sigrok_iso7816_stream)).
- **PWA** ([`frontend/`](frontend/)) — окно трассировки с декодированными
APDU, SIM Toolkit, SMS и SCP80 OTA; сессии, импорт PCAP и трасс COMPRION,
интерфейс EN/RU.
## Возможности
**Декодер APDU** (на стороне сервера, отображается в PWA):
- Полное декодирование APDU — CLA по ISO 7816-4 / ETSI с **логическим
каналом 0-19** (стандартные каналы из b2-b1, расширенные 4-19 из b4-b1
по TS 102 221 §10.3), secure messaging и chaining команд, имена INS из
таблицы спецификаций, учёт SFI в P1/P2 для READ/UPDATE BINARY и команд
с записями; ответ MANAGE CHANNEL показывает назначенный картой канал
- Статусные слова — полный набор ISO 7816-4 плюс специфичные для UICC
значения: `91XX` (ожидается proactive-команда), `62F1/F2/F3`,
`63F1/F2` (больше данных), `9300` (SAT busy), `9850`, `9862–64`
- SIM Toolkit — SAT (GSM 11.14), CAT (TS 102 223) и USAT (TS 31.111):
proactive-команды с декодированными квалификаторами, TERMINAL RESPONSE,
ENVELOPE (Menu Selection, Call Control, SMS-PP download…); учитываются
известные несоответствия старых карт, нераспознанные TLV сохраняются
- TERMINAL CAPABILITY (TS 102 221 §11.1.19) — питание терминала (класс
напряжения, максимальный ток, тактовая частота), расширенные логические
каналы, дополнительные интерфейсы (UICC-CLF) и возможности eUICC
(SGP.22/SGP.32)
- SMS TPDU — SMS-DELIVER/SUBMIT, метки времени SCTS, информационные
элементы UDH
- SCP80 OTA secured packets — биты SPI (шифрование, требование/режим PoR,
RC/CC/DS, счётчик), алгоритм KIc/KID + набор ключей, TAR, CNTR/PCNTR;
декодирование Response Packet (PoR) по GET RESPONSE; **опциональная
расшифровка на клиенте** зашифрованных пакетов — вставьте 3DES/AES-ключ
карты в панели деталей, чтобы увидеть настоящие CNTR и защищённые данные
приложения (ключ остаётся в браузере, только в памяти; зашифрованные
в эфире CNTR/PCNTR/RC — это шифротекст, и они так и помечены); защищённое
сообщение приложения декодируется как поток **C-APDU** (SELECT,
UPDATE BINARY, …) с полной разбивкой CLA/INS/P1/P2/Lc/Le — сразу для
открытого текста или после расшифровки для зашифрованных пакетов
- Разбор ATR (пересчёт тактовой частоты, Fi/Di, битовая маска T,
безопасен для усечённых ATR) и FCP/FCI TLV; исторические байты
разбираются как COMPACT-TLV объекты UICC (TS 102 221 §6.3.1) — card
service data, **card capabilities** (ISO 7816-4 §8.1.1.2.7 таблица 88:
способы назначения и заявленное максимальное число логических каналов,
`8 or more` у карт с расширенными каналами) и завершающий индикатор
состояния (LCS/SW)
**PWA SIMtrace Analyser** ([`frontend/`](frontend/)):
- Окно трассировки с режимами «Карта»/«Список» — proactive,
TERMINAL RESPONSE, ENVELOPE и AUTH-команды выделяются в режиме карты
- Сессии с прямыми ссылками (`#session=N`), импорт PCAP
(`.pcap/.pcapng/.cap`), импорт трасс COMPRION (текстовый экспорт
«ISO Protocol Layer» из Device Manager), поиск и **фильтр команд с
множественным выбором** — любые команды и/или готовые пресеты («Проактивные
сессии»: FETCH, TERMINAL PROFILE и все команды с ответом SW 91xx;
«Файловые операции»: SELECT,
READ/UPDATE BINARY и READ/UPDATE RECORD, вместе с GET RESPONSE, несущим
данные выбранной команды)
- Устанавливаемая PWA, тёмная тема, интерфейс на английском/русском
## Требования
- **Python 3.9+**
- **PyUSB** — `pip install pyusb` (нужен только для захвата с оборудования
SIMtrace2; захват GSMTAP/UDP и импорт PCAP работают без него)
- **libusb** — системная библиотека, обычно уже есть в Linux; в Windows
нужно заменить драйвер SIMtrace2
(см. [Доступ к USB-устройству](#доступ-к-usb-устройству))
- **Оборудование SIMtrace2** с прошивкой в режиме *trace* (только для
прямого захвата; VID `1d50`, PID `60e3`, USB class `ff`, subclass `01`).
О сборке и прошивке trace-прошивки см.
[проект SIMtrace2](https://gitea.osmocom.org/sim-card/simtrace2).
Других зависимостей нет. Вывод PCAP, GSMTAP и hex dump использует только
стандартную библиотеку Python.
## Установка
Есть два способа получить анализатор: установить артефакт релиза (без истории
git) или склонировать репозиторий для разработки. В обоих случаях в комплекте
одна и та же PWA.
### Из релиза (без истории git)
Всё находится на странице
[последнего релиза](https://github.com/anttro/simtrace-analyser/releases/latest).
**Wheel** (рекомендуется — изолированная установка, PWA внутри пакета):
```sh
pipx install ./simtrace_analyser-2.7.10-py3-none-any.whl
# или: pip install ./simtrace_analyser-2.7.10-py3-none-any.whl
# затем запуск (интерфейс отдаётся на http://127.0.0.1:8081/):
simtrace-analyser-server --capture gsmtap
```
`pip` также может скачать wheel прямо со страницы релиза (подставьте версию,
указанную там):
```sh
pip install https://github.com/anttro/simtrace-analyser/releases/download/v2.7.10/simtrace_analyser-2.7.10-py3-none-any.whl
```
С GitHub CLI можно скачать wheel последнего релиза, не зная версии:
```sh
gh release download --pattern '*.whl'
pipx install ./simtrace_analyser-*.whl
```
**Архив исходников** — ассеты *Source code (zip / tar.gz)* содержат полное
дерево без истории git: распакуйте, перейдите в каталог и используйте скрипты
запуска ниже (`./start.sh` в Linux/macOS, `start.bat` в Windows).
### Из клона репозитория (для разработки)
```sh
git clone https://github.com/anttro/simtrace-analyser.git
cd simtrace-analyser
./start.sh # Linux/macOS; в Windows: start.bat
```
Скрипты запуска добавляют каталог в `PYTHONPATH` и запускают
`python -m simtrace_analyser`, поэтому для просмотра и захвата GSMTAP
установка не нужна; они принимают параметры сервера
(`./start.sh --capture direct --port 8080`). Для прямого захвата с
оборудования нужен **PyUSB** (`pip install pyusb`).
Чтобы получить консольные команды (`simtrace-analyser-server`,
`simtrace2-pysniff`), установите пакет:
```sh
pip install -e .
simtrace-analyser-server --capture gsmtap
```
В Windows скрипты `.bat` вызывают команду `python`, поэтому Python 3 должен
быть в `PATH` (проверьте `python --version`); для прямого захвата по USB
дополнительно нужна замена драйвера, описанная в разделе
[Доступ к USB-устройству](#доступ-к-usb-устройству).
## Запуск
### Анализирующий сервер + PWA (`simtrace-analyser-server`)
Сохраняет захваченный APDU-трафик в SQLite и отдаёт его по HTTP вместе
со встроенной PWA **SIMtrace Analyser** (`frontend/` в исходном клоне, при
установке — внутри пакета) на том же origin.
Три режима захвата:
```sh
# Слушать GSMTAP от simtrace2-pysniff (или оригинального simtrace2-sniff):
simtrace-analyser-server --capture gsmtap
# Захват напрямую с оборудования SIMtrace2 (внешний инструмент не нужен):
simtrace-analyser-server --capture direct
# Просмотр/анализ существующих записей без бэкенда захвата:
simtrace-analyser-server --capture disabled
```
Сервер пишет в stderr информацию о жизненном цикле захвата (каждая строка
с локальным временем): `Capture started` при старте, периодический
heartbeat `Capture alive: session=N messages=M bytes=B dropped=D skipped=S`
и `Capture stopped` (либо `ERROR: capture thread stopped on error …`,
если поток захвата неожиданно умер). Неверно сформированные или не-SIM
датаграммы GSMTAP отбрасываются и считаются (`dropped`), а не молча
убивают захват; `tpdu`-пакет, вовсе не похожий на APDU (короче заголовка,
недопустимый CLA `FF` или зарезервированный ISO класс `001x`),
пропускается и считается (`skipped`) — посимвольный или миссемплированный
поток больше не засоряет декодирование. Интервал heartbeat по умолчанию
60 с, настраивается через `--log-interval SECONDS`.
GSMTAP-листенер также принимает декодер **sigrok-iso7816-stream**
(https://github.com/anttro/sigrok_iso7816_stream) — пассивный SIM-сниффер
на базе FX2-логического анализатора, выдающий тот же формат GSMTAP-SIM
на UDP 4729. Его стандартные подтипы PPS-запроса/ответа (`0x02`/`0x03`)
декодируются как PPS, а пользовательские подтипы для событий линий RST/VCC
(`0x10`/`0x11`, добавлены для совместимости с тем проектом) — как временные
маркеры `RESET ASSERTED` / `RST de-asserted — ATR follows` и `VCC ON/OFF`;
сброс или пропадание питания корректно сбрасывает отслеживание выбранного
файла. Когда событие
RST несёт измеренную частоту CLK (декодер v1.9.0+, опциональное расширение
полезной нагрузки), следующий ATR получает частоту CLK, скорость передачи
данных и ETU, вычисленные из его TA1 Fi/Di
(`data_rate = clk_hz × D / F`); измерение потребляется ATR, поэтому
следующий ATR без сброса не получит устаревшую скорость (поздно пришедшее
измерение восстанавливается для «своего» ATR). GSMTAP-пакеты с флагом
десинхронизации `GSMTAP_FLAG_BAD_FCS` (устанавливается тем декодером при
нарушении кадрирования) отображаются в таймлайне как
помеченная/десинхронизированная запись, чтобы такие артефакты было легко
заметить при разборе, а не молча искажали декодирование.
### Импорт текстового экспорта COMPRION
Кнопка **Import COMPRION trace** принимает экспорт **ISO Protocol Layer**
(табулированный текст) из COMPRION Device Manager — байтовое представление
протокола (ATR, PPS, APDU с кодами возврата). Экспорт *ISO Application
Layer* не содержит необработанных байтов ответов и не нужен; при его выборе
выводится указание на файл Protocol Layer (та же проверка выполняется в PWA
до загрузки и на сервере — для вызовов API).
Обмены перекодируются в такие же «проводные» TPDU, какие несёт захват
GSMTAP (обмен case 4 превращается в команду, статусное слово `61 xx` и GET
RESPONSE с данными ответа и итоговым SW), поэтому связывание
команда/ответ, декодирование FCP и файлов и фильтры работают так же, как
для живого захвата.
**Точные метки времени:** диалог импорта запрашивает экспорт *ISO Protocol
Layer* (обязательный) и, при наличии, соответствующий экспорт *ISO
Application Layer* — два отдельных поля выбора, имена выбранных файлов
видны, а ошибка остаётся в диалоге до исправления или отмены. С обоими
файлами метки времени Application Layer по обменам становятся таймлайном
трассы: окно сессии и интервалы между APDU точные; без него таймлайн —
оценка, описанная ниже. Перед импортом проверяется, что файлы относятся к
одной сессии (`Session Name`, при отсутствии — `Working directory`; метки
времени экспорта у слоёв различаются и не сравниваются) и что число обменов
совпадает (экспорты должны покрывать один и тот же набор обменов) — при
несовпадении импорт отклоняется, а не смешивает сессии. У ATR и обмена PPS
блоков в Application Layer нет, поэтому они получают метку времени
предыдущего обмена.
**Только Protocol Layer:** столбец `Delay` измеряет лишь активность
карты/линии — паузы хоста между сериями APDU в него не входят — поэтому
таймлайн сохраняет порядок сообщений и короткие интервалы, но заметно
короче реальной сессии. Его единица измерения задаётся предполагаемой
тактовой частотой 3,8 МГц (`CLK_HZ` в `simtrace_analyser/comprion.py`) —
это масштаб, а не измерение: в экспорте нет CLK, и импорт намеренно его не
выдумывает (ATR показывает F/D из файла, без аннотации скорости/ETU, в
отличие от захвата сниффером sigrok-iso7816-stream). Окно настенных часов
сессии берётся из метки времени `Session Name` в файле, если она там есть.
Обмены длиннее 255 байт (APDU с расширенной длиной) невозможно представить
в хранимом «проводном» виде — они пропускаются с пометкой в отчёте импорта.
### Просмотр файлов (сопровождение состояния файлов)
В верхней панели вкладки «Трассировка» появился выбор вида (*Map* / *Stats* /
**Files**) — он выровнен по правому краю над боковой панелью и имеет её
ширину, поэтому виден всё время, пока панель прокручивается (выпадающий
список, три подписи-вкладки уже не помещались). Вид
Files — это таймлайн файловых операций по всей трассе: строки **Read** и
**Update** показывают те же имена файлов, что и вид Map (изменение со стороны
карты выглядит как чтение со ссылкой **Изменено на карте!**, открывающей
подробности), а щелчок по строке переходит прямо к APDU в трассе и оставляет
его выделенным, пока не выбран другой (список APDU сохраняет позицию читателя:
новые сообщения прижимают вид к низу, только пока читатель уже внизу,
поэтому переход не срывается живым опросом и не снимает выделение). У строк с записанным изменением
(изменение со стороны карты либо запись, изменившая или впервые показавшая
байты) есть кнопка **Show diff** («Изменения»): окно показывает полный путь файла (`MF/EF_ICCID (2FE2)`,
`ADF/EF_IMSI (6F07)`, `DF_TELECOM/DF_PHONEBOOK/4FA1`, `AID …/4F09` — вся
цепочка DF из пути выбора в трассе, каждый DF назван по словарю
спецификаций, а AID — по меткам из EF.DIR, если они есть) и затронутую
единицу — файл
целиком или изменившуюся запись — **до и после** изменения в виде hex-вида
(до 16 байт в строке: короткий файл/запись заканчивает строку, а не
дополняется `--`, и столбец смещений появляется, только когда представление
занимает больше одной строки), причём изменённые
байты подсвечены одним цветом, а впервые наблюдаемые — другим; ниже —
счётчики изменённых/новых байт, ссылка на APDU и легенда цветов под
представлениями, перечисляющая только реально показанные пометки.
У файлов телефонной книги FID назначает карта, поэтому словарь их не
знает: если в трассе есть записи **EF_PBR**, они разбираются
(TS 31.102 §4.4.2.1 — группы типов `A8`/`A9`/`AA` и примитивные теги `C0`…`CC`
с FID и, для трёхбайтового объекта, SFI), и Files называет файлы по
объявлению самой карты — например
`DF_TELECOM/DF_PHONEBOOK/EF_PBC (4FA1)` — а объявленные SFI пополняют карту
SFI→FID этого DF (правило «SFI = 5 младших бит FID» из TS 102 221 §11.1.1.4.8
для остальных файлов остаётся).
Изображения отдаёт `GET /api/sessions/<id>/files/image?key=…&change=…`; они
восстанавливаются из текущего образа отменой более поздних изменений
(`filetrack.FileTracker.change_images`) — поэтому ничего не дублируется по
событиям. Каждое изменение значения записывается, так что значения точны;
байт, который был лишь *впервые показан* после выбранного изменения, может
отображаться известным в обоих видах.
Данные даёт `simtrace_analyser/filetrack.py` (`GET /api/sessions/<id>/files`) —
однопроходный анализатор сессии, который ведёт по ключу (DF, FID) и **через
сбросы карты**: счётчики доступа (`select`/`read`/`update`, только успешные
операции), разреженный образ наблюдаемого содержимого и журнал изменений.
Изменения со стороны устройства — это операции UPDATE из трассы; изменения со
стороны карты выводятся, когда чтение возвращает байты, отличающиеся от уже
известных образу (никогда не виденные байты просто заполняют образ — это
наблюдение, а не изменение). Файлы, доступные по SFI, попадают в ту же
запись, что и доступ по пути/FID: соответствия SFI ↔ FID берутся из
нормативных таблиц (анекс H.1 TS 102 221 и анексы H.1–H.12 TS 31.102;
строки SFI ISIM — из TS 31.103) и из каждого
показанного FCP с DO `88`, включая правило спецификации «SFI = 5 младших бит
FID» при отсутствии DO; SFI, использованный до того, как связь выучена,
остаётся предварительным и сливается с разрешённой записью. Контекст DF
следует TS 102 221 §8.4/Table 8.2 (выбор EF оставляет текущим его родительский
DF, включая выбор по пути); приложения, выбранные по неизвестному AID,
получают в качестве идентичности DF сам AID и имя из EF.DIR, если он
показан в трассе. Ограничения: образ замораживается после 64 КБ
наблюдаемых байт на файл (`image_truncated`), журнал изменений хранит
последние 1000 событий на файл (`changes_total` продолжает считать).
Счётчики API отдаёт, но в этом виде пока не показываются.
Имена файлов **привязаны к DF**: `simtrace_analyser/ef_tables.py` содержит
полные таблицы файлов и SFI по каждому DF, извлечённые из закреплённых
спецификаций (TS 102 221, TS 31.102 включая анексы SFI H.1–H.12, TS 31.103,
TS 51.011), поэтому FID, повторно используемый в разных DF, разрешается в имя
своего контекста — `4F09` это EF_SUPI_NAI в DF_5GS, но EF_PROSE_GC в DF_ProSe;
`6F07` — EF_IMSI в USIM/SIM, но EF_IST в ISIM; `6F4E` — EF_EXT4 в DF_TELECOM,
но EF_EXT5 в ADF USIM, — а плоская таблица служит запасным вариантом, когда DF
неизвестен. `tests/extract_spec_tables.py` пересобирает закреплённый фикстур
(`tests/data/spec_files.json`), `--check` повторно сверяет таблицы с PDF.
Параметры сервера:
```
--host ADDR адрес привязки HTTP (по умолчанию: 127.0.0.1)
--port PORT порт HTTP-сервера (по умолчанию: 8081)
--db FILE путь к базе SQLite (по умолчанию: ~/.simtrace-analyser/sessions.db)
--capture MODE gsmtap | direct | disabled (по умолчанию: gsmtap)
--gsmtap-port PORT UDP-порт листенера GSMTAP (по умолчанию: 4729)
--web-dir PATH каталог статических файлов PWA (по умолчанию: PWA внутри
установленного пакета или <repo>/frontend при запуске из исходников)
```
Затем откройте **http://127.0.0.1:8081/** в браузере — PWA отдаётся
сервером, поэтому UI и API используют один origin, и настройка
CORS/Private-Network-Access не требуется. Используйте `--web-dir PATH`,
чтобы отдавать другой каталог PWA (по умолчанию: PWA внутри пакета или
`<repo>/frontend` при запуске из исходников).
### Размещённая PWA (лендинг)
Автономная копия PWA размещена на **https://simtrace.atroshin.ru**.
Это чистый фронтенд: укажите в нём (Settings → Server URL) адрес
локально запущенного `simtrace-analyser-server`.
> **Ограничение браузера:** когда PWA отдаётся с публичного HTTPS-хоста,
> доступ к локальному серверу (`http://127.0.0.1:8081`) требует двух
> вещей: сервер должен отправлять
> `Access-Control-Allow-Private-Network: true` (этот сервер отправляет),
> и браузер должен иметь разрешение на доступ к локальной сети —
> в Chrome/Edge/Vivaldi: Настройки сайта → Доступ к локальной сети →
> разрешить сайту (или принять запрос разрешения). Без разрешения
> браузера запрос к `127.0.0.1` блокируется ещё до отправки preflight.
### Утилита захвата (`simtrace2-pysniff`)
Захватывает трафик оборудования SIMtrace2 и выводит его в stdout, GSMTAP
(Wireshark) или PCAP-файлы. Это встроенная замена оригинального
инструмента Osmocom `simtrace2-sniff`.
Скрипт запуска `./sniff-start.sh` выполняет предварительную проверку прав
доступа к USB (при неудаче печатает инструкцию по установке udev-правила)
и затем запускает модуль Python. В Windows используйте `sniff-start.bat`
с теми же параметрами (проверка прав не требуется).
```sh
./sniff-start.sh
./sniff-start.sh --format timestamp
./sniff-start.sh --gsmtap 127.0.0.1:4729
./sniff-start.sh --pcap trace.pcap --format atr-time
```
Параметры также можно задавать через переменные окружения:
```sh
FORMAT=timestamp GSMTAP=127.0.0.1 ./sniff-start.sh
```
Кроссплатформенный запуск модуля:
```sh
python -m simtrace2_pysniff
python -m simtrace2_pysniff --format timestamp --gsmtap 127.0.0.1:4729
python -m simtrace2_pysniff --pcap trace.pcap
```
Если пакет установлен через `pip install -e .`, используйте консольный
скрипт напрямую:
```sh
simtrace2-pysniff --format atr-time
```
## Доступ к USB-устройству
Нужен для захвата с оборудования SIMtrace2 (утилита и режим
`--capture direct` сервера); для источников GSMTAP и PCAP не требуется.
### Linux
Для доступа к устройству SIMtrace2 без root нужно udev-правило.
```sh
sudo cp 70-simtrace2-pysniff.rules /etc/udev/rules.d/
sudo udevadm control --reload-rules
sudo udevadm trigger
```
Затем переподключите USB-кабель SIMtrace2. Правило использует
`TAG+="uaccess"` (ACL systemd-logind) — членство в группе и права на
запись для всех не нужны.
### Windows
В Windows нет libusb-совместимого драйвера для SIMtrace2. Используйте
[Zadig](https://zadig.akeo.ie/), чтобы заменить драйвер по умолчанию:
1. Скачайте и запустите **Zadig**
2. Подключите устройство SIMtrace2
3. Выберите его в выпадающем списке (VID `1D50`, PID `60E3` — "Osmocom SIMtrace 2")
4. Выберите **WinUSB** (или libusbK) как драйвер замены
5. Нажмите **Replace Driver** (однократная операция)
После этого `python -m simtrace2_pysniff` работает так же, как в Linux.
Скрипты запуска для Windows соответствуют shell-версиям и передают все
параметры: `start.bat --capture direct` запускает сервер анализатора, а
`sniff-start.bat` — утилиту захвата. Оба вызывают команду `python`, поэтому
Python 3 должен быть в `PATH` (проверьте `python --version` в новом окне
команды).
## Параметры CLI утилиты
```
python -m simtrace2_pysniff [OPTIONS]
--format, -f FORMAT Формат вывода (по умолчанию: hex)
hex — обычный hex-дамп
timestamp — строки TPDU с префиксом [ЧЧ:ММ:СС.мс]
atr-time — строки TPDU с префиксом [СССС.мс] от последнего ATR
--gsmtap HOST[:PORT] Отправлять ATR/TPDU как GSMTAP по UDP (порт по умолчанию 4729)
--pcap FILE Записывать перехваченные данные в PCAP для Wireshark
--output, -o FILE Записывать hex-дамп в файл
--no-stdout Не выводить hex-дамп в stdout
--vendor HEX USB vendor ID (по умолчанию: 0x1d50)
--product HEX USB product ID (по умолчанию: автоопределение)
Параметры восстановления:
--no-reconnect Выходить при отключении USB вместо переподключения
--reconnect-delay-min SEC Минимальная задержка переподключения (по умолчанию: 1.0)
--reconnect-delay-max SEC Максимальная задержка переподключения (по умолчанию: 30.0)
--backoff-factor N Множитель экспоненциальной задержки (по умолчанию: 1.5)
--inactivity-timeout SEC Переподключаться после N секунд тишины (по умолчанию: выключено)
```
## Форматы вывода
- **`hex`** (по умолчанию): обычный hex-дамп — `ATR: 3b 9e ...`,
`TPDU: a0 a4 00 00 02 3f 00`
- **`timestamp`**: строки TPDU с локальным временем —
`[14:32:05.123] TPDU: a0 a4 00 00 02 3f 00`
- **`atr-time`**: строки TPDU с секундами от последнего ATR —
`[0001.234] TPDU: a0 a4 00 00 02 3f 00`
Сообщения, не являющиеся TPDU (ATR, PPS, изменения состояния карты, Fi/Di),
выводятся одинаково во всех форматах.
- **GSMTAP**: сообщения ATR и APDU по UDP (порт 4729) в Wireshark
- **PCAP**: сообщения ATR/TPDU как пакеты Ethernet/IP/UDP/GSMTAP,
открываются в Wireshark
## Фоновый режим / демон
SIGHUP автоматически игнорируется, когда stdin не является терминалом
(т.е. при запуске в фоне или через канал). Сессии в терминале на переднем
плане по-прежнему обрабатывают SIGHUP обычным образом.
Для постоянной работы в фоне с выводом в файлы:
```sh
nohup ./sniff-start.sh --output /tmp/sniff.log &> /tmp/sniff-err.log &
# или
FORMAT=timestamp nohup python -m simtrace2_pysniff --output /tmp/sniff.log &> /tmp/sniff-err.log &
```
## Использование как библиотеки
```python
from simtrace2_pysniff import SniffSession
session = SniffSession(inactivity_timeout=30.0)
for msg in session.iter_messages():
print(f"{msg.type}: {msg.data.hex()}")
```
## Восстановление
Утилита по умолчанию переживает сбросы оборудования, отключения кабеля
и зависания прошивки — она переподключается с экспоненциальной задержкой
(1с → 30с). Используйте `--inactivity-timeout`, чтобы также переподключаться
при «тихих» зависаниях прошивки.
## Связанные проекты
- **[simtrace2](https://gitea.osmocom.org/sim-card/simtrace2)** — вышестоящий
проект оборудования/прошивки SIMtrace2, с которого утилита захвата
снимает трафик.
- **[sigrok_iso7816_stream](https://github.com/anttro/sigrok_iso7816_stream)** —
пассивный ISO 7816 сниффер на базе FX2LP, выдающий такой же поток
GSMTAP-SIM на UDP 4729 (принимается GSMTAP-листенером этого проекта).