mcpField
L
logicmso

logicmso

github.com/brownfinesecurity安全87541 次安装21 周前更新
代码仓库

关于 logicmso

面向 Saleae Logic MSO 信号采集分析的技能,供硬件调试和协议研究使用。它读取二进制导出文件,分析信号转换与时序,并提供常见协议解码示例。

主要功能

  1. 01读取 Saleae 二进制导出文件
  2. 02分析转换时间与脉冲时长
  3. 03生成时序直方图和聚类
  4. 04解码 UART、SPI、I2C 和 1-Wire
  5. 05提供未知协议分析示例

适用场景

  1. 01检查采集信号的时序特征
  2. 02识别未知信号协议
  3. 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-api Python 包——**请勿盲目使用 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 技巧

  1. 未知协议:先运行 analyze_protocol.py --clusters 查看时序分布
  2. 多个通道:分别导出每个通道,识别时钟线与数据线
  3. 信号反相:某些采集的逻辑电平是反相的
  4. 时序变化:真实硬件会有抖动,请使用基于阈值的检测
  5. 部分采集:检查采集是否从传输中途开始
  6. 自定义协议:查找重复模式,识别同步/帧定界字节

故障排除

“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