我们买了一个录音机,比用笔记本电脑的麦克风录音要好很多,而且省电。当然,我也试过用手机录,结果用了半天就中断了(安卓太不靠谱了)。
我的录音需要更准确的时间信息。录音机怎么知道现在几点了?还好没有跟风,不用联网!
自带一个小程序,叫做“录音笔时间同步工具”(英文叫“SetUDiskTime”,可以找到)。是一个EXE文件,一个DLL文件。功能很棒,没有广告,没有推荐,不需要注册任何乱七八糟的账号录音笔时间设置完成后,甚至不需要打开浏览器访问别人的官网。只需弹出一个框显示当前时间,请务必设置时间。今年,这么简单的Windows软件真的很少见了。
但是,它不支持我使用的 Linux。虽然我尽了最大努力让记录仪保持通电,但时间浪费了好几次,它的 FAT 文件系统也被弄脏了好几次。每次都要打开WinXP虚拟机设置时间,很麻烦。
Wine 不行,硬件相关的东西基本没用。拿Procmon去跟踪一下,没有复杂的操作,主要就是几个DeviceIoControl调用录音笔时间设置完成后,但是看不到调用参数。我试过IDA,但是完全看不懂……但是我可以知道它是通过IOCTL_SCSI_PASSTHROUGH直接向设备发送SCSI命令的。
由于无法追踪,请尝试抓取USB包。本来想用Wireshark的,但是Wireshark的WinXP版好像不支持。我尝试再次将设备分配给VBox,然后在Linux上捕获包,但结果是权限被拒绝...我是root并且被拒绝...
那么,让我们在 Windows 上捕获数据包。有个软件叫USBPcap,下载安装最新版本,但是遇到了bug。然后尝试旧版本。官网没有给出旧版本的下载地址,但是很容易看出下载链接有版本号。去commit log找到旧版本号替换掉就可以了~
抓取包,在 Linux 下拿到它,然后扔给 Wireshark 来解释它。它很小,不到50个数据包,而且大多数都是重复的。关键位置快速定位:
发送 0xcc 命令,设备回复“ACTIONSUSBD”,大概是为了准备设备。然后发送一个 0xb0 命令和 7 个字节的数据,并设置时间。简单明了,不像那些小米空气净化器那样的所谓“物联网”,加密通信让人无法正常使用。
那么,这7个字节是如何传输时间数据的呢?我首先检查了 UNIX 时间戳,但它不匹配。后来发送的字符串看起来像YYYYMMDDHHMMSS的格式,但显然不是当时的时间。啊,它是十六进制的!我做了一些心算,结果很合适!然后我拿出我的 Python 卡片计算器,确定年份是 little-endian 16 位整数。
好了,协议细节说清楚了,接下来就是实现了。我以为我必须编写一个 C 程序并调用一些 ioctl。后来网友说有一个sg3_utils包。很好,直接用它来调Python,就不用研究那些ioctl怎么写了。
#!/usr/bin/env python3 import os import sys import struct import subprocess import datetime def set_time(dev): cmd = ['sg_raw', '-s', '7', dev, 'b0', '00', '00', '00', '00', '00', '00', '07', '00', '00', '00', '00'] p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stderr=subprocess.PIPE) dt = datetime.datetime.now() data = struct.pack('