Compare commits
7
Commits
6fbe57052f
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
50dba20f04 | ||
|
|
f492f29ea6 | ||
|
|
2b83d21e64 | ||
|
|
9a661f5ab2 | ||
|
|
5a7768e6a9 | ||
|
|
7801c62ca3 | ||
|
|
f18a11edaf |
No files matched your search
@@ -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
|
||||||
|
|||||||
@@ -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)
|

|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## 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
@@ -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)
|

|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## Требования
|
## Требования
|
||||||
|
|
||||||
@@ -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) — зависимость для прямого захвата с
|
||||||
оборудования.
|
оборудования.
|
||||||
@@ -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 |
@@ -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 |
@@ -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',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -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')]
|
||||||
|
|||||||
Reference in new issue
Block a user