mirror of
https://github.com/yincongcyincong/wechat_chatter.git
synced 2026-07-15 10:26:52 +08:00
support send file
This commit is contained in:
+237
-9
@@ -299,8 +299,16 @@ var uploadGetCallbackWrapperFuncAddr = baseAddr.add({{.uploadGetCallbackWrapperF
|
||||
var uploadOnCompleteAddr = baseAddr.add({{.uploadOnCompleteAddr}});
|
||||
var uploadOnCompleteFuncAddr = baseAddr.add({{.uploadOnCompleteFuncAddr}});
|
||||
var downloadImagAddr = baseAddr.add({{.downloadImagAddr}});
|
||||
var hdPicDownloadAddr = baseAddr.add({{.hdPicDownloadAddr}})
|
||||
var startDownloadMedia = baseAddr.add({{.startDownloadMedia}})
|
||||
var downloadFileAddr = baseAddr.add({{.downloadFileAddr}})
|
||||
|
||||
var downloadGlobalX0;
|
||||
var downloadFileX1 = ptr(0)
|
||||
var fileIdAddr = ptr(0)
|
||||
var fileMd5Addr = ptr(0)
|
||||
var downloadAesKeyAddr = ptr(0)
|
||||
var filePathAddr = ptr(0)
|
||||
var fileCdnUrlAddr = ptr(0)
|
||||
var uploadImageX1 = ptr(0);
|
||||
var imgCgiAddr = ptr(0);
|
||||
var sendImgMessageAddr = ptr(0);
|
||||
@@ -538,7 +546,7 @@ setImmediate(AttachSendTextProto);
|
||||
|
||||
// 拦截 SendTextProto 编码逻辑,注入自定义 Payload
|
||||
function attachSendTextProto() {
|
||||
textProtoX1PayloadAddr = Memory.alloc(2048);
|
||||
textProtoX1PayloadAddr = Memory.alloc(3096);
|
||||
console.log("[+] Frida 分配的 Payload 地址: " + textProtoX1PayloadAddr);
|
||||
|
||||
Interceptor.attach(protobufAddr, {
|
||||
@@ -1171,12 +1179,25 @@ setImmediate(attachGetCallbackFromWrapper);
|
||||
rpc.exports = {
|
||||
triggerSendImgMessage: triggerSendImgMessage,
|
||||
triggerUploadImg: triggerUploadImg,
|
||||
triggerSendTextMessage: triggerSendTextMessage
|
||||
triggerSendTextMessage: triggerSendTextMessage,
|
||||
triggerDownload: triggerDownload,
|
||||
};
|
||||
|
||||
// -------------------------发送图片消息分区-------------------------
|
||||
|
||||
// -------------------------接收消息分区-------------------------
|
||||
function setupDownloadFileDynamic() {
|
||||
downloadFileX1 = Memory.alloc(1624)
|
||||
fileIdAddr = Memory.alloc(128)
|
||||
fileMd5Addr = Memory.alloc(128)
|
||||
downloadAesKeyAddr = Memory.alloc(128)
|
||||
filePathAddr = Memory.alloc(256)
|
||||
fileCdnUrlAddr = Memory.alloc(256)
|
||||
|
||||
}
|
||||
|
||||
setImmediate(setupDownloadFileDynamic)
|
||||
|
||||
function setReceiver() {
|
||||
Interceptor.attach(buf2RespAddr, {
|
||||
onEnter: function (args) {
|
||||
@@ -1287,8 +1308,9 @@ function setReceiver() {
|
||||
},
|
||||
});
|
||||
|
||||
Interceptor.attach(hdPicDownloadAddr, {
|
||||
Interceptor.attach(startDownloadMedia, {
|
||||
onEnter: function (args) {
|
||||
downloadGlobalX0 = this.context.x0;
|
||||
var fileIDAddr = this.context.x1.add(0x40).readPointer();
|
||||
var fileId = fileIDAddr?.readUtf8String();
|
||||
if (!fileId.endsWith("_1")) {
|
||||
@@ -1296,12 +1318,35 @@ function setReceiver() {
|
||||
}
|
||||
|
||||
console.log(" [+] download file: ", fileId);
|
||||
this.context.x1.add(0x148).writeByteArray([0xa0, 0x86, 0x01, 0x00]);
|
||||
this.context.x1.add(0xA0).writeU32(0x02);
|
||||
const t = this.context.x1.add(0xA0).readU32()
|
||||
if (t === 3) {
|
||||
this.context.x1.add(0xA0).writeU32(0x02);
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
Interceptor.attach(downloadFileAddr, {
|
||||
onEnter: function (args) {
|
||||
var dataPtr = this.context.x1;
|
||||
var dataLen = this.context.x2.toInt32();
|
||||
var fileId = this.context.sp.add(0x30).readPointer().readUtf8String();
|
||||
var cdnUrl = this.context.x19.add(0x2F8).readPointer().readUtf8String();
|
||||
|
||||
if (dataLen > 0) {
|
||||
var buffer = dataPtr.readByteArray(dataLen);
|
||||
var uint8Array = new Uint8Array(buffer);
|
||||
|
||||
send({
|
||||
type: "download",
|
||||
media: Array.from(uint8Array),
|
||||
file_id: fileId,
|
||||
cdn_url: cdnUrl,
|
||||
})
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Interceptor.attach(downloadImagAddr, { // 建议使用函数起始地址或你计算出的偏移地址
|
||||
Interceptor.attach(downloadImagAddr, {
|
||||
onEnter: function (args) {
|
||||
var dataPtr = this.context.x1;
|
||||
var dataLen = this.context.x2.toInt32();
|
||||
@@ -1323,10 +1368,163 @@ function setReceiver() {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// 使用 setImmediate 确保在模块加载后执行
|
||||
setImmediate(setReceiver)
|
||||
|
||||
// fileType: HdImage => 1,Image => 2, thumbImage => 3, Video => 4, File => 5,
|
||||
function triggerDownload(receiver, cdnUrl, aesKey, filePath, fileType) {
|
||||
const downloadMediaPayload = [
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x00
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x10
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x20
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x30
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xF0, 0xB6, 0x4C, 0xFC, 0x0A, 0x00, 0x00, 0x00, // 0x40
|
||||
0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
|
||||
0x80, 0x10, 0x4B, 0xFA, 0x0A, 0x00, 0x00, 0x00, // 0x58
|
||||
0xB2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
|
||||
0xF0, 0xB3, 0x4C, 0xFC, 0x0A, 0x00, 0x00, 0x00, // 0x70
|
||||
0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
|
||||
0x60, 0xC4, 0x2D, 0xFE, 0x0A, 0x00, 0x00, 0x00, // 0x88
|
||||
0xC8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x90
|
||||
0xD0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, // 0x98
|
||||
0x03, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, // 0xa0
|
||||
0x00, 0x00, 0x00, 0x00, 0x01, 0xAA, 0xAA, 0xAA, // 0xa8
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xb0
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xc0
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xd0
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xd8
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xe0
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xf0
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x100
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x110
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x02, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, // 0x128
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x11, 0x28, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x148
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x02, 0x00, 0x00, 0xAA, 0xAA, 0xAA, // 0x170
|
||||
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, // 0x180
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x1E, 0x00, 0x00, 0x00, 0xAA, 0xAA, 0xAA, 0xAA, // 0x1a0
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x22, 0x1A, 0xFE, 0x0A, 0x00, 0x00, 0x00, // 0x1d0
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x1f0
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x200
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x288
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
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,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0x4F, 0x56, 0xFC, 0x0A, 0x00, 0x00, 0x00, // 0x2c0
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x300
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, // 0x318
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x340
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, // 0x378
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x03, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x00, // 0x3e0
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
];
|
||||
|
||||
patchString(fileIdAddr, receiver + "_" + String(Math.floor(Date.now() / 1000)) + "_" + Math.floor(Math.random() * 1001) + "_1");
|
||||
patchString(fileCdnUrlAddr, cdnUrl)
|
||||
patchString(downloadAesKeyAddr, aesKey)
|
||||
patchString(filePathAddr, filePath);
|
||||
|
||||
downloadFileX1.writeByteArray(downloadMediaPayload);
|
||||
downloadFileX1.add(0x40).writePointer(fileIdAddr);
|
||||
downloadFileX1.add(0x58).writePointer(fileCdnUrlAddr);
|
||||
downloadFileX1.add(0x70).writePointer(downloadAesKeyAddr);
|
||||
downloadFileX1.add(0x88).writePointer(filePathAddr);
|
||||
downloadFileX1.add(0xa0).writeU32(fileType);
|
||||
|
||||
const startDwMedia = new NativeFunction(startDownloadMedia, 'int64', ['pointer', 'pointer']);
|
||||
const result = startDwMedia(downloadGlobalX0, downloadFileX1);
|
||||
|
||||
console.log("下载调用结果: " + result);
|
||||
return result;
|
||||
}
|
||||
|
||||
function getMessages(content, sender, mediaContent) {
|
||||
var messages = [];
|
||||
if (sender.includes("@chatroom")) {
|
||||
@@ -1339,6 +1537,21 @@ function getMessages(content, sender, mediaContent) {
|
||||
messages.push({type: "image", data: {text: part}});
|
||||
} else if (part.startsWith("<msg><voicemsg")) {
|
||||
messages.push({type: "record", data: {text: part}});
|
||||
} else if (part.startsWith("<?xml version=\"1.0\"?><msg><appmsg")) {
|
||||
const regex = /<type>(.*?)<\/type>/s;
|
||||
const match = part.match(regex);
|
||||
if (match.length > 1) {
|
||||
switch (match[1]) {
|
||||
case "5":
|
||||
messages.push({type: "share", data: {text: part}});
|
||||
break
|
||||
case "6":
|
||||
messages.push({type: "file", data: {text: part}});
|
||||
break
|
||||
}
|
||||
}
|
||||
} else if (content.startsWith("<msg><emoji")) {
|
||||
messages.push({type: "face", data: {text: part}});
|
||||
} else {
|
||||
messages.push({type: "text", data: {text: part}});
|
||||
}
|
||||
@@ -1352,6 +1565,21 @@ function getMessages(content, sender, mediaContent) {
|
||||
mediaContent = mediaContent.subarray(audioStart);
|
||||
}
|
||||
messages.push({type: "record", data: {text: content, media: Array.from(mediaContent)}});
|
||||
} else if (content.startsWith("<?xml version=\"1.0\"?><msg><appmsg")) {
|
||||
const regex = /<type>(.*?)<\/type>/s;
|
||||
const match = content.match(regex);
|
||||
if (match.length > 1) {
|
||||
switch (match[1]) {
|
||||
case "5":
|
||||
messages.push({type: "share", data: {text: content}});
|
||||
break
|
||||
case "6":
|
||||
messages.push({type: "file", data: {text: content}});
|
||||
break
|
||||
}
|
||||
}
|
||||
} else if (content.startsWith("<msg><emoji")) {
|
||||
messages.push({type: "face", data: {text: content}});
|
||||
} else {
|
||||
messages.push({type: "text", data: {text: content}});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user