From iothackbot
Analyzes digital/analog captures from Saleae Logic MSO devices, decoding protocols like UART, SPI, I2C from exported binary files. Use for CTF challenges, hardware reverse engineering, or protocol analysis.
How this skill is triggered — by the user, by Claude, or both
Slash command
/iothackbot:logicmsoThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
This skill enables analysis of captured signals from Saleae Logic MSO devices using the `saleae-mso-api` Python library. It supports loading binary exports, analyzing signal transitions, and decoding common protocols.
This skill enables analysis of captured signals from Saleae Logic MSO devices using the saleae-mso-api Python library. It supports loading binary exports, analyzing signal transitions, and decoding common protocols.
saleae-mso-api Python package — Do NOT blindly pip install. First check if it's already installed:
python3 -c "from saleae.mso_api.binary_files import read_file; print('saleae-mso-api is available')"
Only if that fails, install it: pip install saleae-mso-api.bin format)from saleae.mso_api.binary_files import read_file
from pathlib import Path
file_path = Path("capture.bin")
saleae_file = read_file(file_path)
# Access metadata
print(f"Version: {saleae_file.version}")
print(f"Type: {saleae_file.type}")
# Access data
contents = saleae_file.contents
Digital exports contain DigitalExport_V1 with chunks:
chunk = saleae_file.contents.chunks[0]
# Key attributes:
chunk.initial_state # Starting logic level (0 or 1)
chunk.transition_times # numpy array of transition timestamps (seconds)
chunk.sample_rate # Capture rate in Hz
chunk.begin_time # Capture start time
chunk.end_time # Capture end time
import numpy as np
times = np.array(chunk.transition_times)
durations_ms = np.diff(times) * 1000 # Convert to milliseconds
# If initial_state is 0 (LOW):
# - Even indices (0, 2, 4...) = HIGH pulse durations
# - Odd indices (1, 3, 5...) = LOW gap durations
# If initial_state is 1 (HIGH):
# - Even indices = LOW gap durations
# - Odd indices = HIGH pulse durations
This skill includes helper scripts for common analysis tasks:
# Analyze signal characteristics
python3 skills/logicmso/analyze_protocol.py capture.bin
# Show detailed timing histogram
python3 skills/logicmso/analyze_protocol.py capture.bin --histogram
# Show detected timing clusters
python3 skills/logicmso/analyze_protocol.py capture.bin --clusters
# Export transitions to CSV
python3 skills/logicmso/analyze_protocol.py capture.bin --export transitions.csv
# Show raw transition values
python3 skills/logicmso/analyze_protocol.py capture.bin --raw -n 50
See examples.md for full worked end-to-end captures: unknown-protocol triage, and UART, SPI, I2C, and 1-Wire decoding with runnable Python.
1/baud_rate secondsfrom saleae.mso_api.binary_files import read_file
import numpy as np
f = read_file("capture.bin")
chunk = f.contents.chunks[0]
print(f"Sample rate: {chunk.sample_rate/1e6:.1f} MHz")
print(f"Duration: {chunk.end_time - chunk.begin_time:.3f}s")
print(f"Initial state: {'HIGH' if chunk.initial_state else 'LOW'}")
print(f"Transitions: {len(chunk.transition_times)}")
times = np.array(chunk.transition_times)
durations_us = np.diff(times) * 1e6 # microseconds
# Separate HIGH and LOW durations
high_idx = 0 if chunk.initial_state == 0 else 1
high_durations = durations_us[high_idx::2]
low_durations = durations_us[(1-high_idx)::2]
print(f"HIGH pulses: min={min(high_durations):.1f}us, max={max(high_durations):.1f}us")
print(f"LOW gaps: min={min(low_durations):.1f}us, max={max(low_durations):.1f}us")
# Find unique timing values (cluster detection)
unique_high = sorted(set(round(d, -1) for d in high_durations)) # Round to 10us
unique_low = sorted(set(round(d, -1) for d in low_durations))
print(f"HIGH clusters: {unique_high}")
print(f"LOW clusters: {unique_low}")
Based on timing patterns:
Once protocol is identified, decode based on protocol rules. For unknown/custom protocols, analyze the timing clusters and bit patterns to determine encoding scheme.
from saleae.mso_api.binary_files import read_file
import numpy as np
f = read_file("uart_capture.bin")
chunk = f.contents.chunks[0]
times = np.array(chunk.transition_times)
BAUD = 115200
BIT_PERIOD = 1 / BAUD
def decode_uart_byte(start_time, times, bit_period):
"""Decode a single UART byte starting at start_time."""
byte_val = 0
for bit_num in range(8):
# Sample at center of each bit (1.5, 2.5, 3.5... bit periods from start)
sample_time = start_time + (1.5 + bit_num) * bit_period
# Find state at sample_time
idx = np.searchsorted(times, sample_time)
state = (chunk.initial_state + idx) % 2
if state:
byte_val |= (1 << bit_num) # LSB first
return byte_val
# Find start bits (falling edges when idle HIGH)
decoded_bytes = []
i = 0
while i < len(times) - 1:
# Look for falling edge (start bit)
if chunk.initial_state == 1 or i > 0:
byte_val = decode_uart_byte(times[i], times, BIT_PERIOD)
decoded_bytes.append(byte_val)
# Skip to next potential start bit (after stop bit)
i += 1
while i < len(times) and times[i] < times[i-1] + 10 * BIT_PERIOD:
i += 1
else:
i += 1
print("Decoded:", bytes(decoded_bytes))
analyze_protocol.py --clusters to see timing distributionFirst verify it's truly missing:
python3 -c "from saleae.mso_api.binary_files import read_file"
Only if the import fails, install it:
pip install saleae-mso-api
Check file size and try re-exporting from Saleae Logic software.
npx claudepluginhub brownfinesecurity/iothackbot --plugin iothackbotCaptures and analyzes network traffic with Wireshark, tcpdump, tshark, Scapy for protocol reverse engineering, security research, and debugging proprietary protocols.
Manipulates binary data via composable CLI pipelines instead of Python scripts. Handles carving, decoding, decrypting, decompressing, and extracting from structured formats and malware samples.
Solves CTF forensics challenges: disk images, memory dumps, PCAPs, log analysis, file carving, deleted file recovery. Covers Volatility, Wireshark/tshark, Sleuth Kit, and carving tools.