7 Commits
Author SHA1 Message Date
catarrh 50dba20f04 README: add SIMple as a GSMTAP-SIM source to the diagram
SIMple can stream its own ISO 7816 APDUs as GSMTAP-SIM packets (its --gsmtap
option), so it belongs beside the sniffers and the sigrok decoder.  The
diagrams get a compact SIMple block between the SIMtrace2 sniffers and the
sigrok_iso7816_stream boxes (they do not move): title SIMple, subtitle
"APDU -> GSMTAP", and its own arrow into the UDP :4729 listener.  It is
deliberately smaller than the primary sniffers, matching its role as a
secondary source.

The README alt text and the gsmtap capture-mode bullet/comment now list SIMple
as a source too (linked to its repository in the bullet).

Both languages; 558 Python + 80 Node tests; runtime zip rebuilt with the
updated diagrams.
2026-10-28 12:36:38 +03:00
catarrh f492f29ea6 README: correct the architecture diagram's capture paths
The diagrams conflated the SIMtrace2 hardware with the sniffer that reads it
and omitted the original Osmocom simtrace2-sniff: they showed
simtrace2-pysniff feeding the GSMTAP listener with the hardware only as its
subtitle, and a second, unexplained "SIMtrace2 hardware / direct USB" box.

The diagrams now show the device -> sniffer -> GSMTAP relationship explicitly:
SIMtrace2 hardware is read either by simtrace2-pysniff or by the original
simtrace2-sniff, and FX2 hardware by the sigrok_iso7816_stream decoder; the
sniffers/decoder stream GSMTAP-SIM to the UDP :4729 listener.  The direct USB
path is drawn separately from the device to the server and is labelled
"pysniff code in-process": --capture direct uses the bundled
simtrace2_pysniff package (DirectSniffer -> SniffSession) inside the server
process, not the simtrace2-pysniff CLI, and bypasses GSMTAP.  PCAP/COMPRION
import, SQLite and the browser UI keep their places.

The READMEs' alt text, the first-run capture-mode notes and the Usage command
comments now name the original simtrace2-sniff as a GSMTAP source and say the
direct mode runs the bundled sniffer code inside the server.

Both languages; 558 Python + 80 Node tests; runtime zip still carries both
diagrams and the README image guard passes.
2026-10-28 01:46:13 +03:00
catarrh 2b83d21e64 README: add architecture diagrams (EN/RU)
Both READMEs gain a capture-and-analysis diagram right under the screenshot:
simtrace2-pysniff and sigrok_iso7816_stream feed the GSMTAP UDP :4729
listener, SIMtrace2 hardware can be read directly over USB, PCAP/COMPRION
traces come from files, and simtrace-analyser-server decodes/stores into
SQLite and serves the web UI.  The SVGs carry title/desc and role=img, use
only inline presentation attributes (no scripts, no external refs) and render
without clipped text; the RU text matches the EN layout.

The runtime zip includes both diagrams so the embedded READMEs keep working,
and a new drift guard checks that every image a README references is present
in the archive.  RU wording: "устанавливаемое PWA" (neuter agreement).

558 Python + 80 Node tests.
2026-10-28 00:36:26 +03:00
catarrh 9a661f5ab2 README: expand the title, move the news line up, update Related tools
The heading now names the tool and what it analyses instead of just the
product name, and the news/website line sits right under the language switch
so it is visible before the description.

The Related section became "Related tools" with the same family block the
sibling projects use (SIMple, SIMtrace Analyser, sigrok_iso7816_stream on one
website and news channel), and simtrace2 is mentioned as the upstream
hardware/firmware the bundled capture utility sniffs from.  One wording tweak:
the capture-liveness paragraph states the current behaviour ("does not
pollute") instead of describing it as a change ("no longer pollutes").

Both languages; docs only, 557 Python + 80 Node tests.
2026-10-27 23:38:43 +03:00
catarrh 5a7768e6a9 README: stop framing the runtime zip as Windows-only
The zip is just an archive: it extracts and runs on any OS, and the release's
Source code assets are offered as zip as well as tar.gz, so users pick the
format they prefer.  The section is now "Zip (no installer)" (RU "Zip (без
установки)") and says the archive works on any OS; the Windows/Linux start
commands stay as instructions, not as the section's rationale.  The
source-archive note names both formats, and the release-notes template
follows.
2026-10-27 11:10:55 +03:00
catarrh 7801c62ca3 README: show the launcher forms in the Usage capture modes
The Usage server section only showed the console script and mentioned the
launchers in prose.  It now lists the three capture modes for ./start.sh
(Linux/macOS) and start.bat (Windows) right after the console-script block,
with the pass-through example (--port).
2026-10-27 11:08:11 +03:00
catarrh f18a11edaf README: say UI/frontend except where PWA actually matters
"PWA" appeared throughout the READMEs although most readers don't know the
term and it is usually irrelevant: the server just serves a web interface.
The text now says UI (web UI) for the app and frontend for the static files -
in the quick start, the install/zip/clone paths, the server and --web-dir
docs, the components list and the decoder notes.  The one place where it
matters - the feature list's installable PWA - keeps the term and unpacks it
(installs to the desktop or home screen and works offline); the hosted copy is
now "Hosted UI" since the point there is connecting to a local server.

Both languages; docs only, 557 Python + 80 Node tests.
2026-10-27 11:06:08 +03:00
7 changed files with 334 additions and 88 deletions

No files matched your search

+1 -1
View File
@@ -13,7 +13,7 @@ The source archive is the same tree a clone would have: unzip it and run
`./start.sh` (Linux/macOS) or `start.bat` (Windows). Direct SIMtrace2 capture `./start.sh` (Linux/macOS) or `start.bat` (Windows). Direct SIMtrace2 capture
on Linux additionally needs the attached `70-simtrace2-pysniff.rules` udev rule. on Linux additionally needs the attached `70-simtrace2-pysniff.rules` udev rule.
**Runtime zip (Windows-friendly, no installer)** — `simtrace-analyser-*.zip` **Runtime zip (no installer)** — `simtrace-analyser-*.zip`
is the runtime tree only (packages, PWA, launchers, docs — no tests, no git): is the runtime tree only (packages, PWA, launchers, docs — no tests, no git):
extract it anywhere and run `start.bat` (Windows) or `./start.sh` extract it anywhere and run `start.bat` (Windows) or `./start.sh`
(Linux/macOS). Python 3 has to be on `PATH`; `pip install pyusb` is only (Linux/macOS). Python 3 has to be on `PATH`; `pip install pyusb` is only
+78 -41
View File
@@ -1,7 +1,9 @@
# SIMtrace Analyser # SIMtrace Analyser — an APDU trace analyser for GSMTAP-SIM captures
English | [Русский](README_RUS.md) English | [Русский](README_RUS.md)
📢 Project news and updates: [website](https://atroshin.ru) · [Telegram channel](https://t.me/youeyeseesee)
APDU trace analyser for the GSMTAP-SIM format — captures SIM/UICC APDU trace analyser for the GSMTAP-SIM format — captures SIM/UICC
communication from a UDP GSMTAP stream (or imports PCAP/PCAPNG files), communication from a UDP GSMTAP stream (or imports PCAP/PCAPNG files),
decodes it, and serves an installable web app for browsing. The repository decodes it, and serves an installable web app for browsing. The repository
@@ -9,9 +11,9 @@ also bundles **simtrace2-pysniff**, a Python replacement for
`simtrace2-sniff` that captures from Osmocom SIMtrace2 hardware and can feed `simtrace2-sniff` that captures from Osmocom SIMtrace2 hardware and can feed
GSMTAP into this analyser. GSMTAP into this analyser.
📢 Project news and updates: [atroshin.ru](https://atroshin.ru) | [Telegram channel](https://t.me/youeyeseesee) ![SIMtrace Analyser UI](frontend.png)
![SIMtrace Analyser PWA](frontend.png) ![Capture and analysis: SIMtrace2 hardware is read by simtrace2-pysniff or the original simtrace2-sniff, and FX2 hardware by the sigrok_iso7816_stream decoder; the sniffers, the decoder and SIMple stream GSMTAP-SIM to the UDP :4729 listener. The server can also read SIMtrace2 hardware directly over USB with the bundled pysniff code in-process, and imports PCAP/COMPRION traces from files. simtrace-analyser-server decodes and stores the traffic in SQLite and serves the web UI](architecture_en.svg)
## Prerequisites ## Prerequisites
@@ -36,12 +38,12 @@ even run on another machine), `--capture disabled`, or PCAP imports.
## Quick start ## Quick start
Three ways to get it running; all of them serve the same PWA at Three ways to get it running; all of them serve the same web UI at
http://127.0.0.1:8081/. http://127.0.0.1:8081/.
### 1. Wheel (pip) ### 1. Wheel (pip)
The wheel bundles the PWA, so the server serves the UI by itself: The wheel includes the UI, so the server serves it by itself:
```sh ```sh
pip install ./simtrace_analyser-2.7.13-py3-none-any.whl pip install ./simtrace_analyser-2.7.13-py3-none-any.whl
@@ -64,11 +66,11 @@ gh release download --pattern '*.whl'
pip install ./simtrace_analyser-*.whl pip install ./simtrace_analyser-*.whl
``` ```
### 2. Zip (Windows-friendly, no installer) ### 2. Zip (no installer)
Download `simtrace-analyser-2.7.13.zip` from the release page and extract it Download `simtrace-analyser-2.7.13.zip` from the release page and extract it
anywhere: it is the runtime tree (the Python packages, the PWA, the launchers anywhere: it is the runtime tree (the Python packages, the web UI, the launchers
and the docs — no tests, no git). Then run: and the docs — no tests, no git). The archive works on any OS; then run:
Windows: Windows:
@@ -85,8 +87,8 @@ Linux/macOS:
Python 3 has to be on `PATH`; `pip install pyusb` is only needed for direct Python 3 has to be on `PATH`; `pip install pyusb` is only needed for direct
SIMtrace2 capture. The launchers accept the server's options SIMtrace2 capture. The launchers accept the server's options
(`start.bat --capture direct`, `./start.sh --capture direct --port 8080`). (`start.bat --capture direct`, `./start.sh --capture direct --port 8080`).
(The release's *Source code* archive is the full tree including tests; it (The release's *Source code (zip / tar.gz)* archives are the full tree
works like a clone below.) including tests; they work like a clone below.)
### 3. Git clone (development) ### 3. Git clone (development)
@@ -113,9 +115,11 @@ simtrace-analyser-server --capture gsmtap
Open **http://127.0.0.1:8081/** in a browser. `Ctrl+C` stops the server. Open **http://127.0.0.1:8081/** in a browser. `Ctrl+C` stops the server.
- `--capture gsmtap` (default) — listen for GSMTAP-SIM on UDP 4729, e.g. from - `--capture gsmtap` (default) — listen for GSMTAP-SIM on UDP 4729, e.g. from
`simtrace2-pysniff` or `sigrok_iso7816_stream`; `simtrace2-pysniff`, the original `simtrace2-sniff`,
- `--capture direct` — read SIMtrace2 hardware directly (needs PyUSB; Windows `sigrok_iso7816_stream` or [SIMple](https://github.com/anttro/simple);
also needs the driver swap, see [USB Device Access](#usb-device-access)); - `--capture direct` — read SIMtrace2 hardware directly (the bundled sniffer
code runs inside the server and talks to the device over USB; needs PyUSB;
Windows also needs the driver swap, see [USB Device Access](#usb-device-access));
- `--capture disabled` — only browse stored captures. - `--capture disabled` — only browse stored captures.
The full runtime guide (server options, the UI views, the capture utility) is The full runtime guide (server options, the UI views, the capture utility) is
@@ -123,26 +127,47 @@ in [Usage](#usage) below.
## Usage ## Usage
### Analysis server + PWA (`simtrace-analyser-server`) ### Analysis server + UI (`simtrace-analyser-server`)
Stores captured APDU traffic in SQLite and serves it over HTTP, together with Stores captured APDU traffic in SQLite and serves it over HTTP, together with
the bundled **SIMtrace Analyser** PWA (`frontend/` in a source checkout, the bundled **SIMtrace Analyser** frontend (`frontend/` in a source checkout,
bundled into the package on install) on the same origin. The commands below bundled into the package on install) on the same origin. Three capture
use the console script; from a source checkout the launchers take the same modes:
options (`./start.sh --capture gsmtap`, `start.bat --capture gsmtap`). Three
capture modes:
```sh ```sh
# Listen for GSMTAP from simtrace2-pysniff (or original simtrace2-sniff): # Listen for GSMTAP from simtrace2-pysniff, the original simtrace2-sniff,
# sigrok_iso7816_stream or SIMple:
simtrace-analyser-server --capture gsmtap simtrace-analyser-server --capture gsmtap
# Capture directly from SIMtrace2 hardware (no external tool needed): # Capture directly from SIMtrace2 hardware (the bundled sniffer code reads the
# device; no external tool, no GSMTAP):
simtrace-analyser-server --capture direct simtrace-analyser-server --capture direct
# Browse/analyse existing captures without a capture backend: # Browse/analyse existing captures without a capture backend:
simtrace-analyser-server --capture disabled simtrace-analyser-server --capture disabled
``` ```
From a source checkout or the runtime zip, the launchers run the same server
with the same options.
Linux/macOS:
```sh
./start.sh --capture gsmtap
./start.sh --capture direct
./start.sh --capture disabled
```
Windows:
```bat
start.bat --capture gsmtap
start.bat --capture direct
start.bat --capture disabled
```
Options pass through unchanged (`./start.sh --capture direct --port 8080`).
The server logs its capture liveness to stderr (each line timestamped The server logs its capture liveness to stderr (each line timestamped
with the local time): `Capture started` on begin, a periodic with the local time): `Capture started` on begin, a periodic
`Capture alive: session=N messages=M bytes=B dropped=D` heartbeat, and `Capture alive: session=N messages=M bytes=B dropped=D` heartbeat, and
@@ -152,7 +177,7 @@ datagram is dropped and counted (`dropped`) rather than silently
killing the capture; a `tpdu` packet that is not APDU-shaped at all killing the capture; a `tpdu` packet that is not APDU-shaped at all
(shorter than the header, the invalid CLA `FF` or an ISO-reserved class) (shorter than the header, the invalid CLA `FF` or an ISO-reserved class)
is skipped and counted (`skipped`) — a character-level or mis-sampled is skipped and counted (`skipped`) — a character-level or mis-sampled
stream no longer pollutes the decode. The heartbeat interval defaults to 60 s and is stream does not pollute the decode. The heartbeat interval defaults to 60 s and is
tunable via `--log-interval SECONDS`. tunable via `--log-interval SECONDS`.
The GSMTAP listener also accepts the **sigrok-iso7816-stream** decoder The GSMTAP listener also accepts the **sigrok-iso7816-stream** decoder
@@ -180,7 +205,7 @@ The **Import COMPRION trace** button accepts the tab-separated **ISO Protocol
Layer** export of COMPRION's Device Manager — the byte-accurate protocol view Layer** export of COMPRION's Device Manager — the byte-accurate protocol view
(ATR, PPS, APDUs with their return codes). The *ISO Application Layer* export (ATR, PPS, APDUs with their return codes). The *ISO Application Layer* export
carries no raw response bytes and is not needed; selecting it answers with a carries no raw response bytes and is not needed; selecting it answers with a
pointer to the Protocol Layer file (the same check runs in the PWA before the pointer to the Protocol Layer file (the same check runs in the UI before the
upload and on the server for API callers). upload and on the server for API callers).
Exchanges are re-encoded into the same wire-shaped TPDUs a GSMTAP capture Exchanges are re-encoded into the same wire-shaped TPDUs a GSMTAP capture
@@ -301,21 +326,22 @@ Server options:
--gsmtap-port PORT UDP port for the GSMTAP listener (default: 4729) --gsmtap-port PORT UDP port for the GSMTAP listener (default: 4729)
--gsmtap-bind ADDR UDP bind address for the GSMTAP listener (default: 127.0.0.1; --gsmtap-bind ADDR UDP bind address for the GSMTAP listener (default: 127.0.0.1;
use 0.0.0.0 to receive from a Docker bridge or another host) use 0.0.0.0 to receive from a Docker bridge or another host)
--web-dir PATH PWA static files directory (default: the PWA bundled in --web-dir PATH static files directory for the web UI (default: the
the installed package, or <repo>/frontend from source) frontend bundled in the installed package, or
<repo>/frontend from source)
``` ```
Then open **http://127.0.0.1:8081/** in a browser. Use `--web-dir PATH` to Then open **http://127.0.0.1:8081/** in a browser. Use `--web-dir PATH` to
serve a different PWA directory (default: the bundled PWA, or serve a different UI directory (default: the bundled frontend, or
`<repo>/frontend` in a source checkout). `<repo>/frontend` in a source checkout).
### Hosted PWA (landing page) ### Hosted UI (landing page)
A standalone copy of the PWA is hosted at **https://simtrace.atroshin.ru**. A standalone copy of the UI is hosted at **https://simtrace.atroshin.ru**.
It is a pure frontend: point it (Settings → Server URL) at a locally running It is a pure frontend: point it (Settings → Server URL) at a locally running
`simtrace-analyser-server`. `simtrace-analyser-server`.
> **Browser restriction:** this is the one setup where the PWA and the API have > **Browser restriction:** this is the one setup where the UI and the API have
> different origins, so the browser applies CORS and Private Network Access > different origins, so the browser applies CORS and Private Network Access
> rules. Reaching a local server (`http://127.0.0.1:8081`) requires two > rules. Reaching a local server (`http://127.0.0.1:8081`) requires two
> things: the server must send `Access-Control-Allow-Private-Network: true` > things: the server must send `Access-Control-Allow-Private-Network: true`
@@ -467,8 +493,8 @@ prompt).
## Components ## Components
- **Analysis server + PWA** (`simtrace-analyser-server`) — stores captured - **Analysis server + UI** (`simtrace-analyser-server`) — stores captured
traffic in SQLite, decodes it, and serves the PWA ([`frontend/`](frontend/)) traffic in SQLite, decodes it, and serves the UI ([`frontend/`](frontend/))
plus the HTTP API on a single origin. Three capture modes: a GSMTAP plus the HTTP API on a single origin. Three capture modes: a GSMTAP
listener, direct SIMtrace2 hardware capture, or disabled (browse existing listener, direct SIMtrace2 hardware capture, or disabled (browse existing
captures only). captures only).
@@ -476,13 +502,13 @@ prompt).
traffic and writes it to stdout, GSMTAP (Wireshark), or PCAP files. It is traffic and writes it to stdout, GSMTAP (Wireshark), or PCAP files. It is
one GSMTAP source of several that the analyser accepts (see also one GSMTAP source of several that the analyser accepts (see also
[sigrok_iso7816_stream](https://github.com/anttro/sigrok_iso7816_stream)). [sigrok_iso7816_stream](https://github.com/anttro/sigrok_iso7816_stream)).
- **PWA** ([`frontend/`](frontend/)) — trace browser with decoded APDU, - **UI** ([`frontend/`](frontend/)) — trace browser with decoded APDU,
SIM Toolkit, SMS and SCP80 OTA detail; sessions, PCAP and COMPRION trace SIM Toolkit, SMS and SCP80 OTA detail; sessions, PCAP and COMPRION trace
import, EN/RU UI. import, EN/RU UI.
## Features ## Features
**APDU decoder** (server-side, rendered by the PWA): **APDU decoder** (server-side, rendered by the UI):
- Full APDU decode — CLA per ISO 7816-4 / ETSI coding with the **logical - Full APDU decode — CLA per ISO 7816-4 / ETSI coding with the **logical
channel 0-19** (standard channels from b2-b1, the extended channels 4-19 channel 0-19** (standard channels from b2-b1, the extended channels 4-19
@@ -519,7 +545,7 @@ prompt).
and the announced maximum number of logical channels, `8 or more` for the and the announced maximum number of logical channels, `8 or more` for the
extended-capable cards) and the trailing status indicator (LCS/SW) extended-capable cards) and the trailing status indicator (LCS/SW)
**SIMtrace Analyser PWA** ([`frontend/`](frontend/)): **SIMtrace Analyser UI** ([`frontend/`](frontend/)):
- Trace view with Map/List modes — proactive, TERMINAL RESPONSE, ENVELOPE - Trace view with Map/List modes — proactive, TERMINAL RESPONSE, ENVELOPE
and AUTH commands get distinctive styling in map view and AUTH commands get distinctive styling in map view
@@ -530,19 +556,30 @@ prompt).
PROFILE and every command answered with SW 91xx; *File operations*: SELECT, PROFILE and every command answered with SW 91xx; *File operations*: SELECT,
READ/UPDATE BINARY and READ/UPDATE RECORD, with the GET RESPONSE carrying a READ/UPDATE BINARY and READ/UPDATE RECORD, with the GET RESPONSE carrying a
selected command's data) selected command's data)
- Installable PWA, dark theme, English/Russian UI - Installable **PWA** (progressive web app: installs to the desktop or home
screen and works offline), dark theme, English/Russian UI
## Related ## Related tools
- **[simtrace2](https://gitea.osmocom.org/sim-card/simtrace2)** — the upstream SIMple, SIMtrace Analyser and sigrok_iso7816_stream are three standalone
SIMtrace2 hardware/firmware project that the capture utility sniffs from. tools for working with SIM/UICC cards, published together on the same
[website](https://atroshin.ru) and [news channel](https://t.me/youeyeseesee).
Each one is fully independent — install only the tools you need:
- **[SIMple](https://github.com/anttro/simple)** — a UICC workbench: APDU
construction, SCP80/SCP81 OTA, SIM Toolkit simulation and card profiling.
- **[SIMtrace Analyser](https://github.com/anttro/simtrace-analyser)** — an
APDU trace analyser for GSMTAP-SIM captures.
- **[sigrok_iso7816_stream](https://github.com/anttro/sigrok_iso7816_stream)** — - **[sigrok_iso7816_stream](https://github.com/anttro/sigrok_iso7816_stream)** —
FX2LP-based passive ISO 7816 sniffer that emits the same GSMTAP-SIM stream a passive ISO 7816 sniffer built on a cheap FX2 logic analyser.
on UDP 4729 (accepted by this project's GSMTAP listener).
The bundled capture utility also sniffs from the upstream
[simtrace2](https://gitea.osmocom.org/sim-card/simtrace2) hardware/firmware
project.
## License ## License
MIT — see [LICENSE](LICENSE). The decoders and the PWA's DES/3DES MIT — see [LICENSE](LICENSE). The decoders and the UI's DES/3DES
implementation are original, written from the ISO 7816, ETSI and 3GPP implementation are original, written from the ISO 7816, ETSI and 3GPP
specifications; no third-party code is bundled. PyUSB (BSD-3-Clause) is a specifications; no third-party code is bundled. PyUSB (BSD-3-Clause) is a
runtime dependency for direct hardware capture. runtime dependency for direct hardware capture.
+82 -46
View File
@@ -1,7 +1,9 @@
# SIMtrace Analyser # SIMtrace Analyser — анализатор APDU-трассировок GSMTAP-SIM
[English](README.md) | Русский [English](README.md) | Русский
📢 Новости и обновления проекта: [сайт](https://atroshin.ru) · [Telegram-канал](https://t.me/youeyeseesee)
Анализатор APDU-трассировок в формате GSMTAP-SIM — захватывает обмен с Анализатор APDU-трассировок в формате GSMTAP-SIM — захватывает обмен с
SIM/UICC из UDP-потока GSMTAP (или импортирует файлы PCAP/PCAPNG), SIM/UICC из UDP-потока GSMTAP (или импортирует файлы PCAP/PCAPNG),
декодирует его и отдаёт устанавливаемое веб-приложение для просмотра. декодирует его и отдаёт устанавливаемое веб-приложение для просмотра.
@@ -9,9 +11,9 @@ SIM/UICC из UDP-потока GSMTAP (или импортирует файлы
на Python, которая захватывает трафик с оборудования Osmocom SIMtrace2 на Python, которая захватывает трафик с оборудования Osmocom SIMtrace2
и может передавать GSMTAP этому анализатору. и может передавать GSMTAP этому анализатору.
📢 Новости и обновления проекта: [atroshin.ru](https://atroshin.ru) | [Telegram-канал](https://t.me/youeyeseesee) ![Интерфейс SIMtrace Analyser](frontend.png)
![PWA SIMtrace Analyser](frontend.png) ![Захват и анализ: оборудование SIMtrace2 читает simtrace2-pysniff или оригинальный simtrace2-sniff, а оборудование FX2 — декодер sigrok_iso7816_stream; они и SIMple передают GSMTAP-SIM слушателю UDP :4729. Сервер также может читать оборудование SIMtrace2 напрямую по USB встроенным кодом pysniff внутри сервера и импортирует трассы PCAP/COMPRION из файлов. simtrace-analyser-server декодирует и сохраняет трафик в SQLite и раздаёт веб-интерфейс](architecture_ru.svg)
## Требования ## Требования
@@ -37,12 +39,12 @@ SIM/UICC из UDP-потока GSMTAP (или импортирует файлы
## Быстрый старт ## Быстрый старт
Три способа запустить анализатор; все они отдают одну и ту же PWA на Три способа запустить анализатор; все они отдают один и тот же веб-интерфейс на
http://127.0.0.1:8081/. http://127.0.0.1:8081/.
### 1. Wheel (pip) ### 1. Wheel (pip)
Wheel содержит PWA внутри пакета, поэтому сервер отдаёт интерфейс сам: Wheel содержит интерфейс внутри пакета, поэтому сервер отдаёт его сам:
```sh ```sh
pip install ./simtrace_analyser-2.7.13-py3-none-any.whl pip install ./simtrace_analyser-2.7.13-py3-none-any.whl
@@ -65,11 +67,11 @@ gh release download --pattern '*.whl'
pip install ./simtrace_analyser-*.whl pip install ./simtrace_analyser-*.whl
``` ```
### 2. Zip (для Windows, без установки) ### 2. Zip (без установки)
Скачайте `simtrace-analyser-2.7.13.zip` со страницы релиза и распакуйте в любое Скачайте `simtrace-analyser-2.7.13.zip` со страницы релиза и распакуйте в любое
место: это рабочее дерево (пакеты Python, PWA, скрипты запуска и документация — место: это рабочее дерево (пакеты Python, интерфейс, скрипты запуска и документация —
без тестов и git). Затем запустите. без тестов и git). Архив подходит для любой ОС. Затем запустите.
Windows: Windows:
@@ -86,8 +88,8 @@ Linux/macOS:
Python 3 должен быть в `PATH`; `pip install pyusb` нужен только для прямого Python 3 должен быть в `PATH`; `pip install pyusb` нужен только для прямого
захвата с SIMtrace2. Скрипты принимают параметры сервера захвата с SIMtrace2. Скрипты принимают параметры сервера
(`start.bat --capture direct`, `./start.sh --capture direct --port 8080`). (`start.bat --capture direct`, `./start.sh --capture direct --port 8080`).
(Архив *Source code* из релиза — это полное дерево вместе с тестами; он (Архивы *Source code (zip / tar.gz)* из релиза — это полное дерево вместе с
работает так же, как клон ниже.) тестами; они работают так же, как клон ниже.)
### 3. Клон репозитория (для разработки) ### 3. Клон репозитория (для разработки)
@@ -115,37 +117,60 @@ simtrace-analyser-server --capture gsmtap
сервер. сервер.
- `--capture gsmtap` (по умолчанию) — слушать GSMTAP-SIM на UDP 4729, - `--capture gsmtap` (по умолчанию) — слушать GSMTAP-SIM на UDP 4729,
например от `simtrace2-pysniff` или `sigrok_iso7816_stream`; например от `simtrace2-pysniff`, оригинального `simtrace2-sniff`,
- `--capture direct` — читать оборудование SIMtrace2 напрямую (нужен PyUSB; в `sigrok_iso7816_stream` или [SIMple](https://github.com/anttro/simple);
Windows также нужна замена драйвера, см. - `--capture direct` — читать оборудование SIMtrace2 напрямую (встроенный код
сниффера работает внутри сервера и обращается к устройству по USB; нужен
PyUSB; в Windows также нужна замена драйвера, см.
[Доступ к USB-устройству](#доступ-к-usb-устройству)); [Доступ к USB-устройству](#доступ-к-usb-устройству));
- `--capture disabled` — только просмотр сохранённых захватов. - `--capture disabled` — только просмотр сохранённых захватов.
Полное руководство по работе (параметры сервера, экраны PWA, утилита захвата) Полное руководство по работе (параметры сервера, экраны интерфейса, утилита захвата)
находится в разделе [Использование](#использование). находится в разделе [Использование](#использование).
## Использование ## Использование
### Анализирующий сервер + PWA (`simtrace-analyser-server`) ### Анализирующий сервер + интерфейс (`simtrace-analyser-server`)
Сохраняет захваченный APDU-трафик в SQLite и отдаёт его по HTTP вместе Сохраняет захваченный APDU-трафик в SQLite и отдаёт его по HTTP вместе
со встроенной PWA **SIMtrace Analyser** (`frontend/` в исходном клоне, при со встроенным фронтендом **SIMtrace Analyser** (`frontend/` в исходном клоне, при
установке — внутри пакета) на том же origin. установке — внутри пакета) на том же origin.
Команды ниже — консольная команда; при запуске из клона скрипты принимают те
же параметры (`./start.sh --capture gsmtap`, `start.bat --capture gsmtap`).
Три режима захвата: Три режима захвата:
```sh ```sh
# Слушать GSMTAP от simtrace2-pysniff (или оригинального simtrace2-sniff): # Слушать GSMTAP от simtrace2-pysniff, оригинального simtrace2-sniff,
# sigrok_iso7816_stream или SIMple:
simtrace-analyser-server --capture gsmtap simtrace-analyser-server --capture gsmtap
# Захват напрямую с оборудования SIMtrace2 (внешний инструмент не нужен): # Захват напрямую с оборудования SIMtrace2 (встроенный код сниффера читает
# устройство; внешний инструмент и GSMTAP не нужны):
simtrace-analyser-server --capture direct simtrace-analyser-server --capture direct
# Просмотр/анализ существующих записей без бэкенда захвата: # Просмотр/анализ существующих записей без бэкенда захвата:
simtrace-analyser-server --capture disabled simtrace-analyser-server --capture disabled
``` ```
При запуске из клона или рабочего zip те же режимы доступны через скрипты
запуска.
Linux/macOS:
```sh
./start.sh --capture gsmtap
./start.sh --capture direct
./start.sh --capture disabled
```
Windows:
```bat
start.bat --capture gsmtap
start.bat --capture direct
start.bat --capture disabled
```
Параметры передаются как есть (`./start.sh --capture direct --port 8080`).
Сервер пишет в stderr информацию о жизненном цикле захвата (каждая строка Сервер пишет в stderr информацию о жизненном цикле захвата (каждая строка
с локальным временем): `Capture started` при старте, периодический с локальным временем): `Capture started` при старте, периодический
heartbeat `Capture alive: session=N messages=M bytes=B dropped=D skipped=S` heartbeat `Capture alive: session=N messages=M bytes=B dropped=D skipped=S`
@@ -155,7 +180,7 @@ heartbeat `Capture alive: session=N messages=M bytes=B dropped=D skipped=S`
убивают захват; `tpdu`-пакет, вовсе не похожий на APDU (короче заголовка, убивают захват; `tpdu`-пакет, вовсе не похожий на APDU (короче заголовка,
недопустимый CLA `FF` или зарезервированный ISO класс `001x`), недопустимый CLA `FF` или зарезервированный ISO класс `001x`),
пропускается и считается (`skipped`) — посимвольный или миссемплированный пропускается и считается (`skipped`) — посимвольный или миссемплированный
поток больше не засоряет декодирование. Интервал heartbeat по умолчанию поток не засоряет декодирование. Интервал heartbeat по умолчанию
60 с, настраивается через `--log-interval SECONDS`. 60 с, настраивается через `--log-interval SECONDS`.
GSMTAP-листенер также принимает декодер **sigrok-iso7816-stream** GSMTAP-листенер также принимает декодер **sigrok-iso7816-stream**
@@ -184,7 +209,7 @@ RST несёт измеренную частоту CLK (декодер v1.9.0+,
(табулированный текст) из COMPRION Device Manager — байтовое представление (табулированный текст) из COMPRION Device Manager — байтовое представление
протокола (ATR, PPS, APDU с кодами возврата). Экспорт *ISO Application протокола (ATR, PPS, APDU с кодами возврата). Экспорт *ISO Application
Layer* не содержит необработанных байтов ответов и не нужен; при его выборе Layer* не содержит необработанных байтов ответов и не нужен; при его выборе
выводится указание на файл Protocol Layer (та же проверка выполняется в PWA выводится указание на файл Protocol Layer (та же проверка выполняется в интерфейсе
до загрузки и на сервере — для вызовов API). до загрузки и на сервере — для вызовов API).
Обмены перекодируются в такие же «проводные» TPDU, какие несёт захват Обмены перекодируются в такие же «проводные» TPDU, какие несёт захват
@@ -305,24 +330,25 @@ TS 51.011), поэтому FID, повторно используемый в р
--gsmtap-port PORT UDP-порт листенера GSMTAP (по умолчанию: 4729) --gsmtap-port PORT UDP-порт листенера GSMTAP (по умолчанию: 4729)
--gsmtap-bind ADDR UDP-адрес привязки листенера GSMTAP (по умолчанию: 127.0.0.1; --gsmtap-bind ADDR UDP-адрес привязки листенера GSMTAP (по умолчанию: 127.0.0.1;
используйте 0.0.0.0, чтобы принимать из Docker-сети или с другого хоста) используйте 0.0.0.0, чтобы принимать из Docker-сети или с другого хоста)
--web-dir PATH каталог статических файлов PWA (по умолчанию: PWA внутри --web-dir PATH каталог статических файлов интерфейса (по умолчанию:
установленного пакета или <repo>/frontend при запуске из исходников) фронтенд внутри установленного пакета или
<repo>/frontend при запуске из исходников)
``` ```
Затем откройте **http://127.0.0.1:8081/** в браузере. Используйте Затем откройте **http://127.0.0.1:8081/** в браузере. Используйте
`--web-dir PATH`, чтобы отдавать другой каталог PWA (по умолчанию: PWA внутри `--web-dir PATH`, чтобы отдавать другой каталог интерфейса (по умолчанию:
пакета или `<repo>/frontend` при запуске из исходников). фронтенд внутри пакета или `<repo>/frontend` при запуске из исходников).
### Размещённая PWA (лендинг) ### Размещённый интерфейс (лендинг)
Автономная копия PWA размещена на **https://simtrace.atroshin.ru**. Автономная копия интерфейса размещена на **https://simtrace.atroshin.ru**.
Это чистый фронтенд: укажите в нём (Settings → Server URL) адрес Это только интерфейс: укажите в нём (Settings → Server URL) адрес
локально запущенного `simtrace-analyser-server`. локально запущенного `simtrace-analyser-server`.
> **Ограничение браузера:** это единственная схема, где PWA и API находятся на > **Ограничение браузера:** это единственная схема, где интерфейс и API
> разных origin, поэтому браузер применяет правила CORS и Private Network > находятся на разных origin, поэтому браузер применяет правила CORS и
> Access. Доступ к локальному серверу (`http://127.0.0.1:8081`) требует двух > Private Network Access. Доступ к локальному серверу
> вещей: сервер должен отправлять > (`http://127.0.0.1:8081`) требует двух вещей: сервер должен отправлять
> `Access-Control-Allow-Private-Network: true` (этот сервер отправляет), > `Access-Control-Allow-Private-Network: true` (этот сервер отправляет),
> и браузер должен иметь разрешение на доступ к локальной сети — > и браузер должен иметь разрешение на доступ к локальной сети —
> в Chrome/Edge/Vivaldi: Настройки сайта → Доступ к локальной сети → > в Chrome/Edge/Vivaldi: Настройки сайта → Доступ к локальной сети →
@@ -479,8 +505,8 @@ Python 3 должен быть в `PATH` (проверьте `python --version`
## Компоненты ## Компоненты
- **Анализирующий сервер + PWA** (`simtrace-analyser-server`) — сохраняет - **Анализирующий сервер + интерфейс** (`simtrace-analyser-server`) — сохраняет
захваченный трафик в SQLite, декодирует его и отдаёт PWA захваченный трафик в SQLite, декодирует его и отдаёт интерфейс
([`frontend/`](frontend/)) вместе с HTTP API на одном origin. Три режима ([`frontend/`](frontend/)) вместе с HTTP API на одном origin. Три режима
захвата: GSMTAP-листенер, захват напрямую с оборудования SIMtrace2 или захвата: GSMTAP-листенер, захват напрямую с оборудования SIMtrace2 или
отключённый захват (только просмотр существующих записей). отключённый захват (только просмотр существующих записей).
@@ -489,13 +515,13 @@ Python 3 должен быть в `PATH` (проверьте `python --version`
PCAP-файлы. Это один из нескольких источников GSMTAP, которые принимает PCAP-файлы. Это один из нескольких источников GSMTAP, которые принимает
анализатор (см. также анализатор (см. также
[sigrok_iso7816_stream](https://github.com/anttro/sigrok_iso7816_stream)). [sigrok_iso7816_stream](https://github.com/anttro/sigrok_iso7816_stream)).
- **PWA** ([`frontend/`](frontend/)) — окно трассировки с декодированными - **Интерфейс** ([`frontend/`](frontend/)) — окно трассировки с декодированными
APDU, SIM Toolkit, SMS и SCP80 OTA; сессии, импорт PCAP и трасс COMPRION, APDU, SIM Toolkit, SMS и SCP80 OTA; сессии, импорт PCAP и трасс COMPRION,
интерфейс EN/RU. интерфейс EN/RU.
## Возможности ## Возможности
**Декодер APDU** (на стороне сервера, отображается в PWA): **Декодер APDU** (на стороне сервера, отображается в интерфейсе):
- Полное декодирование APDU — CLA по ISO 7816-4 / ETSI с **логическим - Полное декодирование APDU — CLA по ISO 7816-4 / ETSI с **логическим
каналом 0-19** (стандартные каналы из b2-b1, расширенные 4-19 из b4-b1 каналом 0-19** (стандартные каналы из b2-b1, расширенные 4-19 из b4-b1
@@ -533,7 +559,7 @@ Python 3 должен быть в `PATH` (проверьте `python --version`
`8 or more` у карт с расширенными каналами) и завершающий индикатор `8 or more` у карт с расширенными каналами) и завершающий индикатор
состояния (LCS/SW) состояния (LCS/SW)
**PWA SIMtrace Analyser** ([`frontend/`](frontend/)): **Интерфейс SIMtrace Analyser** ([`frontend/`](frontend/)):
- Окно трассировки с режимами «Карта»/«Список» — proactive, - Окно трассировки с режимами «Карта»/«Список» — proactive,
TERMINAL RESPONSE, ENVELOPE и AUTH-команды выделяются в режиме карты TERMINAL RESPONSE, ENVELOPE и AUTH-команды выделяются в режиме карты
@@ -545,20 +571,30 @@ Python 3 должен быть в `PATH` (проверьте `python --version`
«Файловые операции»: SELECT, «Файловые операции»: SELECT,
READ/UPDATE BINARY и READ/UPDATE RECORD, вместе с GET RESPONSE, несущим READ/UPDATE BINARY и READ/UPDATE RECORD, вместе с GET RESPONSE, несущим
данные выбранной команды) данные выбранной команды)
- Устанавливаемая PWA, тёмная тема, интерфейс на английском/русском - **PWA** (progressive web app): устанавливается на рабочий стол или домашний
экран и работает офлайн; тёмная тема, интерфейс на английском/русском
## Связанные проекты ## Связанные инструменты
- **[simtrace2](https://gitea.osmocom.org/sim-card/simtrace2)** — вышестоящий SIMple, SIMtrace Analyser и sigrok_iso7816_stream — три автономных
проект оборудования/прошивки SIMtrace2, с которого утилита захвата инструмента для работы с SIM/UICC-картами, представленные на одном
снимает трафик. [сайте](https://atroshin.ru) и в одном [Telegram-канале](https://t.me/youeyeseesee).
Каждый полностью независим — устанавливайте только нужные вам:
- **[SIMple](https://github.com/anttro/simple)** — мастерская для UICC/SIM:
конструкторы APDU, OTA SCP80/SCP81, симуляция SIM Toolkit и профилирование
карт.
- **[SIMtrace Analyser](https://github.com/anttro/simtrace-analyser)** —
анализатор APDU-трассировок GSMTAP-SIM.
- **[sigrok_iso7816_stream](https://github.com/anttro/sigrok_iso7816_stream)** — - **[sigrok_iso7816_stream](https://github.com/anttro/sigrok_iso7816_stream)** —
пассивный ISO 7816 сниффер на базе FX2LP, выдающий такой же поток пассивный ISO 7816-сниффер на дешёвом логическом анализаторе FX2.
GSMTAP-SIM на UDP 4729 (принимается GSMTAP-листенером этого проекта).
Встроенная утилита захвата также снимает трафик с вышестоящего проекта
оборудования/прошивки [simtrace2](https://gitea.osmocom.org/sim-card/simtrace2).
## Лицензия ## Лицензия
MIT — см. [LICENSE](LICENSE). Декодеры и реализация DES/3DES в PWA написаны MIT — см. [LICENSE](LICENSE). Декодеры и реализация DES/3DES в интерфейсе написаны
самостоятельно по спецификациям ISO 7816, ETSI и 3GPP; сторонний код в проект самостоятельно по спецификациям ISO 7816, ETSI и 3GPP; сторонний код в проект
не включён. PyUSB (BSD-3-Clause) — зависимость для прямого захвата с не включён. PyUSB (BSD-3-Clause) — зависимость для прямого захвата с
оборудования. оборудования.
+78
View File
@@ -0,0 +1,78 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="960" height="640" viewBox="0 0 960 640" role="img" aria-labelledby="diagram-title diagram-desc" font-family="'Segoe UI', 'Helvetica Neue', Arial, 'DejaVu Sans', sans-serif">
<title id="diagram-title">SIMtrace Analyser: capture and analysis</title>
<desc id="diagram-desc">SIMtrace2 hardware is read by simtrace2-pysniff (bundled) or the original simtrace2-sniff, and FX2 hardware by the sigrok_iso7816_stream decoder; the sniffers, the decoder and SIMple stream GSMTAP-SIM to the listener on UDP :4729. The server can also read SIMtrace2 hardware directly over USB with the bundled sniffer code, and imports PCAP/COMPRION traces from files. simtrace-analyser-server decodes and stores the traffic in SQLite and serves the web UI.</desc>
<defs>
<marker id="arrow" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
<path d="M0 0 L10 5 L0 10 Z" fill="#64748b"/>
</marker>
</defs>
<rect x="1" y="1" width="958" height="638" rx="18" fill="#ffffff" stroke="#e2e8f0" stroke-width="1.5"/>
<text x="480" y="30" text-anchor="middle" font-size="14" fill="#475569">capture → analyse</text>
<!-- capture devices -->
<rect x="100" y="48" width="250" height="64" rx="12" fill="#f8fafc" stroke="#cbd5e1" stroke-width="1.5"/>
<text x="225" y="74" text-anchor="middle" font-size="15" font-weight="600" fill="#0f172a">SIMtrace2 hardware</text>
<text x="225" y="94" text-anchor="middle" font-size="12" fill="#475569">Osmocom USB sniffer</text>
<rect x="610" y="48" width="250" height="64" rx="12" fill="#f8fafc" stroke="#cbd5e1" stroke-width="1.5"/>
<text x="735" y="74" text-anchor="middle" font-size="15" font-weight="600" fill="#0f172a">FX2 logic analyzer</text>
<text x="735" y="94" text-anchor="middle" font-size="12" fill="#475569">Saleae clone</text>
<line x1="225" y1="112" x2="225" y2="148" stroke="#64748b" stroke-width="2" marker-end="url(#arrow)"/>
<line x1="735" y1="112" x2="735" y2="148" stroke="#64748b" stroke-width="2" marker-end="url(#arrow)"/>
<!-- sniffers -->
<rect x="100" y="150" width="250" height="96" rx="12" fill="#eff6ff" stroke="#93c5fd" stroke-width="1.5"/>
<text x="225" y="176" text-anchor="middle" font-size="14" font-weight="600" fill="#0f172a">SIMtrace2 sniffers</text>
<text x="225" y="202" text-anchor="middle" font-size="13" fill="#334155" font-family="'Cascadia Mono', Consolas, 'DejaVu Sans Mono', monospace">simtrace2-pysniff</text>
<text x="225" y="224" text-anchor="middle" font-size="13" fill="#334155" font-family="'Cascadia Mono', Consolas, 'DejaVu Sans Mono', monospace">simtrace2-sniff (Osmocom)</text>
<rect x="610" y="150" width="250" height="96" rx="12" fill="#f5f3ff" stroke="#c4b5fd" stroke-width="1.5"/>
<text x="735" y="190" text-anchor="middle" font-size="14" font-weight="600" fill="#0f172a" font-family="'Cascadia Mono', Consolas, 'DejaVu Sans Mono', monospace">sigrok_iso7816_stream</text>
<text x="735" y="212" text-anchor="middle" font-size="13" fill="#475569">decoder</text>
<!-- a secondary GSMTAP-SIM source: SIMple can stream its APDUs -->
<rect x="395" y="166" width="170" height="64" rx="12" fill="#ecfeff" stroke="#a5f3fc" stroke-width="1.5"/>
<text x="480" y="192" text-anchor="middle" font-size="16" font-weight="600" fill="#0f172a">SIMple</text>
<text x="480" y="212" text-anchor="middle" font-size="12" fill="#475569">APDU → GSMTAP</text>
<line x1="225" y1="246" x2="425" y2="278" stroke="#64748b" stroke-width="2" marker-end="url(#arrow)"/>
<line x1="480" y1="230" x2="480" y2="278" stroke="#64748b" stroke-width="2" marker-end="url(#arrow)"/>
<line x1="735" y1="246" x2="535" y2="278" stroke="#64748b" stroke-width="2" marker-end="url(#arrow)"/>
<!-- GSMTAP listener -->
<rect x="350" y="280" width="260" height="72" rx="12" fill="#fffbeb" stroke="#fcd34d" stroke-width="1.5"/>
<text x="480" y="310" text-anchor="middle" font-size="16" font-weight="600" fill="#0f172a" font-family="'Cascadia Mono', Consolas, 'DejaVu Sans Mono', monospace">GSMTAP UDP :4729</text>
<text x="480" y="332" text-anchor="middle" font-size="13" fill="#475569">listener</text>
<!-- file import -->
<rect x="650" y="280" width="240" height="72" rx="12" fill="#f8fafc" stroke="#cbd5e1" stroke-width="1.5"/>
<text x="770" y="310" text-anchor="middle" font-size="14" font-weight="600" fill="#0f172a">PCAP / COMPRION</text>
<text x="770" y="332" text-anchor="middle" font-size="13" fill="#475569">import from files</text>
<line x1="480" y1="352" x2="480" y2="390" stroke="#64748b" stroke-width="2" marker-end="url(#arrow)"/>
<line x1="770" y1="352" x2="635" y2="390" stroke="#64748b" stroke-width="2" marker-end="url(#arrow)"/>
<!-- the direct USB path bypasses the sniffers and GSMTAP -->
<path d="M100 84 H52 V448 H258" fill="none" stroke="#64748b" stroke-width="2" stroke-linejoin="round" marker-end="url(#arrow)"/>
<text x="64" y="418" font-size="12" font-weight="600" fill="#475569">direct USB</text>
<text x="64" y="436" font-size="12" fill="#475569">pysniff code in-process</text>
<!-- analysis server -->
<rect x="260" y="392" width="440" height="84" rx="12" fill="#ecfdf5" stroke="#6ee7b7" stroke-width="1.5"/>
<text x="480" y="427" text-anchor="middle" font-size="18" font-weight="600" fill="#0f172a" font-family="'Cascadia Mono', Consolas, 'DejaVu Sans Mono', monospace">simtrace-analyser-server</text>
<text x="480" y="451" text-anchor="middle" font-size="13" fill="#475569">decodes · stores</text>
<line x1="400" y1="476" x2="250" y2="514" stroke="#64748b" stroke-width="2" marker-end="url(#arrow)"/>
<line x1="560" y1="476" x2="710" y2="514" stroke="#64748b" stroke-width="2" marker-end="url(#arrow)"/>
<!-- storage and UI -->
<rect x="110" y="516" width="280" height="76" rx="12" fill="#f8fafc" stroke="#cbd5e1" stroke-width="1.5"/>
<text x="250" y="548" text-anchor="middle" font-size="18" font-weight="600" fill="#0f172a">SQLite</text>
<text x="250" y="570" text-anchor="middle" font-size="13" fill="#475569">sessions.db</text>
<rect x="570" y="516" width="280" height="76" rx="12" fill="#f8fafc" stroke="#cbd5e1" stroke-width="1.5"/>
<text x="710" y="548" text-anchor="middle" font-size="18" font-weight="600" fill="#0f172a">Browser (web UI)</text>
<text x="710" y="570" text-anchor="middle" font-size="13" fill="#475569">installable PWA</text>
</svg>

After

Width:  |  Height:  |  Size: 6.3 KiB

+78
View File
@@ -0,0 +1,78 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" width="960" height="640" viewBox="0 0 960 640" role="img" aria-labelledby="diagram-title diagram-desc" font-family="'Segoe UI', 'Helvetica Neue', Arial, 'DejaVu Sans', sans-serif">
<title id="diagram-title">SIMtrace Analyser: захват и анализ</title>
<desc id="diagram-desc">Оборудование SIMtrace2 читает simtrace2-pysniff (входит в комплект) или оригинальный simtrace2-sniff, а оборудование FX2 — декодер sigrok_iso7816_stream; они и SIMple передают GSMTAP-SIM слушателю UDP :4729. Сервер также может читать оборудование SIMtrace2 напрямую по USB встроенным кодом сниффера и импортирует трассы PCAP/COMPRION из файлов. simtrace-analyser-server декодирует и сохраняет трафик в SQLite и раздаёт веб-интерфейс.</desc>
<defs>
<marker id="arrow" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
<path d="M0 0 L10 5 L0 10 Z" fill="#64748b"/>
</marker>
</defs>
<rect x="1" y="1" width="958" height="638" rx="18" fill="#ffffff" stroke="#e2e8f0" stroke-width="1.5"/>
<text x="480" y="30" text-anchor="middle" font-size="14" fill="#475569">захват → анализ</text>
<!-- устройства захвата -->
<rect x="100" y="48" width="250" height="64" rx="12" fill="#f8fafc" stroke="#cbd5e1" stroke-width="1.5"/>
<text x="225" y="74" text-anchor="middle" font-size="15" font-weight="600" fill="#0f172a">Оборудование SIMtrace2</text>
<text x="225" y="94" text-anchor="middle" font-size="12" fill="#475569">USB-сниффер Osmocom</text>
<rect x="610" y="48" width="250" height="64" rx="12" fill="#f8fafc" stroke="#cbd5e1" stroke-width="1.5"/>
<text x="735" y="74" text-anchor="middle" font-size="15" font-weight="600" fill="#0f172a">Логический анализатор FX2</text>
<text x="735" y="94" text-anchor="middle" font-size="12" fill="#475569">клон Saleae</text>
<line x1="225" y1="112" x2="225" y2="148" stroke="#64748b" stroke-width="2" marker-end="url(#arrow)"/>
<line x1="735" y1="112" x2="735" y2="148" stroke="#64748b" stroke-width="2" marker-end="url(#arrow)"/>
<!-- снифферы -->
<rect x="100" y="150" width="250" height="96" rx="12" fill="#eff6ff" stroke="#93c5fd" stroke-width="1.5"/>
<text x="225" y="176" text-anchor="middle" font-size="14" font-weight="600" fill="#0f172a">Снифферы SIMtrace2</text>
<text x="225" y="202" text-anchor="middle" font-size="13" fill="#334155" font-family="'Cascadia Mono', Consolas, 'DejaVu Sans Mono', monospace">simtrace2-pysniff</text>
<text x="225" y="224" text-anchor="middle" font-size="13" fill="#334155" font-family="'Cascadia Mono', Consolas, 'DejaVu Sans Mono', monospace">simtrace2-sniff (Osmocom)</text>
<rect x="610" y="150" width="250" height="96" rx="12" fill="#f5f3ff" stroke="#c4b5fd" stroke-width="1.5"/>
<text x="735" y="190" text-anchor="middle" font-size="14" font-weight="600" fill="#0f172a" font-family="'Cascadia Mono', Consolas, 'DejaVu Sans Mono', monospace">sigrok_iso7816_stream</text>
<text x="735" y="212" text-anchor="middle" font-size="13" fill="#475569">декодер</text>
<!-- второй источник GSMTAP-SIM: SIMple умеет отдавать свои APDU -->
<rect x="395" y="166" width="170" height="64" rx="12" fill="#ecfeff" stroke="#a5f3fc" stroke-width="1.5"/>
<text x="480" y="192" text-anchor="middle" font-size="16" font-weight="600" fill="#0f172a">SIMple</text>
<text x="480" y="212" text-anchor="middle" font-size="12" fill="#475569">APDU → GSMTAP</text>
<line x1="225" y1="246" x2="425" y2="278" stroke="#64748b" stroke-width="2" marker-end="url(#arrow)"/>
<line x1="480" y1="230" x2="480" y2="278" stroke="#64748b" stroke-width="2" marker-end="url(#arrow)"/>
<line x1="735" y1="246" x2="535" y2="278" stroke="#64748b" stroke-width="2" marker-end="url(#arrow)"/>
<!-- слушатель GSMTAP -->
<rect x="350" y="280" width="260" height="72" rx="12" fill="#fffbeb" stroke="#fcd34d" stroke-width="1.5"/>
<text x="480" y="310" text-anchor="middle" font-size="16" font-weight="600" fill="#0f172a" font-family="'Cascadia Mono', Consolas, 'DejaVu Sans Mono', monospace">GSMTAP UDP :4729</text>
<text x="480" y="332" text-anchor="middle" font-size="13" fill="#475569">слушатель</text>
<!-- импорт файлов -->
<rect x="650" y="280" width="240" height="72" rx="12" fill="#f8fafc" stroke="#cbd5e1" stroke-width="1.5"/>
<text x="770" y="310" text-anchor="middle" font-size="14" font-weight="600" fill="#0f172a">Импорт PCAP / COMPRION</text>
<text x="770" y="332" text-anchor="middle" font-size="13" fill="#475569">из файлов</text>
<line x1="480" y1="352" x2="480" y2="390" stroke="#64748b" stroke-width="2" marker-end="url(#arrow)"/>
<line x1="770" y1="352" x2="635" y2="390" stroke="#64748b" stroke-width="2" marker-end="url(#arrow)"/>
<!-- прямой USB-путь минует снифферы и GSMTAP -->
<path d="M100 84 H52 V448 H258" fill="none" stroke="#64748b" stroke-width="2" stroke-linejoin="round" marker-end="url(#arrow)"/>
<text x="64" y="418" font-size="12" font-weight="600" fill="#475569">прямой USB</text>
<text x="64" y="436" font-size="12" fill="#475569">код pysniff внутри сервера</text>
<!-- анализирующий сервер -->
<rect x="260" y="392" width="440" height="84" rx="12" fill="#ecfdf5" stroke="#6ee7b7" stroke-width="1.5"/>
<text x="480" y="427" text-anchor="middle" font-size="18" font-weight="600" fill="#0f172a" font-family="'Cascadia Mono', Consolas, 'DejaVu Sans Mono', monospace">simtrace-analyser-server</text>
<text x="480" y="451" text-anchor="middle" font-size="13" fill="#475569">декодирует · сохраняет</text>
<line x1="400" y1="476" x2="250" y2="514" stroke="#64748b" stroke-width="2" marker-end="url(#arrow)"/>
<line x1="560" y1="476" x2="710" y2="514" stroke="#64748b" stroke-width="2" marker-end="url(#arrow)"/>
<!-- хранилище и интерфейс -->
<rect x="110" y="516" width="280" height="76" rx="12" fill="#f8fafc" stroke="#cbd5e1" stroke-width="1.5"/>
<text x="250" y="548" text-anchor="middle" font-size="18" font-weight="600" fill="#0f172a">SQLite</text>
<text x="250" y="570" text-anchor="middle" font-size="13" fill="#475569">sessions.db</text>
<rect x="570" y="516" width="280" height="76" rx="12" fill="#f8fafc" stroke="#cbd5e1" stroke-width="1.5"/>
<text x="710" y="548" text-anchor="middle" font-size="18" font-weight="600" fill="#0f172a">Браузер (веб-интерфейс)</text>
<text x="710" y="570" text-anchor="middle" font-size="13" fill="#475569">устанавливаемое PWA</text>
</svg>

After

Width:  |  Height:  |  Size: 6.9 KiB

+2
View File
@@ -40,6 +40,8 @@ ROOT_FILES = (
'README.md', 'README.md',
'README_RUS.md', 'README_RUS.md',
'frontend.png', 'frontend.png',
'architecture_en.svg',
'architecture_ru.svg',
'LICENSE', 'LICENSE',
) )
+15
View File
@@ -81,6 +81,21 @@ class TestReleaseZip(unittest.TestCase):
self.assertIn('%s/frontend/%s' % (top, asset), self.names, self.assertIn('%s/frontend/%s' % (top, asset), self.names,
'precached %s is missing from the zip' % asset) 'precached %s is missing from the zip' % asset)
def test_readme_images_are_in_the_zip(self):
# Drift guard: the runtime tree's READMEs embed the screenshot and the
# architecture diagrams by relative path, so every referenced image
# must travel with the archive.
top = 'simtrace-analyser-%s' % __version__
for readme in ('README.md', 'README_RUS.md'):
text = (REPO / readme).read_text()
images = re.findall(r'!\[[^\]]*\]\(([^)\s]+)\)', text)
self.assertTrue(images, 'no images referenced by %s' % readme)
for image in images:
self.assertNotIn('://', image, image)
self.assertIn('%s/%s' % (top, image), self.names,
'%s references %s, which is missing from the zip'
% (readme, image))
def test_batch_files_use_crlf(self): def test_batch_files_use_crlf(self):
with zipfile.ZipFile(self.archive) as zf: with zipfile.ZipFile(self.archive) as zf:
bats = [n for n in self.names if n.endswith('.bat')] bats = [n for n in self.names if n.endswith('.bat')]