mirror of
https://github.com/yincongcyincong/wechat_chatter.git
synced 2026-07-15 10:26:52 +08:00
修复 OneBot 漏捕获有效消息的问题
- 正确解析 protobuf 消息头,取消短消息长度误判 - 保留 Frida 消息大小及内存安全检查 - 将不匹配的 protobuf 数据降级为警告日志
This commit is contained in:
@@ -14,6 +14,10 @@ import (
|
||||
func HandleProtobufMsgAndSend(payload map[string]interface{}) {
|
||||
jsonData, err := HandleProtobufMsg(payload)
|
||||
if err != nil {
|
||||
if isUnsupportedProtobufMessage(err) {
|
||||
Warn("跳过不匹配的protobuf消息", "err", err)
|
||||
return
|
||||
}
|
||||
Error("protobuf消息处理失败", "err", err)
|
||||
return
|
||||
}
|
||||
@@ -29,6 +33,17 @@ func HandleProtobufMsgAndSend(payload map[string]interface{}) {
|
||||
}
|
||||
}
|
||||
|
||||
func isUnsupportedProtobufMessage(err error) bool {
|
||||
if err == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
message := err.Error()
|
||||
return strings.Contains(message, "cannot extract message data") ||
|
||||
strings.Contains(message, "missing required fields") ||
|
||||
strings.Contains(message, "no messages found")
|
||||
}
|
||||
|
||||
func HandleProtobufMsg(payload map[string]interface{}) ([]byte, error) {
|
||||
dataInter, ok := payload["data"]
|
||||
if !ok {
|
||||
|
||||
+54
-5
@@ -185,6 +185,49 @@ function readByteArrayIfReadable(addr, len) {
|
||||
}
|
||||
}
|
||||
|
||||
function readProtobufVarint(bytes, offset) {
|
||||
var value = 0;
|
||||
var multiplier = 1;
|
||||
|
||||
for (var i = 0; i < 10 && offset + i < bytes.length; i++) {
|
||||
var current = bytes[offset + i];
|
||||
value += (current & 0x7f) * multiplier;
|
||||
if (!Number.isSafeInteger(value)) {
|
||||
return null;
|
||||
}
|
||||
if ((current & 0x80) === 0) {
|
||||
return { value: value, nextOffset: offset + i + 1 };
|
||||
}
|
||||
multiplier *= 128;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function hasRecvMessageHeader(bytes) {
|
||||
var field1Tag = readProtobufVarint(bytes, 0);
|
||||
if (!field1Tag || field1Tag.value !== 0x08) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var recvType = readProtobufVarint(bytes, field1Tag.nextOffset);
|
||||
if (!recvType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var field2Tag = readProtobufVarint(bytes, recvType.nextOffset);
|
||||
if (!field2Tag || field2Tag.value !== 0x12) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var wrapperLength = readProtobufVarint(bytes, field2Tag.nextOffset);
|
||||
if (!wrapperLength || wrapperLength.value <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return wrapperLength.value <= bytes.length - wrapperLength.nextOffset;
|
||||
}
|
||||
|
||||
function sendDownloadChunks(dataPtr, dataLen, fileId, cdnUrl) {
|
||||
if (!cdnUrl || dataLen <= 0) {
|
||||
return;
|
||||
@@ -1050,17 +1093,23 @@ function setReceiver() {
|
||||
return;
|
||||
}
|
||||
|
||||
if (x2 < 4 || x2 > MAX_FRIDA_MESSAGE_BYTES) {
|
||||
if (x2 < 4) {
|
||||
return;
|
||||
}
|
||||
if (x2 > MAX_FRIDA_MESSAGE_BYTES) {
|
||||
console.warn("[skip] protobuf_msg length out of range: " + x2);
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. field 2 wrapper长度 < 128 (单字节varint) → wrapper内容过小,非聊天消息
|
||||
if (currentPtr.add(2).readU8() === 0x10 || currentPtr.add(2).readU8() === 0x16 || (currentPtr.add(3).readU8() & 0x80) === 0) {
|
||||
const mem = readByteArrayIfReadable(currentPtr, x2);
|
||||
if (!mem) {
|
||||
console.warn("[skip] protobuf_msg memory read failed, length=" + x2);
|
||||
return;
|
||||
}
|
||||
const mem = readByteArrayIfReadable(currentPtr, x2);
|
||||
if (!mem) return;
|
||||
const uint8Array = new Uint8Array(mem);
|
||||
if (!hasRecvMessageHeader(uint8Array)) {
|
||||
return;
|
||||
}
|
||||
|
||||
send({
|
||||
type: "protobuf_msg",
|
||||
|
||||
Reference in New Issue
Block a user