计客蓝牙魔方协议逆向分析

阅读量    79085 | 评论 5

分享到: QQ空间 新浪微博 微信 QQ facebook twitter

 

0x00 前言

本文大致记录了一个,对于蓝牙魔方中的协议逆向分析的步骤。

去年年初的时候,对蓝牙有一点儿兴趣,搞了搞ubertooth one(好像是叫这个名字? 进不清楚了),用来嗅探蓝牙数据的,然后顺手又买了一个计客的魔方,带蓝牙功能的,简单来说就是基于蓝牙和手机的数据传输,将魔方的状态输出到手机上,以此来实现一些好玩的小功能的(诶再说下去感觉像是在打广告了)

这个其实没啥太多干货,甚至没有知识点,总的来说,仅仅是记录一个,处理问题接近问题的思路,具体关于拧动魔方的方向,这里也不提了,回头带一个魔方入门教程在结尾的参考中吧。

 

0x01 基础逻辑推理分析

在着手分析之前,其实需要搞明白一个问题,这个玩具,它是怎么通过和手机建立蓝牙连接后,将自己的状态同步到手机上的。

首先,它内部一定是存在感应器来获取魔方转动的情况的,这里的问题是,它给到手机的数据,是什么样子的,理论上只有两种方式

  1. 仅仅给出魔方转动的方向情况,手机端接收到之后,自行进行计算。
  2. 每次转动,都将整个魔方的状态发送到手机上。

我之前觉着是第二种,因为考虑到蓝牙也许会出现丢包或者数据包传输时的次序问题,所以这里不管怎么想,也都是每次同步状态过去比较稳健的样子。实际着手验证的方式也非常简单,连接手机后随便转动几下,再断开连接,连上另外一个设备,如果魔方状态仍然被同步了,起码说明,它是能存储自身状态的(老实说我在最初分析的时候就是这样想的,但是现在回过头来看,也许还是有点儿牵强吧,因为也存在每次连接同步状态,后续仅仅发送转动方向的可能性)

 

0x02 状态获取&信息收集

接下来的事情比较简单,就是先通过电脑连接上魔方,这个比较简单,代码我也上git了

https://github.com/EggUncle/GiikerDesktopClient

就是使用bleak的python库,写一点儿python就行了,我这里代码写的比较随意,因为仅仅是分析和获取协议信息,没有进一步开发的打算(本来是有的。。但是没啥时间了),可以拿到这样的信息:

Connected: True
[Service] 180A: Device Information
    [Characteristic] 2A29: (read) | Name: , Value: b'GiCube.Co.Ltd' 4769437562652e436f2e4c7464
[Service] 180F: Battery Service
    [Characteristic] 2A19: (read,notify) | Name: , Value: b'7' 37
        [Descriptor] 2902: (Handle: 15) | Value: b'\x00\x00' 0000
[Service] AADB: Unknown
    [Characteristic] AADC: (read,notify) | Name: , Value: b'\x124Vx3333\x124Vx\x9a\xbc\x00\x00a\x13a\x13' 1234567833333333123456789abc000061136113   这个大概率是魔方状态
        [Descriptor] 2902: (Handle: 19) | Value: b'\x00\x00' 0000
[Service] AAAA: Unknown
    [Characteristic] AAAB: (notify) | Name: , Value: None
        [Descriptor] 2902: (Handle: 23) | Value: b'\x00\x00' 0000
    [Characteristic] AAAC: (write-without-response) | Name: , Value: None
[Service] 00001530-1212-EFDE-1523-785FEABCD123: Unknown
    [Characteristic] 00001532-1212-EFDE-1523-785FEABCD123: (write-without-response) | Name: , Value: None
    [Characteristic] 00001531-1212-EFDE-1523-785FEABCD123: (write,notify) | Name: , Value: None
        [Descriptor] 2902: (Handle: 31) | Value: b'\x00\x00' 0000
    [Characteristic] 00001534-1212-EFDE-1523-785FEABCD123: (read) | Name: , Value: b'\x01\x00' 0100

蓝牙协议我其实不怎么熟悉,就是随便看了看,简单提一下,其实可以吧蓝牙设备抽象成一个类,它提供各种各样的服务,也就是一些成员变量或者函数,用的时候,去调用相关服务获取信息就行了。这里能看到一个比较可疑的Characteristic:AADC,因为它带的数据量看起来最大,符合我前面说的“每一次通信包含整个魔方状态”的推论,因此这里进一步进行一些转动,收集到了一些数据。

需要注意的是,从一个协议角度来理解整个魔方转动状态的时候,毫无疑问的是,魔方的中轴一定是不动的,也就是说,保持一个方向,不会对整个魔方进行转体之类的操作。

这里整体以蓝色为顶,橙色为前

复原状态:
1234 5678 3333 3333 1234 5678 9abc 0000 6113 6113

最上面那层 顺时针拧一下 即 U
1234 8567 3333 3333 1234 5678 c9ab 0000 1161 1311
1234 7856 3333 3333 1234 5678 bc9a 0000 1111 6113
1234 6785 3333 3333 1234 5678 abc9 0000 1111 1161
1234 5678 3333 3333 1234 5678 9abc 0000 1111 1111

最右 R
1624 5738 3223 3223 1264 5b38 9a7c 2620 4111 1111
1764 5328 3333 3333 12b4 5768 9a3c 0000 4141 1111
1374 5268 3223 3223 1274 53b8 9a6c 2620 4141 4111
1234 5678 3333 3333 1234 5678 9abc 0000 4141 4141


最下面一层 拧一下 D
4123 5678 3333 3333 4123 5678 9abc 0000 6363 6361
3412 5678 3333 3333 3412 5678 9abc 0000 6363 6363
2341 5678 3333 3333 2341 5678 9abc 0000 6363 6363
1234 5678 3333 3333 1234 5678 9abc 0000 6363 6363

最前面一层 F
1273 5684 3311 3311 1237 56c4 9ab8 0000 3163 6363
1287 5643 3333 3333 123c 5687 9ab4 0000 3131 6363
1248 5637 3311 3311 1238 564c 9ab7 0000 3131 3163
1234 5678 3333 3333 1234 5678 9abc 0000 3131 3131

拿到了这些信息的样子,接下来进行进一步的分析

 

0x03 协议信息分析

首先,在魔方复原状态下,出现了很多很规律的数据,例如

1-8位的数据是 1234 5678
17-28位的数据是 1234 5678 9abc

首先魔方的每一块颜色都不一样(这里指三维状态下的块),因此,肯定是需要使用不同的代码来标示不同的块的,因此这两段数据,有很大的可能,是代指各个块,魔方的角块有8个,而棱块有12个,正好对应上了这两组数据。(诶这里就一句话就吧最关键的块数据情况描述出来了,我当时看其实看了老半天。。)

这里再放一张图来说说啥是角块啥是棱块吧:

然后这里使用了一些常见的魔方公式,比如说PLL中的三棱块对调:

获取到了这样的数据:

对换蓝色层的棱块
对换前
1234 5678 3333 3333 1234 5678 9abc 0000 3331 6361
后
1234 5678 3333 3333 1234 5678 bc9a 0000 2143 2143

可以看到, 9abc 变成了 bc9a,总的来说就是通过这类的变换,最后获取到了每一个编码对应的魔方的块:

棱块:
绿黄 1
绿红 2
绿白 3
橙绿 4
红黄 5
红白 6
橙白 7
橙黄 8
蓝黄 9
蓝红 a
蓝白 b
橙蓝 c

角块:
黄绿红 1
红绿白 2
白橙绿 3
黄绿橙 4
黄蓝红 5
红蓝白 6
白橙蓝 7
黄蓝橙 8

这样,整个块的编码就清楚了,接下来还有一个问题也迎刃而解了,就是,角块和棱块后面对应的数据分别是什么。后续我又进行了一些转动,简单推理得出,3333 3333 这段数据,就是对应每一个棱块的朝向,因为他们仅仅只有1/2/3 三种数字出现,而棱块只有两个朝向,因此使用二进制数据标示 000 三个十六进制数字,转换成二进制正好是12个0,这样就说得通的,具体如下:

1234 5678 3333 3333 1234 5678 9abc 0000 3331 6361
A    B    C    D    E    F    G    H    I    J

棱块:EFG坐标 H 前三个数字的二进制为朝向
角块:AB坐标 CD朝向

 

0x04 block之后的发散思路

老实说分析到上面那一步之后,我就整个block住了,因为我实在是不太明白其中朝向的和这串数据到底有什么关系。。当时一直念叨着,朝向朝向朝向的,突然想到,整个魔方协议的设计思路,和魔方的一个项目,有很强的关系—-盲拧。 诶早年在南昌WCA的时候,看过两个钟头盲39个三阶的巨佬,太强了,算了不扯远了,说回盲拧的事情。我并不会盲拧,但是早些年玩魔方的时候,有一些玩魔方的朋友会这玩意,简单和他们聊过,总体来说就是,通过记忆魔方的编码情况,然后通过一系列比较特殊的,对整个魔方状态改动比较小的公式(我可能不太能描述清楚这个概念,大致意思就是,在交换一些使用者期望交换的块之后,其他块尽可能的保持不变),魔方盲拧的编码方式种类也比较多,后来真的找着了:

https://my.oschina.net/flylb/blog/729487

这里仅仅看编码的部分就好了,整体思路非常接近,唯一有一点点区别的是,棱块的朝向在这个编码中不是1/2/3,而是0/1/2,且棱块的高/中/低级面,和角块的高/中/低级面,并不相同。

棱块:
高级色 橙色 红色
中级色 白色 黄色
低级色 蓝色 绿色

角块:
高级色 蓝色 绿色
中级色 橙色 红色
低级色 白色 黄色

这里在分析和最后代码实现其实也花了很多时间,不过本身仅仅是一些业务逻辑,不涉及问题分析,这里就不记了,回头看看代码吧。

 

0x05 总结

总的来说就只是一个,逆向的分析思路吧,其实挺简单的

  1. 逻辑分析推理 (如果我来整这玩意,咋样能合适一点儿)
  2. 信息收集 (收集一批数据看看,是不是和猜想一样的)
  3. 思路发散 (如果真的分析不动了,找找资料看看也没有类似的玩意)

 

0x06 参考

  1. https://cube3x3.com/%E5%A6%82%E4%BD%95%E8%A7%A3%E5%86%B3%E9%AD%94%E6%96%B9/
  2. http://www.mf100.org/base.htm
  3. http://www.mf100.org/cfop/pll.htm
分享到: QQ空间 新浪微博 微信 QQ facebook twitter
|推荐阅读
|发表评论
|评论列表
加载更多