Linux 与 Windows 双系统共享蓝牙鼠标

起因

本着“师夷长技以制夷”的想法,装了一个 Windows 10,装完过后发现蓝牙鼠标需要重新配对,切换系统过后又需要重新配对……

看样子蓝牙的配对信息是存储在系统上的,所以要实现在切换系统后不需要重新配对就能正常使用蓝牙鼠标的话,基本思路应该是手动修改其中一个系统上的配对信息使其与另一个系统一致。

查了一圈,蓝牙 3.0 和 4.x 的配对信息还很不一样,总的说来 4.x 的信息量更大,需要改动的参数也多一些,本文主要针对蓝牙 4.x 的鼠标。

基本步骤

  1. 先在 Linux 下配对蓝牙鼠标(用于生成配置文件)
  2. 切换到 Windows 下配对蓝牙鼠标(用于读取配对信息)
  3. 修改 Linux 下的配对信息与 Windows 一致

当然也可以反过来做,修改 Windows 下的配对信息与 Linux 下一致,但是不推荐那样做。

读取 Windows 下的蓝牙配对信息

Windows 的蓝牙配对信息存储在注册表中:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\BTHPORT\Parameters\Keys\<本机蓝牙 MAC>\<鼠标蓝牙 MAC>

其中的 MAC 地址不带分隔符,并且这里需要系统权限才能访问,我找到两个方法来读取这部分信息。

使用 psexec.exe 以系统权限启动 regedit.exe

psexec.exe 可以在这个页面(直接下载 PSTools.zip )下载到,将 PSTools.zip 中的 PsExec.exe 或
PsExec64.exe 解压出来,并以管理员权限运行 cmd,然后在 cmd 中输入下面的命令以系统权限启动 regedit.exe :

psexec64.exe -si regedit

然后我们就可以在注册表编辑器中查看相应的键值,也可以将其导出:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\BTHPORT\Parameters\Keys\6057xxxxxxxx\eb50xxxxxxxx]
"LTK"=hex:a5,2e,55,1c,85,79,c8,de,30,69,e0,a1,aa,f9,d1,91
"KeyLength"=dword:00000000
"ERand"=hex(b):69,28,ef,ac,68,4f,83,67
"EDIV"=dword:000046fd
"IRK"=hex:74,e7,db,73,11,08,b0,a6,a4,98,e7,86,46,33,58,03
"Address"=hex(b):xx,xx,xx,xx,50,eb,00,00
"AddressType"=dword:00000001
"CSRK"=hex:41,b5,eb,a7,94,a7,13,c9,21,22,1d,b2,25,7d,b8,6e
"OutboundSignCounter"=dword:00000000
"AuthReq"=dword:00000001

使用 dumphive 在 Linux 下直接读取 Windows 注册表

获取 dumphive

dumphive 这个项目有点老了,并且已经停止了更新,好在还能用,源码可以在这里找到:
https://gitorious.org/canaima-gnu-linux/dumphive.git
不过这个镜像站随时都有可能停止服务,所以我这里提供一个备份:dumphive-git.tar.gz
下载源码后自行编译安装即可。

读取注册表

在 Linux 下挂载 Windows 系统盘,进入 Windows/System32/config 目录,里面的 system 文件就是我们要读取的注册表文件了。
操作示例:

sudo mount /dev/sda3 /mnt          #假设 sda3 是 Windows 系统盘
cd /mnt/Windows/System32/config    #注意路径大小写
dumphive system ~/system.reg

执行下面的命令,可以查找到显示蓝牙配对相关的信息:

nanpuyue@nanpuyue-pc~$ grep -Pn 'BTHPORT.*(\\[\da-f]{12}){2}' ~/system.reg
238970:[ROOT\ControlSet001\Services\BTHPORT\Parameters\Keys\6057xxxxxxxx\eb50xxxxxxxx]

这里可能会有多条输出,取决于系统当前配对的蓝牙设备数,我这里只有一条,所以可以确定就是我要配置的蓝牙鼠标。
其中 238970 表示行号, MAC 地址已经脱敏,然后我们用文本编辑器打开 ~/system.reg,跳到第 238970 行就能看到内容了:

vi ~/system.reg +238970
[ROOT\ControlSet001\Services\BTHPORT\Parameters\Keys\6057xxxxxxxx\eb50xxxxxxxx]
"LTK"=hex:a5,2e,55,1c,85,79,c8,de,30,69,e0,a1,aa,f9,d1,91
"KeyLength"=dword:00000000
"ERand"=hex(b):69,28,ef,ac,68,4f,83,67
"EDIV"=dword:000046fd
"IRK"=hex:74,e7,db,73,11,08,b0,a6,a4,98,e7,86,46,33,58,03
"Address"=hex(b):xx,xx,xx,xx,50,eb,00,00
"AddressType"=dword:00000001
"CSRK"=hex:41,b5,eb,a7,94,a7,13,c9,21,22,1d,b2,25,7d,b8,6e
"OutboundSignCounter"=dword:00000000
"AuthReq"=dword:00000001

这与我们用注册表编辑器导出的信息一致。

修改 Linux 下的蓝牙配对信息

Linux 下蓝牙设备的配对信息存储在 /var/lib/bluetooth/<本机蓝牙 MAC> 目录下,例如 /var/lib/bluetooth/60:57:XX:XX:XX:XX,MAC 地址中的字母全为大写,且含冒号分隔符。
进入该目录:

sudo su
cd /var/lib/bluetooth/60:57:XX:XX:XX:XX

可以看到系统已配对的蓝牙设备:

root@nanpuyue-pc:/var/lib/bluetooth/60:57:XX:XX:XX:XX# ls -l
总用量 24
drwx------ 2 root root  4096 3月  13 19:48 4C:57:XX:XX:XX:XX
drwx------ 2 root root 12288 3月  13 22:38 cache
drwxr-xr-x 2 root root  4096 3月  13 21:52 EB:50:XX:XX:XX:XX
-rw------- 1 root root    69 3月   9 13:21 settings

进入我们要配置的蓝牙鼠标的目录:

cd EB:50:XX:XX:XX:XX

我们需要修改的就是这个目录下的 info 文件,以我的为例,改好的文件如下:

[General]
Name=Microsoft Surface Mouse
Appearance=0x03c2
AddressType=static
SupportedTechnologies=LE;
Trusted=true
Blocked=false
Services=00001800-0000-1000-8000-00805f9b34fb;00001801-0000-1000-8000-00805f9b34fb;0000180a-0000-1000-8000-00805f9b34fb;0000180f-0000-1000-8000-00805f9b34fb;00001812-0000-1000-8000-00805f9b34fb;

[IdentityResolvingKey]
Key=74E7DB731108B0A6A498E78646335803

[LocalSignatureKey]
Key=41B5EBA794A713C921221DB2257DB86E
Counter=0
Authenticated=false

[LongTermKey]
Key=A52E551C8579C8DE3069E0A1AAF9D191
Authenticated=0
EncSize=16
EDiv=18173
Rand=7458892718852221033

[ConnectionParameters]
MinInterval=6
MaxInterval=6
Latency=60
Timeout=200

[DeviceID]
Source=2
Vendor=1118
Product=2329
Version=272

下面详细介绍 Windows 下和 Linux 下几个参数的对应关系:

WindowsLinux
LTK[LongTermKey] Key
IRK[IdentityResolvingKey] Key
CSRK[LocalSignatureKey] Key
EDIV[LongTermKey] EDiv
ERand[LongTermKey] Rand

需要修改的就是上面这几个参数,其中 LTK IRK CSRK 都只是简单的去掉逗号分隔符并转换为大写,以 LTK 为例:

nanpuyue@nanpuyue-pc:~$ echo a5,2e,55,1c,85,79,c8,de,30,69,e0,a1,aa,f9,d1,91|tr -d ,|tr a-z A-Z
A52E551C8579C8DE3069E0A1AAF9D191

EDIV 和 ERand 需要从十六进制转换为十进制:

nanpuyue@nanpuyue-pc:~$ echo $((16#000046fd))
18173
nanpuyue@nanpuyue-pc:~$ echo $((16#$(echo 69,28,ef,ac,68,4f,83,67|tr , '\n'|tac|tr -d '\n')))
7458892718852221033

这里特别要注意的是 ERand 的转换,要先把 69,28,ef,ac,68,4f,83,67 倒序。

然后重启蓝牙服务,不出意外的话,就能在不重新配对的情况下在 Linux 使用鼠标了。

后记

  1. 如果不想使用繁多的 Linux 命令,建议在 Windows 注册表编辑器中直接读取 EDIV 和 ERand 的十进制数据。
  2. 我开始修改好后一直不成功,然后才发现 ERand 的转换需要倒序;然而还是不成功,最后发现两次配对后鼠标的 MAC 地址最后一位居然不一样,改了 Linux 下蓝牙鼠标配置文件的目录名(就是 MAC 地址)后终于好了。

标签: Linux, Windows, Bluetooth

已有 2 条评论

  1. leaeasy leaeasy

    好6的实现

  2. milebye milebye

    谢谢博主的分享~~~

添加新评论