Files
dwarf_protocol/00_methodology.md
Jacquin Antoine be87e8a4ca Add complete DWARFLAB protocol documentation
- Architecture overview, BLE and WebSocket protocols
- All 19 modules with command IDs validated against smali source
- BLE packet format with CRC-16/MODBUS pseudocode
- Complete WsCmd index (~300 commands)
- Connection flow with pseudocode examples
- Methodology section explaining APK decompilation process
2026-06-13 00:21:19 +02:00

97 lines
5.6 KiB
Markdown

# Methodology & Sources
## How This Documentation Was Obtained
All information in this documentation was extracted through **static analysis of the decompiled DWARFLAB Android APK** (v3.4.0, build 629, package `com.convergence.dwarflab`). No device was needed — the entire protocol is defined in the app's code.
### Decompilation
The APK was decompiled using **apktool v3.4.0**, which produced:
- `AndroidManifest.xml` — permissions, activities, services
- `smali/` through `smali_classes7/` — 7 DEX files of dalvik bytecode
- `lib/` — native `.so` libraries (arm64, armeabi-v7a, x86_64)
- `assets/` — voice JSON, country JSON, keystores
- `res/` — layouts, drawables, Lottie animations
### Key Smali Files Mapped to Protocol Concepts
| Protocol Concept | Smali File | Location |
|-----------------|------------|----------|
| BLE UUIDs | `cg1.smali` | `smali_classes4/` |
| BLE commands | `j80.smali` | `smali_classes4/` |
| BLE packet format | `l80.smali` | `smali_classes4/` |
| BLE CRC-16 | `vc0.smali` | `smali_classes4/` |
| WebSocket URL | `v55.smali` | `smali_classes4/` |
| WsPacket fields | `BaseProto$WsPacket.smali` | `smali_classes5/` |
| WsModuleId | `WsModuleId.smali` | `smali_classes4/` |
| WsCmd (all commands) | `WsCmd.smali` | `smali_classes4/` |
| WsMessageType | `WsMessageType.smali` | `smali_classes4/` |
| WsRespCode | `WsRespCode.smali` | `smali_classes4/` |
| DeviceType | `DeviceType.smali` | `smali_classes4/` |
| BluetoothPacketSender | `BluetoothPacketSender.smali` | `smali_classes4/` |
| ConnectionManager | `ConnectionManager.smali` | `smali_classes4/` |
| Proto messages | `AstroProto*.smali`, `CameraProto*.smali`, etc. | `smali_classes5/` |
### Extraction Methods
#### 1. UUID Discovery (`cg1.smali`)
The `cg1` class contains 8 static UUID strings. Read directly from the `<clinit>` method — the values are string constants embedded in the bytecode.
#### 2. Command IDs (`WsCmd.smali`)
The `WsCmd` enum contains ~300 entries. Each entry is initialized in `<clinit>` via `<init>(String name, int ordinal, int cmd)`. The third parameter (`cmd`) is the numeric command ID. Extracted by tracing register values through the constructor calls.
**Important**: Kotlin enum ordinals and explicit `cmd` IDs are different numbers. The `cmd` value is what goes on the wire.
#### 3. Module IDs (`WsModuleId.smali`)
The `WsModuleId` enum uses **ordinal values only** (no custom id field). Module ID = ordinal position in the enum (0-18).
#### 4. BLE Packet Format (`l80.smali`)
The `l80` class (obfuscated name for `BluetoothPacket`) encodes packets in method `j()`:
- Magic byte `0xAA` at position 0
- 9-byte header: protocolVersion, cmdInstruction, packageSequence, totalPackages, extendedProtocol (2B), validDataLength (2B)
- Payload: protobuf data
- CRC-16 computed by class `vc0` over header+payload
- End marker `0x0D`
The CRC lookup table in `vc0.smali` starts with `{0x0000, 0xC0C1, 0xC181, 0x0140, ...}` which identifies it as CRC-16/MODBUS (reflected polynomial 0xA001 = 0x8005 reflected, init 0xFFFF).
#### 5. WebSocket URL (`v55.smali`)
The URL is assembled by concatenating: `"ws://"` + `yd3.b()` (host IP) + `":9900/?client_id="` + `y32.c()` (client ID). Two additional constants: `0x1139` (4409) and `0x113A` (4410) for secondary ports.
#### 6. DeviceType IDs (`DeviceType.smali`)
The constructor signature is `<init>(String name, int ordinal, int deviceId, int nameResId)`. The `deviceId` parameter is the on-wire device identifier. Careful register tracing is required because smali reuses registers:
- Unknown: deviceId=0
- DWARF_2: deviceId=1
- DWARF_3: deviceId=2
- DWARF_mini: deviceId=4 (ordinal=3, **gap at deviceId=3**)
- DWARF_4: deviceId=5
- DWARF_DRAGON: deviceId=6
#### 7. Proto Message Fields (`smali_classes5/com/convergence/dwarflab/proto/`)
Each `.smali` file in the proto package corresponds to a protobuf message. Field numbers are embedded as constants in the `writeTo()` method (serialized using `writeString(fieldNumber, value)`, `writeInt32(fieldNumber, value)`, etc.). Field names are preserved in the obfuscated class names via Kotlin metadata annotations.
### Limitations
- **Obfuscated names**: Most class names are obfuscated (e.g., `l80`, `cg1`, `j80`). Kotlin metadata annotations help recover some names.
- **No `.proto` files**: The original `.proto` source files are not included in the APK. Field names and numbers are inferred from the generated Java/Kotlin code.
- **String literals**: Some strings (UUIDs, URLs, keys) are embedded directly and can be extracted with certainty. Others require contextual inference.
- **Behavioral details**: Timing, retry logic, and UI flow are inferred from the code but not directly observable without a device.
- **Version-specific**: This documentation corresponds to APK v3.4.0. Newer or older versions may differ.
### Verification
All data points were cross-validated in two passes:
1. **First pass**: Initial extraction from smali source code
2. **Second pass**: Independent re-reading of each smali file to confirm register values, field numbers, and constants
Key verifications:
- All 8 BLE UUIDs confirmed from `cg1.smali`
- All 19 module IDs confirmed from `WsModuleId.smali` (ordinals)
- All ~300 WsCmd command IDs confirmed from `WsCmd.smali` (hex → decimal conversions)
- All 8 WsPacket field numbers confirmed from `BaseProto$WsPacket.smali`
- DeviceType IDs confirmed with register tracing (including the gap at deviceId=3)
- BLE command bytes (0-7) confirmed from `j80.smali`
- BLE packet format confirmed from `l80.smali` (header layout, CRC, end marker)
- WebSocket URL and ports confirmed from `v55.smali`
- CRC-16/MODBUS confirmed from `vc0.smali` lookup table