效果展示

思路
通过解析qq消息的PB 报文元数据获取构建版本号并通过自建规则表对应即可
通过开源模块ono得知,qq消息是通过C++ 跨平台内核(nt_kernel)处理,我们要hook的是他的JNI桥接类就是com.tencent.qqnt.kernel.nativeinterface.IQQNTWrapperSession$CppProxy
这里是直接站在巨人的肩膀上了,当然通过层层分析我们也可以最终定位到这个类,比如可以通过发送按钮入手
这里放一个AI总结的完整推导链路
undefined
[UI 界面层]
AIOInputSendBtn (R.id.send_btn: 0x7f0a39dc / 2131392636)
│ (ViewBinding: uk3.a / AioInputbarLayoutBinding)
▼
[MVI 视图代理层]
AIOSendMsgVBDelegate (com.tencent.mobileqq.aio.input.sendmsg.d$b)
│ onClick() 发送用户意图 MVI UserIntent: a.a2.d
▼
[ViewModel 业务层]
AIOSendMsgVMDelegate (com.tencent.mobileqq.aio.input.sendmsg.AIOSendMsgVMDelegate)
│ handleSendBtnClicked() -> combineArgsAndSendMix() -> H()
▼
[上层消息服务门面]
AIOMsgService (com.tencent.mobileqq.aio.msg.service.AIOMsgService)
│ s() -> 调用 com.tencent.qqnt.msg.f.f().sendMsg(...)
▼
[QQ NT 内核服务工厂]
com.tencent.qqnt.msg.f
│ f() -> IKernelService.getMsgService()
▼
[内核服务实现]
KernelServiceImpl (com.tencent.qqnt.kernel.api.impl.KernelServiceImpl)
│ wrapperSession.getMsgService() (IQQNTWrapperSession)
▼
[JNI 跨平台胶水层]
ee.y0() -> IQQNTWrapperSession.CppProxy.getNTWrapperSession()成功找到该类后我们尝试hook,onMsfPush方法,注意到第二个参数是字节流ByteArray,我们简单打印看看
原始字节流

这就是我们的二进制的Protobuf
我们可以通过多种方式把他解析成json
这里ono自实现了一个动态pb递归解析

这样我们就得到了可读的消息序列
注意到1.1.4这个值对于同一个人发的消息是不变的,和设备和qq版本有关,经过搜索发现这个是subid,就是qq构建版本号,对于不同版本不同设备构建的qq都是不一样的。

因此我们只要收集一份subid对于os,version的规则表即可得知对方系统以及qq版本
这里我收集了一部分,mobile是安卓设备
undefined
{
"mobile":[
{
"subid": 537397820,
"version": "9.3.75"
},
{
"subid": 537400114,
"version": "9.3.80"
},
{
"subid": 537395443,
"version": "9.3.70"
},
{
"subid": 1002,
"version": "9.3.35"
},
{
"subid": 1001,
"version": "9.3.35"
},
{
"subid": 537154744,
"version": "8.9.38"
},
{
"subid": 537375300,
"version": "9.3.25"
},
{
"subid": 537375294,
"version": "9.3.75"
},
{
"subid": 537397781,
"version": "9.3.75"
},
{
"subid": 537395438,
"version": "9.3.70"
},
{
"subid": 537397778,
"version": "9.3.75"
},
{
"subid": 537397776,
"version": "9.3.75"
},
{
"subid": 537378244,
"version": "9.3.30"
},
{
"subid": 537389183,
"version": "9.3.60"
},
{
"subid": 537388721,
"version": "9.3.60"
},
{
"subid": 537386844,
"version": "9.3.55"
},
{
"subid": 537385634,
"version": "9.3.55"
},
{
"subid": 537384055,
"version": "9.3.50"
},
{
"subid": 537382844,
"version": "9.3.70"
},
{
"subid": 537380421,
"version": "9.3.35"
},
{
"subid": 537379915,
"version": "9.3.35"
},
{
"subid": 537393105,
"version": "9.3.65"
},
{
"subid": 537377777,
"version": "9.3.30"
},
{
"subid": 537376842,
"version": "9.3.30"
},
{
"subid": 537375249,
"version": "9.3.25"
},
{
"subid": 537374827,
"version": "9.3.25"
},
{
"subid": 537373375,
"version": "9.2.50"
},
{
"subid": 537372142,
"version": "9.3.20"
},
{
"subid": 537371675,
"version": "9.3.20"
},
{
"subid": 1100123456789,
"version": "9.9.18"
},
{
"subid": 537397314,
"version": "9.3.75"
},
{
"subid": 537395482,
"version": "9.3.70"
},
{
"subid": 537284112,
"version": "9.1.67"
},
{
"subid": 537318136,
"version": "9.2.25"
},
{
"subid": 537315836,
"version": "9.2.20"
},
{
"subid": 537309888,
"version": "9.2.10"
},
{
"subid": 537306614,
"version": "9.2.5"
},
{
"subid": 537303102,
"version": "9.2.0"
},
{
"subid": 537297278,
"version": "9.1.95"
},
{
"subid": 537294918,
"version": "9.1.91"
},
{
"subid": 537288318,
"version": "9.1.75"
},
{
"subid": 537285986,
"version": "8.9.60"
},
{
"subid": 537285958,
"version": "9.1.70"
},
{
"subid": 537285947,
"version": "9.1.70"
},
{
"subid": 537323314,
"version": "9.2.27"
},
{
"subid": 537275637,
"version": "9.1.60"
},
{
"subid": 537270081,
"version": "9.1.55"
},
{
"subid": 537270042,
"version": "9.1.5"
},
{
"subid": 537264586,
"version": "9.1.35"
},
{
"subid": 537262765,
"version": "9.1.31"
},
{
"subid": 537260041,
"version": "9.1.25"
},
{
"subid": 537228627,
"version": "9.0.70"
},
{
"subid": 537200229,
"version": "9.0.8"
},
{
"subid": 537140000,
"version": "9.2.0"
},
{
"subid": 537064117,
"version": "8.9.60"
},
{
"subid": 537352525,
"version": "9.1.30"
},
{
"subid": 537367511,
"version": "9.3.10"
},
{
"subid": 537366999,
"version": "9.3.10"
},
{
"subid": 537365129,
"version": "7.8.9"
},
{
"subid": 537363319,
"version": "9.2.36"
},
{
"subid": 537360578,
"version": "9.3.1"
},
{
"subid": 537358739,
"version": "9.2.98"
},
{
"subid": 537357515,
"version": "9.2.95"
},
{
"subid": 537357474,
"version": "9.2.95"
},
{
"subid": 537356503,
"version": "9.2.55"
},
{
"subid": 537353962,
"version": "9.2.90"
},
{
"subid": 537369802,
"version": "9.3.15"
},
{
"subid": 537351308,
"version": "9.2.85"
},
{
"subid": 537348304,
"version": "9.2.80"
},
{
"subid": 537344683,
"version": "9.2.75"
},
{
"subid": 537341685,
"version": "9.2.66"
},
{
"subid": 537340717,
"version": "9.2.70"
},
{
"subid": 537339353,
"version": "9.2.66"
},
{
"subid": 537335442,
"version": "9.2.60"
},
{
"subid": 537333094,
"version": "9.2.55"
},
{
"subid": 537330106,
"version": "9.2.50"
},
{
"subid": 537327462,
"version": "9.1.78"
}
],
"windows":[
{
"subid": 537313906,
"version": "9.9.21"
},
{
"subid": 597163582,
"version": "9.9.35"
},
{
"subid": 537346872,
"version": "9.9.29"
},
{
"subid": 537340213,
"version": "9.9.27"
},
{
"subid": 537335442,
"version": "9.2.60"
},
{
"subid": 537352474,
"version": "9.9.30"
},
{
"subid": 537355830,
"version": "9.9.31"
},
{
"subid": 537376512,
"version": "9.9.32"
},
{
"subid": 537379411,
"version": "9.9.33"
},
{
"subid": 1100123456789,
"version": "9.9.18"
},
{
"subid": 537382819,
"version": "9.9.35"
},
{
"subid": 537383527,
"version": "9.9.33"
}
],
"macos":[],
"ios":[
{
"subid": 537396808,
"version": "9.3.75"
}
],
"linux":[
{
"subid": 537382855,
"version": "3.2.33"
}
],
"tim":[
{
"subid": 537298415,
"version": "4.1.0"
},
{
"subid": 537298414,
"version": "4.1.0"
},
{
"subid": 537298411,
"version": "4.1.0"
},
{
"subid": 537263459,
"version": "4.0.97"
},
{
"subid": 537261121,
"version": "4.0.96"
}
],
"watch":[],
"mobile_old":[]
}