mirror of
https://github.com/yincongcyincong/wechat_chatter.git
synced 2026-07-15 10:26:52 +08:00
236 lines
10 KiB
Go
236 lines
10 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/hex"
|
|
)
|
|
|
|
// BuildUploadPayload 构建上传图片/视频/语音的payload模板,返回hex编码字符串
|
|
// uploadType: "img", "video", "voice"
|
|
// JS侧会在固定偏移写入运行时指针: 0x00, 0x08, 0x48, 0x68(receiver), 0xa8, 0xe8, 0x118, 0x148, 0x200
|
|
func BuildUploadPayload(uploadType string) string {
|
|
// 公共部分 (760字节 = 0x2F8),以img为基准
|
|
// 差异字节: [0x9C] img=0x01/video=0x04/voice=0x0F, [0x1BC-0x1BF] img=AAAAAAAA/video=01000000/voice=07000000
|
|
payload := []byte{
|
|
0x20, 0x05, 0x33, 0x8C, 0x0B, 0x00, 0x00, 0x00, // 0x00 (被uploadFunc1Addr覆盖)
|
|
0x00, 0x05, 0x33, 0x8C, 0x0B, 0x00, 0x00, 0x00, // 0x08 (被uploadFunc2Addr覆盖)
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x10
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x18
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x20
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x28
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x30
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x38
|
|
0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, // 0x40
|
|
0xD0, 0x72, 0x20, 0x89, 0x0B, 0x00, 0x00, 0x00, // 0x48 (被imageIdAddr/videoIdAddr/voiceIdAddr覆盖)
|
|
0x26, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x50
|
|
0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, // 0x58
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x60
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x68 (被receiver覆盖)
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x70
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, // 0x78
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x80
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x88
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x90
|
|
0x01, 0xAA, 0xAA, 0xAA, 0x01, 0x00, 0x00, 0x00, // 0x98 ([0x9C]由uploadType决定)
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xA0
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xA8 (被md5Addr覆盖)
|
|
0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xB0
|
|
0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, // 0xB8
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xC0
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xC8
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xD0
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xD8
|
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, // 0xE0 文件大小(-1=未知)
|
|
0x00, 0x55, 0xDB, 0x89, 0x0B, 0x00, 0x00, 0x00, // 0xE8 (被ImagePath/videoPath覆盖)
|
|
0xB2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xF0
|
|
0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, // 0xF8
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x100
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x108
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x110
|
|
0x40, 0x54, 0xDB, 0x89, 0x0B, 0x00, 0x00, 0x00, // 0x118 (被ImagePath/videoPath覆盖)
|
|
0xB2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x120
|
|
0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, // 0x128
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x130
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x138
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x140
|
|
0x40, 0x5D, 0xDB, 0x89, 0x0B, 0x00, 0x00, 0x00, // 0x148 (被ImagePath/videoPath覆盖)
|
|
0xB2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x150
|
|
0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, // 0x158
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x160
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x168
|
|
0x00, 0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, // 0x170 [0x174]=0x0B
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x178
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x180
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x188
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x190
|
|
0x00, 0xAA, 0xAA, 0xAA, 0x01, 0x00, 0x00, 0x00, // 0x198
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x1A0
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x1A8
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x1B0
|
|
0x00, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, // 0x1B8 ([0x1BC-0x1BF]由uploadType决定)
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x1C0
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x1C8
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x1D0
|
|
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x1D8
|
|
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x1E0
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x1E8
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x1F0
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x1F8
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x200 (被uploadAesKeyAddr覆盖)
|
|
0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x208
|
|
0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x210
|
|
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x218
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x220
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x228
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x230
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x238
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x240
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x248
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x250
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x258
|
|
0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, // 0x260
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x268
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x270
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x278
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x280
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x288
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x290
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x298
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x2A0
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x2A8
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x2B0
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x2B8
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x2C0
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x2C8
|
|
0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x2D0
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x2D8
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x2E0
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x2E8
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x2F0
|
|
}
|
|
|
|
switch uploadType {
|
|
case "video":
|
|
payload[0x9C] = 0x04
|
|
payload[0x1BC] = 0x01
|
|
payload[0x1BD] = 0x00
|
|
payload[0x1BE] = 0x00
|
|
payload[0x1BF] = 0x00
|
|
}
|
|
|
|
return hex.EncodeToString(payload)
|
|
}
|
|
|
|
// BuildVoiceUploadPayload 构建语音上传的payload模板,返回hex编码字符串
|
|
// 基于WeChat实际内存dump校正
|
|
// JS侧会在固定偏移写入运行时指针: 0x00, 0x08, 0x48(voiceIdAddr), 0x50(voiceId长度), 0x58(voiceId容量), 0x68(receiver), 0x100(audioData), 0x108(audioLen), 0x110(audioCap)
|
|
func BuildVoiceUploadPayload() string {
|
|
payload := []byte{
|
|
// 0x00 (被uploadFunc1Addr覆盖)
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
// 0x08 (被uploadFunc2Addr覆盖)
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
// 0x10
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
// 0x18
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
// 0x20
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
// 0x28
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
// 0x30
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
// 0x38
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
// 0x40
|
|
0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
|
// 0x48 (被voiceIdAddr覆盖)
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
// 0x50 voiceId length (JS实时写入)
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
// 0x58 voiceId capacity (JS实时写入)
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
|
|
// 0x60
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
// 0x68 (被receiver覆盖, inline string区域)
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
// 0x70
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
// 0x78 [0x7F]=receiver length
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13,
|
|
// 0x80
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
// 0x88
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
// 0x90
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
// 0x98 [0x9C]=0x0F voice type
|
|
0x01, 0xAA, 0xAA, 0xAA, 0x0F, 0x00, 0x00, 0x00,
|
|
// 0xA0
|
|
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
|
// 0xA8
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
// 0xB0
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
// 0xB8
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
// 0xC0
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
// 0xC8
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
// 0xD0
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
// 0xD8 音频参数
|
|
0x10, 0x0E, 0x00, 0x00, 0x08, 0x07, 0x00, 0x00,
|
|
// 0xE0 文件大小(-1=未知)
|
|
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
|
// 0xE8
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
// 0xF0
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
// 0xF8
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
// 0x100 (被voiceAudioDataAddr覆盖 - 音频数据指针)
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
// 0x108 音频数据长度 (JS写入)
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
// 0x110 音频数据容量 (JS写入, 带high bit)
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
|
|
// 0x118
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
// 0x120
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
// 0x128
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
// 0x130
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
// 0x138
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
// 0x140
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
// 0x148
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
// 0x150
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
// 0x158
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
// 0x160
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
// 0x168
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
// 0x170 [0x174]=0x01
|
|
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
|
// 0x178
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
// 0x180
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
// 0x188
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
// 0x190
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
// 0x198
|
|
0x00, 0xAA, 0xAA, 0xAA, 0x01, 0x00, 0x00, 0x00,
|
|
}
|
|
|
|
return hex.EncodeToString(payload)
|
|
}
|