解码自定义硬件的有线协议(通过 RS232)<-> Windows 应用程序?

逆向工程 ollydbg 编码 串行通讯 料斗
2021-06-18 02:05:31

背景

我有一个带有 RS232 端口的硬件设备,以及一个与之通信的 Windows (XP) 应用程序。除了基本串行之外没有操作系统级驱动程序,因此所有解码都在应用程序中完成。

我有能力捕获双向线路流量,并且通常会在串行端口上进行监听(很好的 Sysinternals Portmon到日志文件,使用一些 perl 后处理(解析IRP_MJ_(READ|WRITE)事件)来获取原始字节转储)。

从这里我得到了基本的有线协议细节(波特率、设置等)

消息似乎采用 格式{ $body }\n,其中发送的命令通常是正文中的单个字节或 2 个字节,响应要复杂得多。

它们跨越多条消息,并且似乎具有额外的结构,例如:

  • 标题 ( {IDCOMPLIANCE ...})
  • 元数据?( {SA...})
  • 数据[+] ({ DL20...})
  • 数据结束指示符 ( {TE5186})

实际示例如下:

> {C}\x0D
< {IDCOMPLIANCE\x20\x20\x20\x20\x20\x20D245}
{SA001FD8BL0001C061BC}
{DL20I000000V80050300DE076A0012000400AF002400FF030300DE0700000000010003000000B883}
{DL20I000020VFF140200DE070900010001000D000100FF0C0200DE076E006E000300A5075904C953}
{DL20I000040VFF0B0200DE07120111010700DE11E406FF0A0200DE070401030105008D12640B3B0C}
{DL20I000060VFF090200DE07F400F400050046112F0AFF080200DE076C016C0107003419950D7181}
{DL20I000080VFF070200DE0753015101060063172A0CFF060200DE07D400D3000A00BE0DF504877D}
{DL20I0000A0VFF050200DE07F200F200040047117309FF040200DE071601150107000414F10C292B}
{DL20I0000C0VFF030200DE07D400D4000500260FC108FF020200DE07B900B90006004C0D26083825}
{DL20I0000E0VFF010200DE07B601B60107001E21F718FF1F0100DE0710010C010900B913150DE89C}
{DL20I000100VFF1E0100DE0785017F010900531A2F0EFF1D0100DE071B01180108001C146D0CE542}
{DL20I000120VFF1C0100DE077E007B0005009C092107FF090100DE0754000100020008000100A748}
{DL20I000140V0000000000000000000000000000000000000000000000000000000000000000D71C}
{DL20I000160V0000000000000000000000000000000000000000000000000000000000000000725F}
{DL20I000180V000000000000000000000000000000000000000000000000000000000000000010A5}
{DL20I0001A0V00000000000000000000000000000000000000000000000000000000000000004CC1}
{TE5186}

我还可以访问控制应用程序,我可以使用该应用程序将某些数据(可能是也可能不完全是通过网络交谈的内容)记录为 CSV 等友好格式。

问题

鉴于我到目前为止的进展主要是将 CSV 输出与电线转储相匹配,尝试更......侵入性地调查实际应用程序是否有任何价值?

我对 asm、windows 二进制文件和 windows 调试的经验很少,但似乎有可能在二进制文件中静态地或在运行时查看,并寻找解码发生的位置。

如果我能找到它,我希望能拼凑出足够的 asm 来了解它是如何生成/解析的,并将其映射到我看到它实际发送的内容。

问题实际上是用我有限的知识找到那些[解码]编码例程。

有两种方法向我建议:

  1. 在调试器中运行,弄清楚如何在串行端口读/写上设置断点,然后从那里逐步查找解码逻辑。

  2. 加载到反编译器中,或者 (a) 跟踪串行读/写的调用,或者 (b) 查找出现在输出 CSV 中的已知字符串,然后返回到使用它们的代码。

[请注意,我在 Mac 上的 VMWare VM 中执行此操作,以防万一]

我目前一直在玩用于 windows 的 OllyDbg 和Hopper Decompiler的演示版本,如果它有用的话,它是负担得起的。

IDA 或 Hex-Rays 会很好,但有点超出我的预算,除非那里有一些东西(例如“解码神秘协议”按钮)可以证明它的合理性。

所以,

  • 有人认识上述格式吗?

  • 是否有更好的 RS232(实际上是通过 USB 串行适配器)嗅探工具?我发现 USBpcap (hxxp://desowin.org/usbpcap/) 可以生成wireshark 跟踪,但是挖掘它以获取实际串行数据很乏味,而且捕获不是实时的。

  • 人们会建议我的下一步行动是什么(继续攻击黑盒 csv/wire-data、反编译或调试?)

  • 如果进行调试,ollydbg 是否能够在串行端口读取上断点(我在哪里可以找到有关如何执行此操作的 n00b 级文档?)

  • 如果反编译,我应该采取什么方法(从端口读取转发,或从 csv/strings 返回?再次,指向如何做到这一点的指针会很棒。)

  • 如果是黑盒,对{DL20...}消息的结构有什么启发吗?

我怀疑它会分解如下内容:

  • DL20- 不确定 20 表示什么。某种长度?

  • I000020 - 显然是某种索引/地址

  • V - 要遵循的“向量”/数组数据的标记?

  • FF140200DE070900010001000D000100 条目 #1

  • FF0C0200DE076E006E000300A5075904 条目 #2

每个条目都包含一个日期(dd/mm/yy,可能是一种奇怪的格式,比如“自罗马沦陷后第一个夏至以来两周的小数”),以及一堆整数和小数(固定点而不是浮点数,可能是)

有些字段我认为是 16 位和小端(Entry#2 最后 4 个字节是 0x0459,与观察到的数据匹配)

  • C953- 不确定,也许是校验和或 CRC?尝试了一些明显的标准,但与它不匹配,并且可能覆盖整个数据包或仅数据。

[为损坏的链接道歉,显然需要更多代表添加> 2]

2个回答

我猜:

DL20I000000V80050300DE076A0012000400AF002400FF030300DE0700000000010003000000B883
^^  ^      ^                                                                ^^^^
||  Addr   Data                                                            CRC16
|` Length
` Data tag
  • D 表示数据
  • L20 表示 0x20 或 32 个十六进制字节,或 64 个十六进制数字
  • I000000 地址(注意每行增加 0x20,支持 L20 作为长度和 I 作为地址)
  • V 数据,大小匹配 L
  • 还有一个 16 位 CRC 或校验和,由最后一行支持,除了每个行都有一个唯一的校验和之外,“全为 0”,表明地址是公式的一部分。

它看起来有点像用于编程 PROM 或微控制器的闪存文件格式。IHEX 没有字母。SREC 与您拥有的类似。

Netzob是专门为此目的构建的工具。我与工具的创建无关,它在我的经验中仍然存在错误,但是对于这种协议的逆向工程非常有用。