mamoe / mirai

高效率 QQ 机器人支持库
https://mirai.mamoe.net
GNU Affero General Public License v3.0
14.37k stars 2.53k forks source link

自定义的加密服务EncryptService, 在某些时候sign会有空参数 #2774

Open zhaodice opened 1 year ago

zhaodice commented 1 year ago

问题描述

我写了个log,实时监控qSecurityGetSign,以及channel.sendMessage,发现某些情况下 qSecurityGetSigncommandName参数和payload为空(值得注意的是sequenceId为正常数字40180) channel.sendMessage的返回值也不再是null,但它的对象的cmdbuffer字段为空,callbackId是0 因为异常的空参数导致签名服务器重启,签名服务器重启后重新收到了正确的签名请求(此时sequenceId变成了30984)

复现

难以复现,是在安卓系统以锁屏状态长时间运行,偶然出现的。

mirai-core 版本

2.15.0

bot-protocol

ANDROID_PAD

其他组件版本

系统日志

 RequestPacked: {"action":"sign","data":{"buffer":[],"cmd":"","qua":"V1_AND_SQ_8.9.73_4416_YYB_D","seq":40180},"qid":9}
 FEKitLogInfo [FEKit_]: qq_sign.h:142 [GetSign] cmd:
 Action:sign, Cost: 57ms ,RCost:0.4418604651162791, Data:{"code":0,"data":{"extra":"121b56315f414e445f53515f382e3...546b885b02d04f4","token":"587a61387436776755676c6c"},"msg":"Success"}
 getPackageName() => "com.tencent.mobileqq"
 RequestPacked: {"action":"submit","data":{"buffer":[],"callback_id":0,"cmd":""},"qid":10}
 FEKitLogInfo [FEKit_]: ChannelManager.cpp:98 origin cmd:GetSecConf ,cmd:trpc.o3.ecdh_access.EcdhAccess.SsoEstablishShareKey
 FEKitLogErr [FEKit_]: ChannelManager.cpp:101 [ChannelManager:OnReceive] success:1 cmd:trpc.o3.ecdh_access.EcdhAccess.SsoEstablishShareKey bcmd:GetSecConf
 FEKitLogErr [FEKit_]: ChannelManager.cpp:125 [ChannelManager:OnReceive] rec emptyData
 Action:submit, Cost: 9ms ,RCost:0.06976744186046512, Data:{"code":0,"data":"","msg":"Success"}

//此处触发签名服务器重启,疑似提交空Hex导致崩溃
 fekit loading...
 FEKitLogErr [FEKit_]: o3_channel_encrypt.h:275 gen new channel
 FEKitLogErr [FEKit_]: o3_channel_encrypt.h:491 est check: c8ab4216533528aada7954c79495ecc2e827c1831c6eb04ab53dc263dcc6b6bf4c5239d302a1d153b5efc42511780c44
 FEKitLogErr [FEKit_]: ChannelManager.cpp:73 o3cm@S: GetSecConf, trpc.o3.ecdh_access.EcdhAccess.SsoEstablishShareKey
 RequestPacked: {"action":"sign","data":{"buffer":[10,8,18,6,8,-35,-104,-49,-36,2,18,2,8,1,26,62,10,...,50,0,64,1],"cmd":"MessageSvc.PbSendMsg","qua":"V1_AND_SQ_8.9.73_4416_YYB_D","seq":30984},"qid":22}
 FEKitLogInfo [FEKit_]: qq_sign.h:142 [GetSign] cmd:MessageSvc.PbSendMsg
 Action:sign, Cost: 16ms ,RCost:0.1391304347826087, Data:{"code":0,"data":{"extra":"121b56315f414e445f53515f38...","o3did":"PhdOhyPsp61x","requestCallback":[{"body":"0a0a47...4001","callback_id":0,"cmd":"trpc.o3.ecdh_access.EcdhAccess.SsoEstablishShareKey"}],"sign":"0c0bd6bb35562d927...7455fb74587393a04a852c7bd577cdf","token":"5068644f6879507370363178"},"msg":"Success"}
 RequestPacked: {"action":"sign","data":{"buffer":[10,10,71,101,116,83,...,12,68,64,1],"cmd":"trpc.o3.ecdh_access.EcdhAccess.SsoEstablishShareKey","qua":"V1_AND_SQ_8.9.73_4416_YYB_D","seq":30986},"qid":23}
 FEKitLogInfo [FEKit_]: qq_sign.h:142 [GetSign] cmd:trpc.o3.ecdh_access.EcdhAccess.SsoEstablishShareKey
 Action:sign, Cost: 16ms ,RCost:0.1391304347826087, Data:{"code":0,"data":{"extra":"0a20bdf81bb5...776582b79577a52344e79745a74343d","o3did":"PhdOhyPsp61x","requestCallback":[],"sign":"0c0be01520d48f1fe...11ae4ae903","token":"5068644f6879507370363178"},"msg":"Success"}
 RequestPacked: {"action":"submit","data":{"buffer":[10,-121,2,47,6,-28,...,81,16,0],"callback_id":0,"cmd":"trpc.o3.ecdh_access.EcdhAccess.SsoEstablishShareKey"},"qid":24}
 FEKitLogInfo [FEKit_]: ChannelManager.cpp:98 origin cmd:GetSecConf ,cmd:trpc.o3.ecdh_access.EcdhAccess.SsoEstablishShareKey
 FEKitLogInfo [FEKit_]: task_handle.h:77 TaskSystem not allow

网络日志

No response

补充信息

No response

zhaodice commented 1 year ago

mirai本身没有任何错误输出,只能从EncryptService的日志查看原因 这个问题优先级不高,因为我可以直接判断是否是空的buffer和cmd,拦截这个异常

StageGuard commented 1 year ago

channel report 包有时候是空的

zhaodice commented 1 year ago

channel report 包有时候是空的

是,但空包不应该commandNamecmd也是空的吧

cssxsh commented 1 year ago

本来就是需要根据 cmd_white_list 进行过滤 unidbg-fetch-qsign 甚至都没写这个 api 我对接的时候还得从 magic-signer-guide 找补

zhaodice commented 1 year ago

本来就是需要根据 cmd_white_list 进行过滤 unidbg-fetch-qsign 甚至都没写这个 api 我对接的时候还得从 magic-signer-guide 找补

~事实上是因为模拟调用的fekit,setCmdWhiteListChangeCallback回调,【根本】不执行,所以qsign也没有white list,似乎是缺少和服务器交互的包,这数据应该是从服务器派发的~ 当我没说,调用ChannelManager.getCmdWhiteList() 就可以拿了,看样子确实没实现