您的位置:首页 > 其它

WM里蓝牙AVRCP的消息队列研究分析(研究ing,笔记)

2009-08-24 12:08 453 查看
WM里蓝牙AVRCP的消息队列研究分析(研究ing,笔记)
2009-06-11 15:05

折腾这破东西好几天了,目前还没得到进一步突破,不过已经知道了许多以前不知道的东西,写一下当前笔记。

AVRCP(Audio/Video Remote Control Profile)是一种在蓝牙协议栈A2DP/AVCTP上实现的控制技术,通俗点说,就是你用蓝牙耳机听歌时按一下拨号键它会暂停,按下选曲它会切换,这就是AVRCP的功劳。

A2DP和AVRCP是一对兄弟,A2DP里WM设备是控制端,蓝牙耳机是接收端,AVRCP反之,这里说的就是WM如何接收蓝牙耳机发送的AVRCP并处理的过程。

WM里AVRCP是在L2CAP层上的扩展协议,它由AVCTP负责传输,这些规范请去看蓝牙协议文档,这里不说了。

WM里AVRCP是通过一个btd.dll驱动实现的,根据IDA静态分析得知,该驱动实现了一个接口
AVCT_EstablishDeviceContext,这个接口建立起一个AVCTP协议的Callback结构,当蓝牙耳机发送一个AVRCP指令
时经过底层蓝牙堆栈的处理后提交到L2CAP层,再由AVCTP协议分析处理,这个分析就是在AVCT_EstablishDeviceContext建
立的Callback回调函数里进行的。

WM是一个基于消息队列的系统,可以说它的内部到处都是MsgQueue,而不知道是不是微软和蓝牙规定的协议还是通用协议里也指定了,蓝牙堆栈的
消息是通过消息队列传输的,因此,微软就不在WM里专门提供一个处理AVRCP的接口函数了,这就造成了今天的局面:业余开发者们都不知道怎么实现它!
(专门的开发厂商有微软提供技术支持,实现起来当然简单,交学费就行……)

而MSDN上提到的那个RequestBluetoothNotifications是只对蓝牙连接和配对等消息队列起反应的,虽然里面写着它是
“Handling Events from Bluetooth
Stack”,但是实际上它能得到的Event并不包括AVRCP,就算你手工把1到65535的dwClass结构全写满也没用,仍然只接收
BTE_CLASS_CONNECTIONS | BTE_CLASS_DEVICE |
BTE_CLASS_PAIRING,不能不说在这方面微软狠狠的涮了开发者一把。

所以要弄懂AVRCP怎么跑到接收程序里的,就得分析btd.dll了。

在IDA里可以看到AVCT_EstablishDeviceContext创建了多个过程调用,最后跑去执行本体

.text:03CA4A4C BL memset

.text:03CA4A50 LDR R4, =sub_3CA3ED4

.text:03CA4A54 LDR LR, =sub_3CA49A4

.text:03CA4A58 LDR R3, =sub_3CA490C

.text:03CA4A5C LDR R2, =sub_3CA4958

.text:03CA4A60 STR R4, [SP,#0x60+var_28]

.text:03CA4A64 LDR R4, [SP,#0x60+var_4C]

.text:03CA4A68 LDR R5, =loc_3CA3EDC

.text:03CA4A6C LDR R6, =loc_3CA3EE4

.text:03CA4A70 LDR R7, =loc_3CA3EEC

..............................

.text:03CA4AC8 BL AVCT_EstablishDeviceContext

注意这个调用:LDR LR, =sub_3CA49A4,看下去会发现它就是AVRCP队列的关键调用

在经过七跳八跳后,我们来到sub_3CA4208

STMFD SP!, {R4-R6,LR}

SUB SP, SP, #0x14

MOV R4, R0

LDR R0, =aAvrcpmsg


MOV R3, #0x14

MOV R2, #0

MOV LR, #5

MOV R5, #0x64

MOV R6, #0

ADD R1, SP, #0x24+var_24

STR R3, [SP,#0x24+var_24]

STR R2, [SP,#0x24+var_20]

STR LR, [SP,#0x24+var_1C]

STR R5, [SP,#0x24+var_18]

STR R6, [SP,#0x24+var_14]

BL CreateMsgQueue

可以看出这里建立了一个消息队列,里面最大保存5条数据!

继续看下去,到sub_3CA4274这里:

SUB SP, SP, #0x1C

MOV R4, R1

MOV R5, R0

MOV R2, #0x18

MOV R1, #0

ADD R0, SP, #0x2C+var_28

BL memset

LDR R0, [R5,#0x10]

MOV LR, #0x7C

MOV R6, #0

MOV R3, #0x32

MOV R2, #0x18

ADD R1, SP, #0x2C+var_28

STR LR, [SP,#0x2C+var_28]

STR R4, [SP,#0x2C+var_24]

STR R6, [SP,#0x2C+var_2C]

BL WriteMsgQueue

很明显这里就是把AVRCP指令写到消息队列中了,至此btd.dll的流程结束。

然后,微软在WM5以上提供了一个A2DP补丁以及一个WMP的AVRCP插件avrcp_mpplugin.dll,把它丢进IDA,跟到CreateMsgQueue:

SUB SP, SP, #0x60

MOV R5, R0

LDR R0, =(dword_3D97020+0x10)

MOV R3, #0x14

MOV R2, #2

MOV LR, #5

MOV R4, #0x64

MOV R6, #1

ADD R1, SP, #0x84+var_64

STR R3, [SP,#0x84+var_64]

STR R2, [SP,#0x84+var_60]

STR LR, [SP,#0x84+var_5C]

STR R4, [SP,#0x84+var_58]

STR R6, [SP,#0x84+var_54]

BL CreateMsgQueue

这里很明显又建立了一个和btd.dll里对应的消息队列结构,都是最大接收5条数据的结构,然后CreateEvent,再WaitForMultiObjects,最后我们来到一个循环:

LDR R0, [R4,#0xC]

ADD R3, SP, #0x40+var_38

MOV R2, #0x18

ADD R1, SP, #0x40+var_28

STR R5, [SP,#0x40+var_3C]

STR R6, [SP,#0x40+var_40]

BL ReadMsgQueue

这里便是把btd.dll写入的消息队列读取出来的部分,然后这个COM服务器形式的UI插件查找Windows Media窗口(类名WMP
for Mobile
Devices),并PostMessage发送一条WM_USER+1(0x8001)的消息过去,param里就是指示当前蓝牙耳机按下了什么按钮的
编码。

然后……分析暂时就到此了……阅读IDA反汇编的能力有限-_-

目前重现的难点在于:

1.CreateMsgQueue的结构是什么?

2.ReadMsgQueue的参数?

因为只有这两个都与btd.dll创建的实例一样了,它才能“识别”到这个消息队列并实现处理,做过MSMQ的人应该都不会陌生,而我是MSMQ的门外汉……

从MSDN里找到一些AVRCP的声明:

typedef enum {

UNITINFO_T = 0x30,

SUBUNITINFO_T,

PASSTHRU_T = 0x7C

} AVCOpCodes;

typedef struct _AvrcpMsg {

UINT OpCode;

UINT OpId;

UINT Reserved[4];

} AvrcpMsg;

typedef enum {

SELECT_T = 0x00,

UP_T,

DOWN_T,

LEFT_T,

RIGHT_T,

RIGHTUP_T,

RIGHTDOWN_T,

LEFTUP_T,

LEFTDOWN_T,

ROOTMENU_T,

SETUPMENU_T,

CONTENTSMENU_T,

FAVMENU_T,

EXIT_T,

CHANNELUP_T,

CHANNELDOWN_T,

PREVCHANNEL_T,

SOUNDSEL_T,

INPUTSEL_T,

DISPLAYINFO_T,

HELP_T,

PAGEUP_T,

PAGEDOWN_T,

POWER_T,

VOLUP_T,

VOLDOWN_T,

MUTE_T,

PLAY_T,

STOP_T,

PAUSE_T,

RECORD_T,

REWIND_T,

FASTFWD_T,

EJECT_T,

FORWARD_T,

BACKWARD_T,

} PassThruOpId;

希望有高手能指点一下!

======================================

补充:已经解决了,有兴趣的可以去下载我写的蓝牙耳机控制插件 for TCPMP,我是世界上第一个为它实现了从底层直接获取AVRCP指令来控制的人哦。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: