关于 logicmso
面向 Saleae Logic MSO 信号采集分析的技能,供硬件调试和协议研究使用。它读取二进制导出文件,分析信号转换与时序,并提供常见协议解码示例。
主要功能
- 01读取 Saleae 二进制导出文件
- 02分析转换时间与脉冲时长
- 03生成时序直方图和聚类
- 04解码 UART、SPI、I2C 和 1-Wire
- 05提供未知协议分析示例
适用场景
- 01检查采集信号的时序特征
- 02识别未知信号协议
- 03解析 UART、SPI 或 I2C 通信
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ brownfinesecurity/ iothackbot --skill logicmso安装后在 Claude Code 中输入/logicmso确认已加载。
附带文件analyze_protocol.pyexamples.md
详细介绍
Saleae Logic MSO 分析
此技能使用 saleae-mso-api Python 库分析从 Saleae Logic MSO 设备捕获的信号。它支持加载二进制导出文件、分析信号转换并解码常见协议。
前置条件
saleae-mso-apiPython 包——**请勿盲目使用 pip install。**先检查是否已安装:
仅当检查失败时,才安装:python3 -c "from saleae.mso_api.binary_files import read_file; print('saleae-mso-api is available')"pip install saleae-mso-api- 从 Saleae Logic 软件导出的二进制文件(
.bin格式)
快速参考
加载二进制文件
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
数字采集结构
数字导出文件包含带有以下分块的 DigitalExport_V1:
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
辅助脚本
此技能包含用于常见分析任务的辅助脚本:
协议分析器
# 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
完整的端到端采集示例请参阅 examples.md,包括未知协议初步分析,以及使用可运行的 Python 进行 UART、SPI、I2C 和 1-Wire 解码。
常见协议模式
UART(异步串行)
- 空闲状态:高电平
- 起始位:低电平(1 个比特周期)
- 数据位:8 位,低位优先
- 停止位:高电平(1–2 个比特周期)
- 常见波特率:9600、19200、38400、57600、115200
- 比特周期计算:
1/baud_rate秒 - 识别特征:比特周期一致,持续时间是基准周期的整数倍
SPI(串行外设接口)
- 4 个信号:SCLK(时钟)、MOSI(主机输出)、MISO(主机输入)、CS(片选)
- 时钟极性(CPOL):空闲时的时钟状态(0=低电平,1=高电平)
- 时钟相位(CPHA):采样边沿(0=前沿,1=后沿)
- 数据:在时钟边沿采样,每次传输通常为 8 位
- 识别特征:时钟信号规律,传输期间 CS 拉低
I2C(集成电路间总线)
- 2 个信号:SDA(数据)、SCL(时钟)
- 空闲状态:均为高电平(由上拉电阻拉高)
- 起始条件:SCL 为高电平时,SDA 从高电平变为低电平
- 停止条件:SCL 为高电平时,SDA 从低电平变为高电平
- 数据:8 位 + ACK/NACK,最高位优先
- 地址:7 位(START 后的第一个字节)
- 识别特征:START/STOP 条件,每个字节有 9 个时钟脉冲(8 个数据位 + ACK)
1-Wire
- 单个信号:DQ(数据/电源)
- 空闲状态:高电平(由上拉电阻拉高)
- 复位脉冲:主机至少将信号拉低 480us
- 存在脉冲:从机响应,将信号拉低 60–240us
- 写入 0:低电平持续 60–120us
- 写入 1:低电平持续 1–15us,然后释放
- 读取:主机拉低信号后 15us 进行采样
分析工作流
步骤 1:初步探索
from 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)}")
步骤 2:分析时序模式
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}")
步骤 3:识别协议
根据时序模式:
- UART:比特周期一致,持续时间是基准周期的整数倍,空闲时为高电平
- SPI/I2C:微秒级时序,需要分析时钟信号,查找规律模式
- 1-Wire:复位脉冲约为 480us,数据脉冲为 1–120us
步骤 4:解码
识别协议后,根据协议规则进行解码。对于未知或自定义协议,分析时序聚类和比特模式,以确定编码方案。
UART 解码示例
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))
CTF 技巧
- 未知协议:先运行
analyze_protocol.py --clusters查看时序分布 - 多个通道:分别导出每个通道,识别时钟线与数据线
- 信号反相:某些采集的逻辑电平是反相的
- 时序变化:真实硬件会有抖动,请使用基于阈值的检测
- 部分采集:检查采集是否从传输中途开始
- 自定义协议:查找重复模式,识别同步/帧定界字节
故障排除
“No module named 'saleae.mso_api'”
先确认该模块确实缺失:
python3 -c "from saleae.mso_api.binary_files import read_file"
仅当导入失败时,才安装:
pip install saleae-mso-api
文件为空或已损坏
检查文件大小,并尝试从 Saleae Logic 软件重新导出。
未检测到信号转换
- 信号可能为恒定电平(一直为高或低)
- 检查是否导出了正确的通道
- 确认原始采集中的触发设置
时间似乎不对
- 检查采样率是否与原始采集设置一致
- 确认时间单位(秒、毫秒还是微秒)
评论
支持 Markdown