mirror of
https://github.com/yincongcyincong/wechat_chatter.git
synced 2026-07-15 10:26:52 +08:00
update receiver
This commit is contained in:
+107
-35
@@ -23,15 +23,23 @@ function setReceiver() {
|
||||
}
|
||||
|
||||
const x2 = this.context.x2.toInt32();
|
||||
console.log(" [+] currentPtr: ", hexdump(currentPtr, {
|
||||
offset: 0,
|
||||
length: x2,
|
||||
header: true,
|
||||
ansi: true
|
||||
}));
|
||||
const fields = getProtobufRawBytes(currentPtr, x2)
|
||||
|
||||
const sender = fields[0]
|
||||
const receiver = fields[1]
|
||||
const content = fields[2]
|
||||
const xml = fields[3]
|
||||
const userContent = fields[4]
|
||||
const mediaContent = fields[3]
|
||||
const xml = fields[4]
|
||||
const userContent = fields[5]
|
||||
const msgId = protobufVarintToNumberString(fields[6])
|
||||
|
||||
if (sender === "" || receiver === "" || content === "" || xml === "") {
|
||||
if (sender === "" || receiver === "" || content === "") {
|
||||
console.log("字段缺失,无法解析 sender:" + sender + " receiver:" + receiver + hexdump(currentPtr, {
|
||||
length: x2,
|
||||
header: true,
|
||||
@@ -76,23 +84,30 @@ function setReceiver() {
|
||||
}
|
||||
|
||||
// 处理用户的名称
|
||||
splitIndex = userContent.indexOf(':')
|
||||
splitIndex = userContent?.indexOf(':')
|
||||
if (splitIndex === -1) {
|
||||
splitIndex = userContent.indexOf('在群聊中@了你')
|
||||
senderNickname = userContent.substring(0, splitIndex).trim();
|
||||
splitIndex = userContent?.indexOf('在群聊中@了你')
|
||||
senderNickname = userContent?.substring(0, splitIndex).trim();
|
||||
} else {
|
||||
senderNickname = userContent.substring(0, splitIndex).trim();
|
||||
senderNickname = userContent?.substring(0, splitIndex).trim();
|
||||
}
|
||||
if (!senderNickname) {
|
||||
senderNickname = sender
|
||||
}
|
||||
|
||||
} else {
|
||||
// 处理用户的名称
|
||||
const splitIndex = userContent?.indexOf(':')
|
||||
senderNickname = userContent.substring(0, splitIndex).trim();
|
||||
senderNickname = userContent?.substring(0, splitIndex).trim();
|
||||
if (!senderNickname) {
|
||||
senderNickname = sender
|
||||
}
|
||||
messages.push({type: "text", data: {text: content}});
|
||||
}
|
||||
|
||||
const msgId = generateAESKey()
|
||||
send({
|
||||
time: Date.now(),
|
||||
post_type: "message",
|
||||
message_type: msgType,
|
||||
user_id: senderUser, // 发送人的 ID
|
||||
self_id: selfId, // 接收人的 ID
|
||||
@@ -102,17 +117,22 @@ function setReceiver() {
|
||||
raw: {peerUid: msgId},
|
||||
message: messages,
|
||||
sender: {user_id: senderUser, nickname: senderNickname},
|
||||
msgsource: xml,
|
||||
raw_message: content,
|
||||
// media: mediaContent,
|
||||
show_content:userContent
|
||||
})
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// 使用 setImmediate 确保在模块加载后执行
|
||||
setImmediate(setReceiver)
|
||||
|
||||
|
||||
function getProtobufRawBytes(pBuffer, scanSize) {
|
||||
const tags = [0x12, 0x1A, 0x2A, 0x52, 0x5A];
|
||||
const tags = [0x12, 0x1A, 0x2A, 0x42, 0x52, 0x5A];
|
||||
let uint8Array;
|
||||
|
||||
try {
|
||||
@@ -149,7 +169,11 @@ function getProtobufRawBytes(pBuffer, scanSize) {
|
||||
// 2. 截取原始 Byte 数据
|
||||
if (i + length <= uint8Array.length) {
|
||||
let rawData = uint8Array.slice(i, i + length);
|
||||
finalResults.push(getCleanString(rawData));
|
||||
if (targetTag === 0x42) {
|
||||
finalResults.push(rawData);
|
||||
} else {
|
||||
finalResults.push(getCleanString(rawData));
|
||||
}
|
||||
i += length;
|
||||
} else {
|
||||
finalResults.push(null); // 长度越界
|
||||
@@ -162,6 +186,13 @@ function getProtobufRawBytes(pBuffer, scanSize) {
|
||||
if (!found) finalResults.push(null); // 未找到该 Tag
|
||||
});
|
||||
|
||||
|
||||
for (; i < uint8Array.length; i++) {
|
||||
if (uint8Array[i] === 0x60 && i + 10 <= uint8Array.length) {
|
||||
finalResults.push(uint8Array.slice(i+1, i+10))
|
||||
}
|
||||
}
|
||||
|
||||
return finalResults;
|
||||
}
|
||||
|
||||
@@ -187,6 +218,8 @@ function getCleanString(uint8Array) {
|
||||
// 这种通常是特殊拉丁字母等,按需保留
|
||||
var charCode = ((c & 0x1F) << 6) | (c2 & 0x3F);
|
||||
out += String.fromCharCode(charCode);
|
||||
} else {
|
||||
i--;
|
||||
}
|
||||
}
|
||||
// 3. 处理三字节 (1110xxxx 10xxxxxx 10xxxxxx) -> 绝大多数汉字在此
|
||||
@@ -204,6 +237,8 @@ function getCleanString(uint8Array) {
|
||||
) {
|
||||
out += String.fromCharCode(charCode);
|
||||
}
|
||||
} else {
|
||||
i -= 2;
|
||||
}
|
||||
} else if ((c & 0xF8) === 0xF0 && i + 2 < len) {
|
||||
var c2 = uint8Array[i++];
|
||||
@@ -218,47 +253,84 @@ function getCleanString(uint8Array) {
|
||||
// 使用 fromCodePoint 处理 4 字节字符
|
||||
out += String.fromCodePoint(codePoint);
|
||||
}
|
||||
} else {
|
||||
i -= 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
function generateAESKey() {
|
||||
const chars = 'abcdef0123456789';
|
||||
let key = '';
|
||||
for (let i = 0; i < 32; i++) {
|
||||
key += chars.charAt(Math.floor(Math.random() * chars.length));
|
||||
function protobufVarintToNumberString(uint8Array) {
|
||||
let result = BigInt(0);
|
||||
let shift = BigInt(0);
|
||||
|
||||
for (let i = 0; i < uint8Array.length; i++) {
|
||||
const byte = uint8Array[i];
|
||||
|
||||
// 1. 取出低 7 位并累加到结果中
|
||||
// (BigInt(byte & 0x7F) << shift)
|
||||
result += BigInt(byte & 0x7F) << shift;
|
||||
|
||||
// 2. 检查最高位 (MSB)。如果为 0,说明这个数字结束了
|
||||
if ((byte & 0x80) === 0) {
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
// 3. 准备处理下一个 7 位
|
||||
shift += BigInt(7);
|
||||
}
|
||||
return key;
|
||||
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// -----------------------测试函数-------------------------
|
||||
|
||||
function testGetProtobufRawBytes() {
|
||||
const rawMemoryData = [
|
||||
0x08, 0x00, 0x12, 0xb6, 0x02, 0x08, 0x01, 0x12, 0xb1, 0x02, 0x08, 0x05, 0x12, 0xac, 0x02, 0x08,
|
||||
0xa6, 0x02, 0x12, 0xa6, 0x02, 0x08, 0xec, 0xfc, 0xb9, 0x96, 0x03, 0x12, 0x15, 0x0a, 0x13, 0x77,
|
||||
0x78, 0x69, 0x64, 0x5f, 0x35, 0x79, 0x72, 0x74, 0x6c, 0x79, 0xf6, 0x33, 0x32, 0x68, 0x39, 0x75,
|
||||
0x31, 0x32, 0x1a, 0x08, 0x0a, 0x06, 0x6b, 0x74, 0x73, 0x6b, 0x74, 0x73, 0x20, 0x01, 0x2a, 0x0d,
|
||||
0x0a, 0x0b, 0x6a, 0x64, 0x6a, 0x78, 0x68, 0x64, 0x62, 0x62, 0x64, 0x64, 0x20, 0x30, 0x03, 0x38,
|
||||
0x01, 0x42, 0x02, 0x08, 0x00, 0x48, 0xaa, 0xdb, 0xff, 0xcc, 0x06, 0x52, 0xc7, 0x01, 0x3c, 0x6d,
|
||||
0x73, 0x67, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x3e, 0x0a, 0x09, 0x3c, 0x62, 0x69, 0x7a, 0x66,
|
||||
0x6c, 0x61, 0x67, 0x3e, 0x30, 0x3c, 0x2f, 0x62, 0x69, 0x7a, 0x66, 0x6c, 0x61, 0x67, 0x3e, 0x0a,
|
||||
0x09, 0x3c, 0x70, 0x75, 0x61, 0x3e, 0x31, 0x3c, 0x2f, 0x70, 0x75, 0x61, 0x3e, 0x0a, 0x09, 0x3c,
|
||||
0x65, 0x67, 0x67, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x3e, 0x31, 0x3c, 0x2f, 0x65,
|
||||
0x67, 0x67, 0x49, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x64, 0x3e, 0x0a, 0x09, 0x3c, 0x73, 0x69,
|
||||
0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x3e, 0x4e, 0x30, 0x5f, 0x56, 0x31, 0x5f, 0x78, 0x6e,
|
||||
0x68, 0x6b, 0x4e, 0x65, 0x68, 0x4b, 0x7c, 0x76, 0x31, 0x5f, 0x42, 0x4b, 0x71, 0x2b, 0x62, 0x45,
|
||||
0x36, 0x31, 0x3c, 0x2f, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x3e, 0x0a, 0x09,
|
||||
0x3c, 0x74, 0x6d, 0x70, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x3e, 0x0a, 0x09, 0x09, 0x3c, 0x70, 0x75,
|
||||
0x62, 0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x2d, 0x69, 0x64, 0x3e, 0x3c, 0x2f, 0x70, 0x75, 0x62,
|
||||
0x6c, 0x69, 0x73, 0x68, 0x65, 0x72, 0x2d, 0x69, 0x64, 0x3e, 0x3c, 0x2f, 0x70, 0x75, 0x62, 0x6c,
|
||||
0x08, 0x00, 0x12, 0xdc, 0x0f, 0x08, 0x01, 0x12, 0xd7, 0x0f, 0x08, 0x05, 0x12, 0xd2, 0x0f, 0x08,
|
||||
0xcc, 0x0f, 0x12, 0xcc, 0x0f, 0x08, 0x85, 0xa0, 0xd5, 0xe8, 0x04, 0x12, 0x15, 0x0a, 0x13, 0x77,
|
||||
0x78, 0x69, 0x64, 0x5f, 0x37, 0x77, 0x64, 0x31, 0x65, 0x63, 0x65, 0x39, 0x39, 0x66, 0x37, 0x69,
|
||||
0x32, 0x31, 0x1a, 0x15, 0x0a, 0x13, 0x77, 0x78, 0x69, 0x64, 0x5f, 0x6c, 0x64, 0x66, 0x74, 0x75,
|
||||
0x68, 0x65, 0x33, 0x36, 0x69, 0x7a, 0x67, 0x31, 0x39, 0x20, 0x22, 0x2a, 0xe6, 0x03, 0x0a, 0xe3,
|
||||
0x03, 0x3c, 0x6d, 0x73, 0x67, 0x3e, 0x3c, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x6d, 0x73, 0x67, 0x20,
|
||||
0x65, 0x6e, 0x64, 0x66, 0x6c, 0x61, 0x67, 0x3d, 0x22, 0x31, 0x22, 0x20, 0x63, 0x61, 0x6e, 0x63,
|
||||
0x65, 0x6c, 0x66, 0x6c, 0x61, 0x67, 0x3d, 0x22, 0x30, 0x22, 0x20, 0x66, 0x6f, 0x72, 0x77, 0x61,
|
||||
0x72, 0x64, 0x66, 0x6c, 0x61, 0x67, 0x3d, 0x22, 0x30, 0x22, 0x20, 0x76, 0x6f, 0x69, 0x63, 0x65,
|
||||
0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x3d, 0x22, 0x34, 0x22, 0x20, 0x76, 0x6f, 0x69, 0x63, 0x65,
|
||||
0x6c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3d, 0x22, 0x31, 0x31, 0x30, 0x30, 0x22, 0x20, 0x6c, 0x65,
|
||||
0x6e, 0x67, 0x74, 0x68, 0x3d, 0x22, 0x31, 0x32, 0x35, 0x32, 0x22, 0x20, 0x62, 0x75, 0x66, 0x69,
|
||||
0x64, 0x3d, 0x22, 0x30, 0x22, 0x20, 0x61, 0x65, 0x73, 0x6b, 0x65, 0x79, 0x3d, 0x22, 0x37, 0x30,
|
||||
0x66, 0x34, 0x31, 0x36, 0x37, 0x36, 0x63, 0x38, 0x31, 0x31, 0x34, 0x33, 0x62, 0x66, 0x33, 0x61,
|
||||
0x38, 0x38, 0x36, 0x62, 0x33, 0x33, 0x38, 0x32, 0x33, 0x30, 0x62, 0x37, 0x38, 0x37, 0x22, 0x20,
|
||||
0x76, 0x6f, 0x69, 0x63, 0x65, 0x75, 0x72, 0x6c, 0x3d, 0x22, 0x33, 0x30, 0x35, 0x32, 0x30, 0x32,
|
||||
0x30, 0x31, 0x30, 0x30, 0x30, 0x34, 0x34, 0x62, 0x33, 0x30, 0x34, 0x39, 0x30, 0x32, 0x30, 0x31,
|
||||
0x30, 0x30, 0x30, 0x32, 0x30, 0x34, 0x66, 0x36, 0x35, 0x63, 0x39, 0x63, 0x65, 0x30, 0x30, 0x32,
|
||||
0x30, 0x33, 0x32, 0x66, 0x38, 0x30, 0x32, 0x39, 0x30, 0x32, 0x30, 0x34, 0x32, 0x35, 0x66, 0x38,
|
||||
0x33, 0x64, 0x62, 0x37, 0x30, 0x32, 0x30, 0x34, 0x36, 0x39, 0x61, 0x31, 0x33, 0x38, 0x65, 0x30,
|
||||
0x30, 0x34, 0x32, 0x34, 0x33, 0x38, 0x36, 0x31, 0x36, 0x34, 0x36, 0x33, 0x33, 0x35, 0x33, 0x36,
|
||||
0x36, 0x36, 0x33, 0x33, 0x32, 0x64, 0x33, 0x37, 0x33, 0x30, 0x33, 0x33, 0x36, 0x36, 0x32, 0x64,
|
||||
0x33, 0x34, 0x36, 0x36, 0x36, 0x36, 0x33, 0x30, 0x32, 0x64, 0x33, 0x39, 0x33, 0x38, 0x33, 0x36,
|
||||
0x36, 0x34, 0x32, 0x64, 0x33, 0x30, 0x36, 0x32, 0x33, 0x33, 0x36, 0x32, 0x36, 0x32, 0x36, 0x32,
|
||||
0x36, 0x32, 0x33, 0x31, 0x33, 0x32, 0x33, 0x38, 0x33, 0x38, 0x33, 0x37, 0x30, 0x32, 0x30, 0x34,
|
||||
0x30, 0x31, 0x31, 0x38, 0x30, 0x30, 0x30, 0x66, 0x30, 0x32, 0x30, 0x31, 0x30, 0x30, 0x30, 0x34,
|
||||
0x30, 0x30, 0x39, 0x61, 0x38, 0x35, 0x33, 0x65, 0x64, 0x61, 0x22, 0x20, 0x76, 0x6f, 0x69, 0x63,
|
||||
0x65, 0x6d, 0x64, 0x35, 0x3d, 0x22, 0x22, 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x6d, 0x73,
|
||||
0x67, 0x69, 0x64, 0x3d, 0x22, 0x34, 0x39, 0x37, 0x35, 0x30, 0x66, 0x31, 0x61, 0x35, 0x31, 0x35,
|
||||
0x61, 0x37, 0x64, 0x30, 0x35, 0x35, 0x63, 0x35, 0x66, 0x31, 0x38, 0x34, 0x32, 0x64, 0x32, 0x66,
|
||||
0x66, 0x39, 0x37, 0x34, 0x30, 0x77, 0x78, 0x69, 0x64, 0x5f, 0x6c, 0x64, 0x66, 0x74, 0x75, 0x68,
|
||||
0x65, 0x33, 0x36, 0x69, 0x7a, 0x67, 0x31, 0x39, 0x5f, 0x32, 0x33, 0x36, 0x5f, 0x31, 0x37, 0x37,
|
||||
0x32, 0x31, 0x37, 0x33, 0x35, 0x33, 0x35, 0x22, 0x20, 0x66, 0x72, 0x6f, 0x6d, 0x75, 0x73, 0x65,
|
||||
0x72, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x77, 0x78, 0x69, 0x64, 0x5f, 0x37, 0x77, 0x64, 0x31,
|
||||
0x65, 0x63, 0x65, 0x39, 0x39, 0x66, 0x37, 0x69, 0x32, 0x31, 0x22, 0x20, 0x2f, 0x3e, 0x3c, 0x2f,
|
||||
0x6d, 0x73, 0x67, 0x3e, 0x30, 0x03, 0x38, 0x01, 0x42, 0xea, 0x09, 0x08, 0xe4, 0x09, 0x12, 0xe4
|
||||
];
|
||||
|
||||
const pBuffer = {
|
||||
// 模拟指针读取内存返回 ArrayBuffer
|
||||
readByteArray: function(size) {
|
||||
readByteArray: function (size) {
|
||||
// 返回模拟数据的 ArrayBuffer 副本
|
||||
const slice = rawMemoryData.slice(0, size);
|
||||
const ab = new ArrayBuffer(slice.length);
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
module github.com/yincongcyincong/weixin-macos/go_al
|
||||
|
||||
go 1.25.0
|
||||
+28
-15
@@ -83,7 +83,7 @@ function generateAESKey() {
|
||||
}
|
||||
|
||||
function getProtobufRawBytes(pBuffer, scanSize) {
|
||||
const tags = [0x12, 0x1A, 0x2A, 0x52, 0x5A];
|
||||
const tags = [0x12, 0x1A, 0x2A, 0x42, 0x52, 0x5A];
|
||||
let uint8Array;
|
||||
|
||||
try {
|
||||
@@ -120,7 +120,11 @@ function getProtobufRawBytes(pBuffer, scanSize) {
|
||||
// 2. 截取原始 Byte 数据
|
||||
if (i + length <= uint8Array.length) {
|
||||
let rawData = uint8Array.slice(i, i + length);
|
||||
finalResults.push(getCleanString(rawData));
|
||||
if (targetTag === 0x42) {
|
||||
finalResults.push(rawData);
|
||||
} else {
|
||||
finalResults.push(getCleanString(rawData));
|
||||
}
|
||||
i += length;
|
||||
} else {
|
||||
finalResults.push(null); // 长度越界
|
||||
@@ -158,6 +162,8 @@ function getCleanString(uint8Array) {
|
||||
// 这种通常是特殊拉丁字母等,按需保留
|
||||
var charCode = ((c & 0x1F) << 6) | (c2 & 0x3F);
|
||||
out += String.fromCharCode(charCode);
|
||||
} else {
|
||||
i--;
|
||||
}
|
||||
}
|
||||
// 3. 处理三字节 (1110xxxx 10xxxxxx 10xxxxxx) -> 绝大多数汉字在此
|
||||
@@ -175,6 +181,8 @@ function getCleanString(uint8Array) {
|
||||
) {
|
||||
out += String.fromCharCode(charCode);
|
||||
}
|
||||
} else {
|
||||
i -= 2;
|
||||
}
|
||||
} else if ((c & 0xF8) === 0xF0 && i + 2 < len) {
|
||||
var c2 = uint8Array[i++];
|
||||
@@ -189,6 +197,8 @@ function getCleanString(uint8Array) {
|
||||
// 使用 fromCodePoint 处理 4 字节字符
|
||||
out += String.fromCodePoint(codePoint);
|
||||
}
|
||||
} else {
|
||||
i -= 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1070,13 +1080,6 @@ function setReceiver() {
|
||||
Interceptor.attach(buf2RespAddr, {
|
||||
onEnter: function (args) {
|
||||
const currentPtr = this.context.x1;
|
||||
// console.log(" [+] currentPtr: ", hexdump(currentPtr, {
|
||||
// offset: 0,
|
||||
// length: 512,
|
||||
// header: true,
|
||||
// ansi: true
|
||||
// }));
|
||||
|
||||
let start = 0x1e;
|
||||
let senderLen = currentPtr.add(start).readU8();
|
||||
if (senderLen !== 0x14 && senderLen !== 0x13) {
|
||||
@@ -1088,15 +1091,22 @@ function setReceiver() {
|
||||
}
|
||||
|
||||
const x2 = this.context.x2.toInt32();
|
||||
// console.log(" [+] currentPtr: ", hexdump(currentPtr, {
|
||||
// offset: 0,
|
||||
// length: x2,
|
||||
// header: true,
|
||||
// ansi: true
|
||||
// }));
|
||||
const fields = getProtobufRawBytes(currentPtr, x2)
|
||||
|
||||
const sender = fields[0]
|
||||
const receiver = fields[1]
|
||||
const content = fields[2]
|
||||
const xml = fields[3]
|
||||
const userContent = fields[4]
|
||||
const mediaContent = fields[3]
|
||||
const xml = fields[4]
|
||||
const userContent = fields[5]
|
||||
|
||||
if (sender === "" || receiver === "" || content === "" || xml === "") {
|
||||
if (sender === "" || receiver === "" || content === "") {
|
||||
console.log("字段缺失,无法解析 sender:" + sender + " receiver:" + receiver + hexdump(currentPtr, {
|
||||
length: x2,
|
||||
header: true,
|
||||
@@ -1116,8 +1126,8 @@ function setReceiver() {
|
||||
msgType = "group"
|
||||
groupId = sender
|
||||
|
||||
let splitIndex = content?.indexOf(':')
|
||||
let pureContent = content?.substring(splitIndex + 1).trim();
|
||||
let splitIndex = content.indexOf(':')
|
||||
let pureContent = content.substring(splitIndex + 1).trim();
|
||||
const parts = pureContent.split('\u2005');
|
||||
for (let part of parts) {
|
||||
part = part.trim();
|
||||
@@ -1175,7 +1185,10 @@ function setReceiver() {
|
||||
raw: {peerUid: msgId},
|
||||
message: messages,
|
||||
sender: {user_id: senderUser, nickname: senderNickname},
|
||||
raw_message: ""
|
||||
msgsource: xml,
|
||||
raw_message: content,
|
||||
// media: mediaContent,
|
||||
show_content:userContent
|
||||
})
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user