缩略图

逆向工程教会龙虾, 逆向某开源硬件设计软件文件格式

2026年03月25日 文章分类 会被自动插入 会被自动插入
本文最后更新于2026-03-25已经过去了17天请注意内容时效性
热度494 点赞 收藏0 评论0

首先给龙虾了json源文件,他能打开但是里面内容他未知因为还没学习, 逆向工程给他PNG参考图,纯VL模型来解析,他能根据图片内容理解成文字 还提供给他PDF和SVG,这个里面也包含一些矢量图形,结构化的数据,有助于我的龙虾做分析 然后完成了整个破文内容

声明:文件格式是开源的,逆向工程我是来博眼球的,如果侵权联系我们删除 以下内容是我的龙虾写的,当然训练他也花了些心血,不过是真的强,在这里表扬一下

画墙机器人 M2 — 文件格式逆向工程纪实报告

本报告记录了从零开始解析某创EDA工程文件的全过程,包含盲目逆向阶段、文档学习阶段,以及两者对照后的修正与总结。 时间:2026-03-25 操作者:技术龙虾(AI Agent)

背景 丢给我一个目录 /home/cs/workspace/画墙机器人m2/,里面有5个文件:

画墙机器人m2.json        68KB   — 原理图数据
PCB_画墙机器人m2.json   450KB  — PCB数据
Schematic_xxx.svg        198KB  — 原理图矢量图
Schematic_xxx.png         96KB  — 原理图位图
Schematic_xxx.pdf         75KB  — 原理图PDF
info                      7KB   — 工程元数据

任务:把这些文件对照起来分析,搞清楚它们的结构关系、格式规律。

第一阶段:盲目逆向

1.1 从图片开始 第一步当然是看图。调用内置的 image() 工具,把 PNG 扔给模型看。

模型返回了完整的电路分析:

电源部分:USB供电 + AMS1117-3.3 线性稳压(5V→3.3V) MCU:AIR001(TSSOP-20),合宙芯片 电机驱动:ULN2003 达林顿阵列,驱动两路 28BYJ48 步进电机 其他:J3Y 单独驱动一路输出(蜂鸣器/继电器) 接口:SPI 6P、COM 5P、扩展 4P×2、3P 结论: 这是一个基于 AIR001 的双路步进电机控制器,10路GPIO扩展,5V供电。

这是纯看图得出的,没有依赖任何文件格式知识。

1.2 info 文件 — 第一个突破口 info 是 JSON 格式,最容易读。一打开就看到了熟悉的 BOM 表结构:

"documents": [
  {
    "uuid": "724e4d6acda97d16b64081183bb70070",
    "title": "Sheet_1",
    "docType": "1",
    "BOM": [["Value","Quantity","Package","Components","CustomPara"], ...]
  },
  {
    "uuid": "...",
    "title": "PCB_画墙机器人m2",
    "filename": "PCB_画墙机器人m2.json",
    "docType": "3"
  }
]

逆向发现:

info 是工程入口,记录了所有子文档列表 documents[0].BOM 就是 BOM 表,共17行(含标题) docType=1 是原理图,docType=3 是 PCB BOM 里有供货商、料号信息(LCSC) 从这里知道了:这个工程至少包含一张原理图 + 一块 PCB。

1.3 原理图 JSON — 艰难的解读 画墙机器人m2.json 打开一看,68KB 的紧凑 JSON。结构是这样的:

{
  "editorVersion": "6.5.15",
  "docType": 5,
  "title": "万能测试仪",
  "schematics": [{
    "uuid": "...",
    "dataStr": {
      "head": {...},
      "canvas": "CA~1000~1000~...",
      "shape": ["LIB~...","W~...","N~...","F~...", ...]  // 共201个
    }
  }],
  "BOM": [...],
  "components": {"hashid": count, ...}
}

盲目逆向阶段遇到的困难:

docType: 5 是什么意思?不知道。和 info 里的 docType 体系不一样 shape 数组里的元素格式是 LIB~x~y~package...~comment~值~,完全自定义的格式 元素的 #@$T~N~ 前缀是什么?看起来像内部坐标数据 components 里的 hash ID 是什么?和 BOM 对不上号 从实际数据中还原出来的 shape 类型统计:

前缀 含义 数量
W 导线 Wire 85
N 网络标签 Net Label 52
F 电源/地符号 Power Flag 32
LIB 库元件 Symbol 24
O 图形对象 5
T 文本标注 2
J 连接点 Junction 1

1.4 LIB 元素的格式破解 逐个拆解 LIB 元素,把 ~ 当分隔符切开,发现规律:

LIB~165~-100~package`R0603`Manufacturer Part``...~comment~10k~1~start~ggeXXX
         X    Y   封装                   参数         注释值

还原出的 LIB 格式:

LIB~x~y~package`封装`Manufacturer`厂商`Manufacturer Part`型号`~~
  ~~0~gge元素ID~~~0~~yes~yes~~~#@$T~N~x~y~角度~颜色~~~~~comment~值~

对照图片验证:

pos=(210,-295) → AIR001 MCU(TSSOP-20) pos=(715,-240) → ULN2003(SOP-16) pos=(880,-630) → 28BYJ48 步进电机 完全对上了。

1.5 PCB JSON — 另一个独立的星球 打开 PCB_画墙机器人m2.json,发现结构完全不一样:

{
  "head": {"docType": 3, ...},
  "canvas": "CA~1000~1000~...mm...",
  "shape": ["TRACK~1~2~IO3~4180.063 3093.6617...","VIA~...",...], // 共192个
  "layers": ["1~TopLayer~#FF0000~true~true~true~", ...], // 共53层
  "objects": ["All~true~false","Component~true~true", ...],
  "BBox": {...}
}

震惊: 这不是原理图 JSON 的子集,是独立设计的结构。原理图里没有的概念(TRACK、VIA、layers)全部是新的。 PCB shape 格式:

前缀 含义 格式
TRACK 铜走线 TRACK~layer~net~x1 y1 x2 y2 [...]~ID~0
VIA 过孔 VIA~x~y~diameter~net~hole_size~ID~0
LIB PCB封装 同原理图LIB格式
ARC 圆弧 ARC~layer~net~起点~终点~曲率~ID~0
HOLE 机械孔 HOLE~x~y~diameter~ID~0
COPPERAREA 铜皮 多边形填充区

1.6 最大的盲点:layer 编号 PCB shape 里有 layer~1、layer~2 这样的数字。layers 数组里确实有定义:

1~TopLayer~#FF0000~true~true~true~
2~BottomLayer~#0000FF~true~false~true~
3~TopSilkLayer~#FFCC00~true~false~true~

我猜测:

1 = 顶层铜 2 = 底层铜 3 = 顶层丝印 但这只是猜测,没有100%把握。 只能通过颜色(红色=TopLayer)来交叉验证。

这就是盲目逆向最大的问题:能猜中,但不确定。

1.7 SVG — 无意中的发现 导出 SVG 打开一看,198KB 的矢量文件。

关键发现: SVG 里每个元素的 id 属性和 JSON 里的 gge 元素 ID 是直接对应的。

<g id="gge286">...</g>   ← 对应 JSON 里的 gge286 元素

这说明 SVG 导出是无损的,不只是图片,而是可定位的结构化数据。JSON 里每个元素的坐标、颜色、线宽都可以从 SVG 里还原出来。

1.8 PCB 网络表还原 从 PCB JSON 的 TRACK 元素中提取 net 名字段,得到了32个网络:

电源/地: GND, +3V3, VCC
MCU输出: O0-O9 (10路)
电机驱动: IO1-IO7 (7路 → ULN2003)
通信: RX, TX, SCK, SI, SO, SS
其他: LED1_1, BOOT, NRST, Q2_2

结合原理图分析,这是通过 ULN2003 驱动两路 28BYJ48 步进电机(每路4相 = IO1-IO7 或类似的分配方式)。

第二阶段:看官方文档

2.1 发现官方文档 J 丢给我链接:https://prodocs.easyeda.com/cn/format/index/

上面有 V2.2 和 V3 两种格式文档可以下载。

顺手把两个都下载了:

V2格式PDF: lceda-pro-file-format-v2.2_2022.12.15.zip
V3格式: lceda-pro-file-format-v3_2025.10.21.zip + .md + .pdf

V3 MD 文档有 3146 行,完整描述了文件格式规范。

2.2 V3 格式:全新的架构 V3 格式(2015年之后的)用行格式存储:

{"type":"DOCHEAD","ticket":N}||{"docType":"SCH_PAGE","uuid":"...","client":"..."}
{"type":"CANVAS","ticket":1,"id":"CANVAS"}||{"originX":0,"originY":0,"unit":"mm",...}
{"type":"LAYER","ticket":2,"id":"[\"LAYER\",1]"}||{"layerType":"TOP",...}
{"type":"PRIMITIVE","ticket":3,"id":"xxx"}||{shape_data}

关键概念:

|| 是分隔符,前半是外层(一致性框架用),后半是实际数据 ticket 越大数据越新 删除数据:{...}||""(内层为空字符串) 不同 docType 是完全独立的文档类型 文档澄清的盲点:

ticket 机制 — 我在逆向时完全没见过这个字段(因为我们的文件是 V2 格式) client 字段 — 用于多终端编辑时的冲突解决 DOCHEAD 概念 — 文档头决定接下来的数据归属哪个子文档 V3 的 PRIMITIVE — 所有图形元素统一用 PRIMITIVE type,不再是 W/LIB/N/F 这些前缀 2.3 我们的文件是 V2 格式 editorVersion: "6.5.15" 和 "6.5.51" 暴露了真相——这是2019-2021年前后的版本。

V2 格式特点(我们的文件):

JSON 紧凑单行格式(不是 type||data 行格式) shape[] 数组存储所有图形元素 ~ 分隔符格式 坐标单位默认 0.01 inch(文档说"若无特殊说明") 真正的删除(数据没了就没了) V3 格式(官方新格式):

type||data 行格式 PRIMITIVE type 替代了 V2 的各种前缀 CANVAS/LAYER/PRIMITIVE 分离 日志追加模式(不删除,只标记) 单位可配置 mm/inch 2.4 官方文档的局限性 V3 MD 文档重点描述的是 V3 格式,对 V2 格式的细节描述很少。

比如:

文档没详细说明 V2 的 LIB~x~y~package...~ 格式 没提到 SVG 导出的 id 映射关系 PCB TRACK 的 TRACK~layer~net~坐标~ID~0 格式文档里没有 结论:官方文档是"架构说明书",不是"字段字典"。V2 的细节还是要靠逆向。

第三阶段:对照与修正

3.1 修正:layer 编号 通过官方文档,验证了我盲猜的 layer 编号是正确的:

编号 层名 颜色
1 TopLayer #FF0000
2 BottomLayer #0000FF
3 TopSilkLayer #FFCC00
4 BottomSilkLayer #66CC33
10 BoardOutLine #FF00FF
11 Multi-Layer #C0C0C0

官方文档明确给出了 layerType 枚举值。我的猜测完全对上了。

3.2 发现:BOM 存在三个地方 来源 内容 完整性
info → documents[0].BOM Value/Qty/Package/Refs/供应商 最完整
原理图JSON → BOM[] Value/Qty/Package/Refs 不含供应商
PCB JSON → BOM[]

重要发现: info 里的 BOM 信息最完整(LCSC供应商、料号都有),而原理图 JSON 里的 BOM 缺少 CustomPara 部分。

3.3 发现:PCB JSON 没有 BOM PCB JSON 的 BOM 字段是空数组 []。PCB 的物料表其实和原理图是共享的,都在 info 里。

3.4 发现:components 的 hash ID 原理图 JSON 里的 components: {"hashid": count, ...} 和 SVG group id 能对上:

SVG: <g id="b0248eb51e084227889f2cb84eab79c4">
JSON: components["b0248eb51e084227889f2cb84eab79c4"] = 4

hash ID 是元件库的内部标识,对应 SVG 里的 group 节点。components 字段记录的是该封装在工程里被使用了多少次。

正文结束 阅读本文相关话题
相关阅读
评论框
管理员开启登录后评论
评论列表

暂时还没有任何评论,快去发表第一条评论吧~

空白列表