前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >破译优利德旗舰万用表UT181A通讯协议

破译优利德旗舰万用表UT181A通讯协议

作者头像
FB客服
发布2018-03-01 11:02:31
1.7K0
发布2018-03-01 11:02:31
举报
文章被收录于专栏:FreeBufFreeBuf

UT181A是优利德门下旗舰级手持数字万用表,主打数据记录(Data Logging)功能,支持USB联机通讯。基本评测可以看我以前发的文章。前文说到,其官方或第三方软件功能有限,缺少最重要的导出功能。另外,数据传输的速度也比较慢。

所以,欲对其协议进行分析,方便扩展、改进、和其它设备(比如树莓派)连接、等等。

本文的破解/破译方法及结论应该适用于UT171系列;UT71系列也可以参考。对破译其它联机通讯的设备也有借鉴意义。

可行性分析

UT181A使用了Silicon Labs HID-to-UART接口模块CP2110. 在操作系统里呈现为一个HID设备,这样的好处是不用装驱动。既然它最终表现为UART协议,应该比较容易重写其通讯协议。其实UT71系列也是类似的方案(HID转UART),只不过用的南京沁恒的模块。

找了一个CP2110的代码在Linux下试了下,可以对UT181A进行基本的连接设置。但因为会话层的协议未知,所以尝试读写操作时没反应。

为了得到会话的详情,最直接和万能的办法是用USB Sniffer。 试了一下Free USB Analyzer,可以看到一些数据,但不能解码为UART层的数据。从USB到HID,再到UART,实际上是隔了两层,需要层层剥壳,还是有点繁琐。Free USB Analyzer的HID解码,是解为键盘/鼠标数据的;也许它的收费版可以解码为UART。

图:用Free USB Analyzer截获UT181A通讯

不过我还有另一条完全不同的思路,也许会更简单。

API Hook

十几年前,我用过这种方法对SCSI设备的通讯进行劫获。这些设备的通讯软件,通常会有一个通讯模块(动态库),提供诸如Send/Receive的API。所以,只要自己写一个提供同样API的动态库取代原有的动态库,但在每个API的实现上,还是转到原动态库上,就可以实现钩子(Hook)的效果。这样截获的数据块是应用层/会话层的,比数据链路层/驱动层的数据有更好的可读性。同时,还可以根据API的调用顺序,得到和设备的交互流程,比如:初始化时要进行哪些设置,通讯参数,等等。

查看UT181A软件的目录,果然有两个这样的动态库。用dumpbin /exports查看其API,初步判断应该只要替换SLABHIDtoUART.dll 就可以了。

图:UT181A使用的动态库及API

从版本信息上,可以看到这个动态库来自Silicon Labs。到其网站上找到了CP2110/4 的SDK,用SDK里的动态库替换这两个动态库,64位版崩溃,换32位版,果然可以运行。

其实优利德使用的版本较老(2010年的1.4),SDK里的版本是2017年的6.7。其中,API数目由42增加到了58。不管怎样,能跑。这样就容易开展下一步的工作了。

图:CP211x SDK里的动态库及API

有了SDK就有了头文件,有头文件就可以写出八股文一样的代码了。弄两行脚本,自动生成大部分苦力代码。。

图:HookAPI实现代码示意

很快,就有了一个“山寨”动态库。

图:自己实现的SLABHIDtoUART.dll及API

正版的要改名;山寨版要记住它名字。——活都找它干。

图:HookAPI的文件名替换

弄好了,发现山寨版的比老正版的API都少了2个。能跑,就没深究了,毕竟优利德的软件不会用到所有API。

看看Log文件,API的调用一目了然。这样,我们就有了一个坚实的基础。

图:通过HookAPI截获的API调用序列

CP211x SDK

发现CP211x的SDK里还提供了Linux版Library(-lslabhidtouart -lslabhiddevice)的源代码及例子。

这两个Library和Windows的SLABHIDtoUART.dll,SLABHIDDevice.dll对应。于是,重写通讯协议就更容易了。对Makefile略做修改后,可以在Intel和ARM(树莓派)架构下编译、运行。

直接用SDK里的例子做个测试,发出第一条命令”AB CD 04 00 05 01 0A 00”后,就可以源源不断地收到数据了。

图:CP211x SDK里例子和UT181A通讯

后续的工作就是根据API Hook的Log,给UT181A发不同的命令,研究其反应,搜集更多的数据,以便发现数据的模式(Pattern)。

协议解码

起始码、长度字

上图中,通过观察每个输入/输出的数据包,发现会间隔地出现”AB CD”。用这两个字节对包进行分隔后,数据看起来更有规律,然后可以看出接下来两个字节应该是包的长度。长度可以和起始字起到相互验证/确认的作用。

图:基本的会话数据

结束码/检验字

对收到的数据包与其实际意义进行初步的对应后,发现最后两字节是多余的。推测应该是校验字。在CRC在线计算网站上对包中的数据做CRC计算,发现与任何一种CRC编码都不能匹配。

其实,对收到的数据,可以忽略这个校验码,因为USB协议保证了数据不会出错,除非是软件层发生了错误。但后来发现,对发送的命令,也多了两个字节。如果万用表那端要对它收到的数据做校验,主机端则必须生成校验码了。

下图的命令中,带有参数。9字节长的包中有一个参数,13字节长的包有2个参数。根据参数的变化,可以观察出最后两字节的变化规律。观察9字节长的包,发现最后两字节是在参数上增加了0x11,但这显然不能解释13字节长的包。进一步的分析发现,原来这个校验就是最简单的“校验和”,即把前面的所有字节(除起始码”AB CD”外)相加。对于长达2258字节的包也是这样,只不过高位溢出忽略。

图:观察结束码

浮点数的表示

理论上,测量值可以用整数或小数表示,小数又可以用定点或浮点。

可以用程控电源输出不同的电压来联机测量,观察数据的变化规律。当然,也可以直接猜一猜,反正就只有3种可能。下图是一个例 子。

图:记录列表及浮点值

图中标示了27.0, 27.1, 27.2。

不太像整型,直接拿浮点试一试。

图:浮点数测试代码

运气不错,就是普通的浮点。同时,可以看出,二进制的数据并不是万用表或软件界面上显示的值,而是看起来有着“更高精度”的原始数据。当然,这个“更高精度”应该是无意义的。事实上,每个数值后面还有一个字节(10/20/30),应该是用于描述其精度(有效位)的。

日期/时间的表示

最后剩下的,也是最难的,就是日期时间了。时间戳也是增加UT181A价值的地方。像UT71D虽然也记录数据,但测量值没有时间戳,只有序号。

抓取采样数据进行分析,每个数据包最大是2258字节,250个采样,所以每个采样用了9个字节:4字节浮点值,1字节描述精度,还有4字节就是时间了。是的,只有4字节,用来表示年/月/日/时/分/秒。——够吗?

在采集的数据中,每个采样对应于什么时间是已知的。取一段连续的采样数据,观察其变化规律。尤其是分钟,小时,日期和月份发生变化时,看数据如何变化。如下图。

图:时间数据观察

理论上,这种时间的表示可以用一个整型,像Unix时间戳那样。但分析上面的变化规律,看起来像是位域表示法。据此推演,结果如下。

图:UT181A的时间的表示法

由于年份使用的是6 bit,需要固定加上2000。所以,这意味着UT181A只能用到2063年(的最后一天)。当然,这总比用Unix时间戳编码要好一点,因为后者只能用到2038年。

传输速度

非常遗憾,波特率只能设置为9600。通过API调用,设置更高的波特率是成功的。但传输中得到的数据是乱的。

在树莓派上测试传输133685个采样,耗时1401秒,传输速度为95.42采样/秒。这与PC上的速度(自己写的代码或官方软件)是一致的。

树莓派

在Debian系的Linux上(Ubuntu或树莓派),CP2110都被识别为HID设备,不需要安装驱动即可使用。而且,树莓派的ARM和Intel都是小字节序,所以不用改代码,重新编译一下就可以运行。

下图是在树莓派上(远程)编译、运行。

在树莓派上编译运行UT181A通讯程序

上一张和树莓派的合影。

图:UT181A与树莓派

2063年测试

在2016年2月12日,据披露,如果把苹果iPhone、iPad等设备的系统时间设置为1970年1月1日,随后重启设备,它会直接变砖。

心怀忐忑与好奇,我决定确认一下2063年12月31日的问题,于是准备把时间设置到那天的最后一分钟。

但优利德的工程师似乎看穿了我的心思:时间只能设置到2060年!

图:UT181A的时间只能设置到2060年

等了1分钟后,时间变成了2061年。

但,如果我想看它出洋相,需要等上3年!——太狡猾了!

结语

通过API Hook的手段,在Windows上截获了 CP2110的通讯详情,破译了UT181A命令和数据的编码方式,重写了主要的会话过程,实现了:实时联机采集数据、传输离线采集的数据并保存为CSV的功能。代码可以在Linux PC和树莓派上运行(理论上,也可以移植到Windows上)。

受硬件限制,不能设置非9600的波特率,所以不能提高传输速度。

“致命缺陷”是:由于时间的编码方式, UT181A只能使用到2063年。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-08-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 FreeBuf 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 可行性分析
  • API Hook
  • CP211x SDK
  • 协议解码
    • 起始码、长度字
      • 结束码/检验字
        • 浮点数的表示
          • 日期/时间的表示
          • 传输速度
          • 树莓派
          • 2063年测试
          • 结语
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档